🏡 index : ~doyle/koselig.git

author Jordan Doyle <jordan@doyle.wf> 2016-10-25 16:00:28.0 +00:00:00
committer Jordan Doyle <jordan@doyle.wf> 2016-10-25 16:00:28.0 +00:00:00
commit
1a93813c078ad3f29c511acef8b4ec9f14934822 [patch]
tree
d3ad7377e8e3a1661874c1ee6dac75eacb59fa43
parent
90b1deec2c9a36e5f5627237398325643acc8642
download
1a93813c078ad3f29c511acef8b4ec9f14934822.tar.gz

Make Wordpress use Laravel's database driver



Diff

 src/Providers/WordpressServiceProvider.php |  16 +-
 src/Proxy/WordpressDatabase.php            | 225 ++++++++++++++++++++++++++++++-
 2 files changed, 235 insertions(+), 6 deletions(-)

diff --git a/src/Providers/WordpressServiceProvider.php b/src/Providers/WordpressServiceProvider.php
index 7f170ee..62dc52b 100644
--- a/src/Providers/WordpressServiceProvider.php
+++ b/src/Providers/WordpressServiceProvider.php
@@ -3,6 +3,7 @@ namespace Koselig\Providers;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
use Koselig\Proxy\WordpressDatabase;
use Koselig\Support\Action;
use Koselig\Support\Wordpress;

@@ -32,6 +33,15 @@ class WordpressServiceProvider extends ServiceProvider
        );

        $this->setConfig();
    }

    public function boot()
    {
        // Wordpress requires $table_prefix rather than another constant.
        $table_prefix = 'wp_';
        $this->setDatabaseConstants($table_prefix);
        require ABSPATH . 'wp-settings.php';

        $this->triggerHooks();

        // Set up the WordPress query.
@@ -91,15 +101,11 @@ class WordpressServiceProvider extends ServiceProvider
     */
    protected function setConfig()
    {
        // Wordpress requires $table_prefix rather than another constant.
        $table_prefix = 'wp_';

        define('WP_DEBUG', config('app.debug'));
        define('WP_DEBUG_DISPLAY', WP_DEBUG);
        define('WP_DEFAULT_THEME', 'koselig');
        define('DISALLOW_FILE_MODS', true);

        $this->setDatabaseConstants($table_prefix);
        $this->setAuthenticationConstants();
        $this->setLocationConstants();
        $this->setMultisiteConstants();
@@ -114,8 +120,6 @@ class WordpressServiceProvider extends ServiceProvider
            'function' => [$this, 'addThemeSupport'],
            'accepted_args' => 0,
        ];

        require ABSPATH . 'wp-settings.php';
    }

    /**
diff --git a/src/Proxy/WordpressDatabase.php b/src/Proxy/WordpressDatabase.php
new file mode 100644
index 0000000..641ab5c
--- /dev/null
+++ b/src/Proxy/WordpressDatabase.php
@@ -0,0 +1,225 @@
<?php
namespace Koselig\Proxy;

use DB;
use Illuminate\Database\QueryException;
use wpdb;

/**
 * Replace Wordpress' database calls to Laravel's database abstraction
 * to hold a single database connection, and for easier query debugging.
 *
 * @author Jordan Doyle <jordan@doyle.wf>
 */
class WordpressDatabase extends wpdb
{
    /**
     * Override the constructor as the Wordpress install doesn't actually
     * need our Database details since it's all handled by laravel.
     */
    public function __construct()
    {
        parent::__construct(null, null, null, null);
    }

    /**
     * Override the Wordpress select method as Laravel has already
     * done this for us.
     *
     * @param string $db
     * @param null $dbh
     */
    public function select($db, $dbh = null)
    {
        // We don't need to select a table, Laravel has done it for us.
    }

    /**
     * Set the properties Wordpress expects so it will run queries for us
     * through this class.
     *
     * @param bool $allow_bail
     * @return void
     */
    public function db_connect($allow_bail = true)
    {
        $this->is_mysql = true;
        $this->has_connected = true;

        $this->ready = true;
        $this->set_sql_mode();
        $this->init_charset();
    }

    /**
     * Retrieves the MySQL server version.
     *
     * @return null|string Null on failure, version number on success.
     */
    public function db_version()
    {
        return DB::selectOne('SELECT version() as v')->v;
    }

