From 1a93813c078ad3f29c511acef8b4ec9f14934822 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Tue, 25 Oct 2016 17:00:28 +0100 Subject: [PATCH] Make Wordpress use Laravel's database driver --- src/Providers/WordpressServiceProvider.php | 16 ++++++++++------ src/Proxy/WordpressDatabase.php | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 6 deletions(-) create mode 100644 src/Proxy/WordpressDatabase.php 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 @@ + + */ +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; + } +} -- libgit2 1.7.2