Skip to content

Commit

Permalink
- proper delete of nulled fields
Browse files Browse the repository at this point in the history
- pause QueryFilters with trigger option
- optimized triggers
  • Loading branch information
caspahouzer committed May 6, 2023
1 parent 219eb60 commit 3eeff92
Show file tree
Hide file tree
Showing 9 changed files with 190 additions and 21 deletions.
140 changes: 135 additions & 5 deletions core.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class WPCPT_Tables_Core
*/
private $helper;

/**
* @var WPCPT_Tables_Settings
*/
private $settings;

/**
* @var LightApps_Connector
*/
Expand Down Expand Up @@ -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();
Expand All @@ -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();
}

Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
}

Expand All @@ -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
*/
Expand All @@ -193,6 +305,11 @@ public function initFilters()
{
$this->setupAdminFilters();
$this->setupQueryFilters();

WPCPT_Tables_QueryFilters::$active = false;
$this->getOrphanedMeta();
$this->getOrphanedPosts();
WPCPT_Tables_QueryFilters::activate();
}

/**
Expand All @@ -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
Expand All @@ -230,6 +347,7 @@ public function activatePlugin()
{
register_uninstall_hook(__FILE__, [$this, 'delete_plugin']);
$this->helper->triggerConnector();
$this->checkTablesAndCompareToPostTypes();
flush_rewrite_rules();
}

Expand All @@ -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();
}

Expand Down
8 changes: 6 additions & 2 deletions lib/Helper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ public function __construct()
}
}

/**
*
*/

/**
* Delete the post from the main posts table
*
Expand All @@ -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();
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/Optimize.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;');
}
}
Expand Down
14 changes: 14 additions & 0 deletions lib/QueryFilters.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions lib/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -204,7 +204,9 @@ private function startRevertCustomPostType($postType)
$this->revertCustomPostType($postType);

// Add notice and redirect
$this->notices->add(sprintf(__('Custom post type <strong>%s</strong> has been reverted to the posts table', 'cpt-tables'), $postType));
if ($show_Notice) {
$this->notices->add(sprintf(__('Custom post type <strong>%s</strong> has been reverted to the posts table', 'cpt-tables'), $postType));
}

// Redirect
wp_safe_redirect($this->redirect_uri);
Expand Down
4 changes: 2 additions & 2 deletions lib/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public function revert(string $table)
$successMessage .= 'Tables deleted: ' . $table . ', ' . $table . '_meta<br/>';
}

WPCPT_Tables_QueryFilters::$active = true;
WPCPT_Tables_QueryFilters::activate();
}

/**
Expand Down Expand Up @@ -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');
Expand Down
10 changes: 4 additions & 6 deletions lib/Triggers.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'])
);
Expand All @@ -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);
}
Expand Down Expand Up @@ -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'])
);
Expand All @@ -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);

Expand Down
23 changes: 22 additions & 1 deletion readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions wp-cpt-tables.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3eeff92

Please sign in to comment.