diff --git a/core.php b/core.php index 7be7870..f4d2ac7 100644 --- a/core.php +++ b/core.php @@ -17,6 +17,11 @@ class WPCPT_Tables_Core */ private $helper; + /** + * @var WPCPT_Tables_Settings + */ + private $settings; + /** * @var LightApps_Connector */ @@ -71,6 +76,10 @@ public function load() add_filter('network_admin_plugin_action_links_cpt-tables/wp-cpt-tables.php', [$this, 'addActionLinksNetwork'], 10, 2); add_filter('plugin_row_meta', array($this, 'filterPluginRowMeta'), 10, 2); + if (count($this->config['post_types']) > 0) { + $self->checkTablesAndCompareToPostTypes(); + } + $self->loadLocalization(); $self->setupConnector(); $self->setupAdminFilters(); @@ -80,7 +89,6 @@ public function load() // Check for triggers on existing cpt tables if (count($this->config['post_types']) > 0) { - $self->checkTablesAndCompareToPostTypes(); $self->checkExistingTriggers(); } @@ -135,6 +143,9 @@ public function clearEnabledPostTypes() public function checkTablesAndCompareToPostTypes() { global $wpdb; + + $post_types = get_option('cpt_tables:tables_enabled', []); + $tables = $wpdb->get_col("SHOW TABLES LIKE '{$this->config['prefix']}%'"); $tables = array_map(function ($table) { return str_replace($this->config['prefix'], '', $table); @@ -143,11 +154,11 @@ public function checkTablesAndCompareToPostTypes() $tables = array_filter($tables, function ($table) { return strpos($table, '_meta') === false; }); - $missing_tables = array_diff($tables, $this->config['post_types']); + $missing_tables = array_diff($tables, $post_types); if (count($missing_tables) > 0) { error_log('Tables found that are not enabled in the plugin settings. Adding to migrated tables.'); - $this->config['post_types'] = array_merge($this->config['post_types'], $missing_tables); - update_option($this->config['tables_enabled'], $this->config['post_types']); + $post_types = array_merge($post_types, $missing_tables); + update_option($this->config['tables_enabled'], $post_types); } } @@ -170,6 +181,107 @@ public function checkExistingTriggers() } } + /** + * Get orphaned posts + */ + public function getOrphanedPosts() + { + global $wpdb; + $tables_class = new WPCPT_Tables_Table($this->db, $this->config); + + $post_types = get_option('cpt_tables:tables_enabled', []); + + foreach ($post_types as $post_type) { + $posts = $wpdb->get_results( + "SELECT p.ID, p.post_author, p.post_date, p.post_date_gmt, p.post_content, p.post_title, p.post_excerpt, p.post_status, p.comment_status, p.ping_status, p.post_password, p.post_name, p.to_ping, p.pinged, p.post_modified, p.post_modified_gmt, p.post_content_filtered, p.post_parent, p.guid, p.menu_order, p.post_type, p.post_mime_type, p.comment_count + FROM {$wpdb->posts} p + WHERE p.post_type = '{$post_type}'" + ); + + foreach ($posts as $post) { + // Insert post into cpt table + $wpdb->insert( + $tables_class->getTableName($post_type), + [ + 'ID' => $post->ID, + 'post_author' => $post->post_author, + 'post_date' => $post->post_date, + 'post_date_gmt' => $post->post_date_gmt, + 'post_content' => $post->post_content, + 'post_title' => $post->post_title, + 'post_excerpt' => $post->post_excerpt, + 'post_status' => $post->post_status, + 'comment_status' => $post->comment_status, + 'ping_status' => $post->ping_status, + 'post_password' => $post->post_password, + 'post_name' => $post->post_name, + 'to_ping' => $post->to_ping, + 'pinged' => $post->pinged, + 'post_modified' => $post->post_modified, + 'post_modified_gmt' => $post->post_modified_gmt, + 'post_content_filtered' => $post->post_content_filtered, + 'post_parent' => $post->post_parent, + 'guid' => $post->guid, + 'menu_order' => $post->menu_order, + 'post_type' => $post->post_type, + 'post_mime_type' => $post->post_mime_type, + 'comment_count' => $post->comment_count, + ] + ); + + // Delete post from wp_posts + $wpdb->delete( + $wpdb->posts, + [ + 'ID' => $post->ID + ] + ); + } + } + } + + /** + * Get orphaned meta from wp_postmeta and insert into cpt table + */ + public function getOrphanedMeta() + { + global $wpdb; + $tables_class = new WPCPT_Tables_Table($this->db, $this->config); + + $post_types = get_option('cpt_tables:tables_enabled', []); + + foreach ($post_types as $post_type) { + // get all post id by wpdb and join with postmeta + $orphaned_metas = $wpdb->get_results( + "SELECT pm.meta_id, pm.post_id, pm.meta_key, pm.meta_value + FROM {$tables_class->getTableName($post_type)} p + JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID" + ); + + // loop orphane meta and insert into new table + foreach ($orphaned_metas as $meta) { + // insert into new table + $wpdb->insert( + $tables_class->getTableName($post_type . '_meta'), + [ + 'meta_id' => $meta->meta_id, + 'post_id' => $meta->post_id, + 'meta_key' => $meta->meta_key, + 'meta_value' => $meta->meta_value + ] + ); + + // delete from old table + $wpdb->delete( + $wpdb->postmeta, + [ + 'meta_id' => $meta->meta_id + ] + ); + } + } + } + /** * Add scripts and styles */ @@ -193,6 +305,11 @@ public function initFilters() { $this->setupAdminFilters(); $this->setupQueryFilters(); + + WPCPT_Tables_QueryFilters::$active = false; + $this->getOrphanedMeta(); + $this->getOrphanedPosts(); + WPCPT_Tables_QueryFilters::activate(); } /** @@ -216,7 +333,7 @@ private function setupQueryFilters() */ private function setupSettings() { - new WPCPT_Tables_Settings( + $this->settings = new WPCPT_Tables_Settings( new WPCPT_Tables_Table($this->db, $this->config), new WPCPT_Tables_Triggers($this->db, $this->config), $this->config @@ -230,6 +347,7 @@ public function activatePlugin() { register_uninstall_hook(__FILE__, [$this, 'delete_plugin']); $this->helper->triggerConnector(); + $this->checkTablesAndCompareToPostTypes(); flush_rewrite_rules(); } @@ -239,6 +357,18 @@ public function activatePlugin() public function deactivatePlugin() { $this->helper->triggerConnector('draft'); + + $settings = new WPCPT_Tables_Settings( + new WPCPT_Tables_Table($this->db, $this->config), + new WPCPT_Tables_Triggers($this->db, $this->config), + $this->config + ); + + $post_types = $this->config['post_types']; + foreach ($post_types as $post_type) { + $settings->startRevertCustomPostType($post_type, false); + } + flush_rewrite_rules(); } diff --git a/lib/Helper.php b/lib/Helper.php index 62f5c82..9e5cbef 100644 --- a/lib/Helper.php +++ b/lib/Helper.php @@ -25,6 +25,10 @@ public function __construct() } } + /** + * + */ + /** * Delete the post from the main posts table * @@ -34,9 +38,9 @@ public function __construct() */ public function savePostAction(int $post_id, WP_Post $post, bool $update) { - WPCPT_Tables_QueryFilters::$active = false; + WPCPT_Tables_QueryFilters::deactivate(); wp_delete_post($post_id, true); - WPCPT_Tables_QueryFilters::$active = true; + WPCPT_Tables_QueryFilters::activate(); } /** diff --git a/lib/Optimize.php b/lib/Optimize.php index 4c62e2f..4712396 100644 --- a/lib/Optimize.php +++ b/lib/Optimize.php @@ -58,7 +58,7 @@ public function cleanup() if (count($cpt_tables) > 0) { foreach ($cpt_tables as $cpt_table) { error_log('Cronjob: Database empty post meta value cleanup for ' . $wpdb->prefix . 'cpt_' . $cpt_table); - $wpdb->query('DELETE FROM ' . $wpdb->prefix . 'cpt_' . $cpt_table . '_meta WHERE meta_value = "" OR meta_value IS NULL'); + $wpdb->query('DELETE FROM ' . $wpdb->prefix . 'cpt_' . $cpt_table . '_meta WHERE meta_value IS NULL'); $wpdb->query('DELETE cptm FROM ' . $wpdb->prefix . 'cpt_' . $cpt_table . '_meta cptm LEFT JOIN ' . $wpdb->prefix . 'cpt_' . $cpt_table . ' cpt ON cpt.ID = cptm.post_id WHERE cpt.ID IS NULL;'); } } diff --git a/lib/QueryFilters.php b/lib/QueryFilters.php index 33e8d0a..d4f6cfa 100644 --- a/lib/QueryFilters.php +++ b/lib/QueryFilters.php @@ -35,6 +35,20 @@ public function __construct(WPCPT_Tables_Db $db, array $config) add_filter('query', [$this, 'updateQueryTables']); } + public static function deactivate() + { + global $wpdb; + $wpdb->query("SET @disable_triggers = 1;"); + self::$active = false; + } + + public static function activate() + { + global $wpdb; + $wpdb->query("SET @disable_triggers = NULL;"); + self::$active = true; + } + /** * If the query is for a post type that has custom tables set up, replace * the post and meta tables with the custom ones diff --git a/lib/Settings.php b/lib/Settings.php index de25180..995c1ca 100644 --- a/lib/Settings.php +++ b/lib/Settings.php @@ -189,7 +189,7 @@ public function showSettingsPage() * * @return array */ - private function startRevertCustomPostType($postType) + public function startRevertCustomPostType($postType, $show_Notice = true) { $enabledPostTypes = $this->getEnabledPostTypes(); if (($key = array_search($postType, $enabledPostTypes)) !== false) { @@ -204,7 +204,9 @@ private function startRevertCustomPostType($postType) $this->revertCustomPostType($postType); // Add notice and redirect - $this->notices->add(sprintf(__('Custom post type %s has been reverted to the posts table', 'cpt-tables'), $postType)); + if ($show_Notice) { + $this->notices->add(sprintf(__('Custom post type %s has been reverted to the posts table', 'cpt-tables'), $postType)); + } // Redirect wp_safe_redirect($this->redirect_uri); diff --git a/lib/Table.php b/lib/Table.php index eaae068..2fe6a2b 100644 --- a/lib/Table.php +++ b/lib/Table.php @@ -155,7 +155,7 @@ public function revert(string $table) $successMessage .= 'Tables deleted: ' . $table . ', ' . $table . '_meta
'; } - WPCPT_Tables_QueryFilters::$active = true; + WPCPT_Tables_QueryFilters::activate(); } /** @@ -262,7 +262,7 @@ public function migrate(string $table) $this->db->query($query, ...$params); } - WPCPT_Tables_QueryFilters::$active = true; + WPCPT_Tables_QueryFilters::activate(); if ($hasErrors) { $this->notices->add($errorMessage, 'error'); diff --git a/lib/Triggers.php b/lib/Triggers.php index 16c484b..47ca946 100644 --- a/lib/Triggers.php +++ b/lib/Triggers.php @@ -113,8 +113,7 @@ private function insertPostTrigger(array $tables) // Create the copy from wp_posts to custom table trigger $params = []; $query = sprintf( - "CREATE TRIGGER %s - AFTER INSERT ON %s FOR EACH ROW BEGIN ", + "CREATE TRIGGER %s AFTER INSERT ON %s FOR EACH ROW BEGIN IF @disable_triggers IS NULL THEN ", $this->db->escape($this->config['prefix'] . $this->insertPostTrigger), $this->db->escape($this->config['default_post_table']) ); @@ -138,7 +137,7 @@ private function insertPostTrigger(array $tables) $params[] = $postType; } - $query .= "END IF; END"; + $query .= "END IF; END IF; END"; $this->db->query($query, ...$params); } @@ -168,8 +167,7 @@ private function insertMetaTrigger(array $tables) // Create the post meta copy trigger $params = []; $query = sprintf( - "CREATE TRIGGER %s - AFTER INSERT ON %s FOR EACH ROW BEGIN ", + "CREATE TRIGGER %s AFTER INSERT ON %s FOR EACH ROW BEGIN IF @disable_triggers IS NULL THEN ", $this->db->escape($this->config['prefix'] . $this->insertMetaTrigger), $this->db->escape($this->config['default_meta_table']) ); @@ -193,7 +191,7 @@ private function insertMetaTrigger(array $tables) $params[] = $postType; } - $query .= "END IF; END"; + $query .= "END IF; END IF; END"; $this->db->query($query, ...$params); diff --git a/readme.txt b/readme.txt index dab8edc..88becd2 100644 --- a/readme.txt +++ b/readme.txt @@ -3,7 +3,7 @@ Donate link: https://paypal.me/klausi4711 Tags: custom post types, CPT, CMS, post, types, post type, custom, content types, custom content types, post types Requires at least: 5.9 Tested up to: 6.2 -Stable tag: 1.2.2 +Stable tag: 1.2.6 Requires PHP: 7.1 License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html @@ -75,6 +75,27 @@ Check out the [GitHub repository](https://github.com/caspahouzer/wp-cpt-tables) == Changelog == +=== 1.2.6 === + +* Find orphaned meta values and copy to new custom table +* Trigger optimization + +=== 1.2.5.2 === + +* Hotfix: Altered correct auto_increment field for meta table + +=== 1.2.5 === + +* Removed autoincrement from copied table as it is controles by the posts_table (Revert CPT Tables and migrate them again to get the changes working) + +=== 1.2.4 === + +* Bugfix in cleanup-cronjob + +=== 1.2.3 === + +* Revert tables on plugin deactivation + === 1.2.2 === * German translation diff --git a/wp-cpt-tables.php b/wp-cpt-tables.php index 73440d1..f677269 100644 --- a/wp-cpt-tables.php +++ b/wp-cpt-tables.php @@ -4,11 +4,11 @@ * Plugin Name: CPT Tables * Plugin URI: https://wordpress.org/plugins/cpt-tables/ * Description: Allow storing custom post types in their own tables in order to make querying large datasets more efficient - * Version: 1.2.2 + * Version: 1.2.6 * Requires at least: 5.9 * Requires PHP: 7.1 * Author: Sebastian Klaus - * Author URI: https://lightapps.de + * Author URI: https://github.com/caspahouzer/wp-cpt-tables/ * License: GPL v2 or later * License URI: https://www.gnu.org/licenses/gpl-2.0.html * Text Domain: cpt-tables