    /**
     * Change the current SQL mode, and ensure its WordPress compatibility.
     *
     * If no modes are passed, it will ensure the current MySQL server
     * modes are compatible.
     *
     * @since 3.9.0
     *
     * @param array $modes Optional. A list of SQL modes to set.
     */
    public function set_sql_mode($modes = [])
    {
        if (empty($modes)) {
            $modes = explode(',', DB::selectOne('SELECT @@SESSION.sql_mode as sql_mode')->sql_mode);
        }

        $modes = array_change_key_case($modes, CASE_UPPER);

        /**
         * Filters the list of incompatible SQL modes to exclude.
         *
         * @since 3.9.0
         *
         * @param array $incompatible_modes An array of incompatible modes.
         */
        $incompatible_modes = (array) apply_filters('incompatible_sql_modes', $this->incompatible_modes);

        foreach ($modes as $i => $mode) {
            if (in_array($mode, $incompatible_modes)) {
                unset($modes[$i]);
            }
        }

        DB::statement('SET SESSION sql_mode=?', [implode(',', $modes)]);
    }

    /**
     * Real escape, using mysqli_real_escape_string() or mysql_real_escape_string()
     *
     * @see mysqli_real_escape_string()
     * @see mysql_real_escape_string()
     * @since 2.8.0
     * @access private
     *
     * @param  string $string to escape
     * @return string escaped
     */
    public function _real_escape($string)
    {
        return substr(DB::getPdo()->quote($string), 1, -1);
    }

    /**
     * Internal function to perform the mysql_query() call.
     *
     * @since 3.9.0
     *
     * @access private
     * @see wpdb::query()
     *
     * @param string $query The query to run.
     */
    private function _do_query($query)
    {
        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            $this->timer_start();
        }

        if (preg_match('/^\s*(insert|create|alter|truncate|drop)\s/i', $query)) {
            $this->last_result = $this->result = DB::statement($query);
        } elseif (preg_match('/^\s*(delete|update|replace)\s/i', $query)) {
            $this->last_result = $this->result = DB::affectingStatement($query);
        } else {
            $this->last_result = $this->result = DB::select($query);
        }

        $this->num_queries++;

        if (defined('SAVEQUERIES') && SAVEQUERIES) {
            $this->queries[] = array($query, $this->timer_stop(), $this->get_caller());
        }
    }

    /**
     * Perform a MySQL database query, using current database connection.
     *
     * More information can be found on the codex page.
     *
     * @since 0.71
     *
     * @param string $query Database query
     * @return int|false Number of rows affected/selected or false on error
     */
    public function query($query)
    {
        if (!$this->ready) {
            $this->check_current_query = true;
            return false;
        }

        /**
         * Filters the database query.
         *
         * Some queries are made before the plugins have been loaded,
         * and thus cannot be filtered with this method.
         *
         * @since 2.1.0
         *
         * @param string $query Database query.
         */
        $query = apply_filters('query', $query);

        $this->flush();

        // Log how the function was called
        $this->func_call = "\$db->query(\"$query\")";

        // If we're writing to the database, make sure the query will write safely.
        if ($this->check_current_query && !$this->check_ascii($query)) {
            $stripped_query = $this->strip_invalid_text_from_query($query);
            // strip_invalid_text_from_query() can perform queries, so we need
            // to flush again, just to make sure everything is clear.
            $this->flush();
            if ($stripped_query !== $query) {
                $this->insert_id = 0;
                return false;
            }
        }

        $this->check_current_query = true;

        // Keep track of the last query for debug.
        $this->last_query = $query;

        try {
            $this->_do_query($query);
        } catch (QueryException $e) {
            $this->last_error = $e->getMessage();

            // Clear insert_id on a subsequent failed insert.
            if ($this->insert_id && preg_match('/^\s*(insert|replace)\s/i', $query)) {
                $this->insert_id = 0;
            }

            $this->print_error($this->last_error);
            return false;
        }

        if (preg_match('/^\s*(create|alter|truncate|drop)\s/i', $query)) {
            $return_val = $this->result;
        } elseif (preg_match('/^\s*(insert|delete|update|replace)\s/i', $query)) {
            $this->rows_affected = $return_val = $this->result;
        } else {
            // Log number of rows the query returned
            // and return number of rows selected
            $this->num_rows = count($this->result);
            $return_val = $this->result;
        }

        return $return_val;
    }
}