initial commit

This commit is contained in:
2024-04-29 13:12:44 +05:45
commit 34887303c5
19300 changed files with 5268802 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
/**
* Class WP_Optimization_attachments
*/
class WP_Optimization_attachments extends WP_Optimization {
public $ui_sort_order = 4500;
public $available_for_auto = false;
public $auto_default = false;
/**
* Display or hide optimization in optimizations list.
*
* @return bool
*/
public function display_in_optimizations_list() {
return false;
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s orphaned attachment deleted', '%s orphaned attachments deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
$sql = "SELECT p.ID FROM `".$this->wpdb->posts."` p LEFT JOIN `".$this->wpdb->posts."` pp ON pp.ID = p.post_parent WHERE p.post_parent > 0 AND p.post_type = 'attachment' AND pp.ID IS NULL;";
$attachment_ids = $this->wpdb->get_col($sql);
$count_ids = count($attachment_ids);
if ($count_ids > 0) {
foreach ($attachment_ids as $attachment_id) {
wp_delete_attachment($attachment_id, true);
}
}
$this->processed_count += $count_ids;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count) {
$message = sprintf(_n('%s orphaned attachment found', '%s orphaned attachments found', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No orphaned attachments found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->register_output($message);
}
/**
* Estimate count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` p LEFT JOIN `" . $this->wpdb->posts . "` pp ON pp.ID = p.post_parent WHERE p.post_parent > 0 AND p.post_type = 'attachment' AND pp.ID IS NULL;";
$postmeta = $this->wpdb->get_var($sql);
$this->found_count += $postmeta;
}
/**
* Returns settings label
*
* @return string|void
*/
public function settings_label() {
return __('Remove orphaned attachments', 'wp-optimize');
}
/**
* Return description
* N.B. This is not currently used; it was commented out in 1.9.1
*
* @return string|void
*/
public function get_auto_option_description() {
return __('Remove orphaned attachments', 'wp-optimize');
}
}

View File

@@ -0,0 +1,179 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_autodraft extends WP_Optimization {
public $available_for_auto = true;
public $auto_default = true;
public $setting_default = true;
public $available_for_saving = true;
public $ui_sort_order = 3000;
protected $setting_id = 'drafts';
protected $auto_id = 'drafts';
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get data requested for preview.
$retention_subquery = '';
if ('true' == $this->retention_enabled) {
$retention_subquery = ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql = $this->wpdb->prepare(
"SELECT `ID`, `post_title`, `post_date` FROM `" . $this->wpdb->posts . "`".
" WHERE post_status = 'auto-draft'".
$retention_subquery.
" ORDER BY `ID` LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($posts)) {
foreach ($posts as $key => $post) {
$posts[$key]['post_title'] = '' == $post['post_title'] ? '('.__('no title', 'wp-optimize').')' : $post['post_title'];
}
}
// get total count auto-draft for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` WHERE post_status = 'auto-draft' ".$retention_subquery.";";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'ID',
'columns' => array(
'ID' => __('ID', 'wp-optimize'),
'post_title' => __('Title', 'wp-optimize'),
'post_date' => __('Date', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('ID')),
'message' => $total > 0 ? '' : __('No auto draft posts found', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$info_message = sprintf(_n('%s auto draft deleted', '%s auto drafts deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$info_message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($info_message);
$this->register_output($info_message);
}
/**
* Do optimization.
*/
public function optimize() {
$clean = "DELETE FROM `" . $this->wpdb->posts . "` WHERE post_status = 'auto-draft'";
if ('true' == $this->retention_enabled) {
$clean .= ' AND post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND `ID` in ('.join(',', $this->data['ids']).')';
}
$clean .= ';';
$this->processed_count += $this->query($clean);
// clean orphaned post meta.
$clean = "DELETE pm FROM `" . $this->wpdb->postmeta . "` pm LEFT JOIN `" . $this->wpdb->posts . "` p ON pm.post_id = p.ID WHERE p.ID IS NULL";
$this->query($clean);
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if (0 != $this->found_count && null != $this->found_count) {
$message = sprintf(_n('%s auto draft post in your database', '%s auto draft posts in your database', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No auto draft posts found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link for output.
if (0 != $this->found_count && null != $this->found_count) {
$message = $this->get_preview_link($message);
}
$this->register_output($message);
}
/**
* Get count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` WHERE post_status = 'auto-draft'";
if ('true' == $this->retention_enabled) {
$sql .= ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql .= ';';
$this->found_count += $this->wpdb->get_var($sql);
}
/**
* Return settings label
*
* @return string|void
*/
public function settings_label() {
if ('true' == $this->retention_enabled) {
return sprintf(__('Clean auto draft posts which are older than %s weeks', 'wp-optimize'), $this->retention_period);
} else {
return __('Clean all auto-draft posts', 'wp-optimize');
}
}
/**
* Return description
*
* @return string|void
*/
public function get_auto_option_description() {
return __('Remove auto-draft posts', 'wp-optimize');
}
}

View File

@@ -0,0 +1,212 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_commentmeta extends WP_Optimization {
public $ui_sort_order = 9000;
public $available_for_saving = true;
private $processed_trash_count;
private $processed_akismet_count;
private $found_trash_count;
private $found_akismet_count;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get clicked comment type link.
$type = isset($params['type']) && 'akismet' == $params['type'] ? 'akismet' : 'trash';
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT * FROM `" . $this->wpdb->commentmeta . "`".
" WHERE ".
('trash' == $type ? "comment_id NOT IN (SELECT comment_id FROM `" . $this->wpdb->comments . "`)" : "").
('akismet' == $type ? "meta_key LIKE" : "").
" %s ORDER BY `comment_ID` LIMIT %d, %d;",
array(
('akismet' == $type ? '%akismet%' : ''),
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($posts)) {
foreach ($posts as $key => $post) {
$posts[$key]['post_title'] = array(
'text' => '' == $post['post_title'] ? '('.__('no title', 'wp-optimize').')' : $post['post_title'],
'url' => get_edit_post_link($post['ID']),
);
}
}
// get total count comments for optimization.
$sql = $this->wpdb->prepare(
"SELECT COUNT(*) FROM `" . $this->wpdb->comments . "`".
"WHERE ".
('trash' == $type ? "comment_id NOT IN (SELECT comment_id FROM `" . $this->wpdb->comments . "`)" : "").
('akismet' == $type ? "meta_key LIKE " : "").
" %s;",
array(
('akismet' == $type ? '%akismet%' : ''),
)
);
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'meta_id',
'columns' => array(
'meta_id' => __('ID', 'wp-optimize'),
'comment_id' => __('Comment ID', 'wp-optimize'),
'meta_key' => __('Meta Key', 'wp-optimize'),
'meta_value' => __('Meta Value', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('comment_ID')),
'message' => $total > 0 ? '' : __('No orphaned comment meta data in your database', 'wp-optimize'),
);
}
/**
* Do actions before optimize() function.
*/
public function before_optimize() {
$this->processed_trash_count = 0;
$this->processed_akismet_count = 0;
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s unused comment metadata item removed', '%s unused comment metadata items removed', $this->processed_trash_count, 'wp-optimize'), number_format_i18n($this->processed_trash_count));
$message1 = sprintf(_n('%s unused akismet comment metadata item removed', '%s unused akismet comment metadata items removed', $this->processed_akismet_count, 'wp-optimize'), number_format_i18n($this->processed_akismet_count));
if ($this->is_multisite_mode()) {
$blogs_count_text = ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
$message .= $blogs_count_text;
$message1 .= $blogs_count_text;
}
$this->logger->info($message);
$this->register_output($message);
$this->logger->info($message1);
$this->register_output($message1);
}
/**
* This needs reviewing when we review the whole cron-run set of options.
*/
public function optimize() {
$clean = "DELETE FROM `" . $this->wpdb->commentmeta . "` WHERE comment_id NOT IN (SELECT comment_id FROM `" . $this->wpdb->comments . "`)";
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND meta_id in ('.join(',', $this->data['ids']).')';
}
$clean .= ";";
$commentstrash_meta = $this->query($clean);
$this->processed_trash_count += $commentstrash_meta;
$clean = "DELETE FROM `" . $this->wpdb->commentmeta . "` WHERE meta_key LIKE '%akismet%'";
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND meta_id in ('.join(',', $this->data['ids']).')';
}
$clean .= ";";
$commentstrash_meta2 = $this->query($clean);
$this->processed_akismet_count += $commentstrash_meta2;
}
/**
* Do actions before get_info().
*/
public function before_get_info() {
$this->found_trash_count = 0;
$this->found_akismet_count = 0;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_trash_count > 0) {
$message = sprintf(_n('%s orphaned comment meta data in your database', '%s orphaned comment meta data in your database', $this->found_trash_count, 'wp-optimize'), number_format_i18n($this->found_trash_count));
} else {
$message = __('No orphaned comment meta data in your database', 'wp-optimize');
}
if ($this->found_akismet_count > 0) {
$message1 = sprintf(_n('%s unused Akismet comment meta rows in your database', '%s unused Akismet meta rows in your database', $this->found_akismet_count, 'wp-optimize'), number_format_i18n($this->found_akismet_count));
} else {
$message1 = __('No Akismet comment meta rows in your database', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$blogs_count_text = ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
$message .= $blogs_count_text;
$message1 .= $blogs_count_text;
}
if ($this->found_trash_count > 0) {
$message = $this->get_preview_link($message, array('data-type' => 'trash'));
}
if ($this->found_akismet_count > 0) {
$message1 = $this->get_preview_link($message1, array('data-type' => 'akismet'));
}
$this->register_output($message);
$this->register_output($message1);
}
/**
* Get count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->commentmeta . "` WHERE comment_id NOT IN (SELECT comment_id FROM `" . $this->wpdb->comments . "`);";
$commentmeta = $this->wpdb->get_var($sql);
$this->found_trash_count += $commentmeta;
$sql = "SELECT COUNT(*) FROM `".$this->wpdb->commentmeta."` WHERE meta_key LIKE '%akismet%';";
$akismetmeta = $this->wpdb->get_var($sql);
$this->found_akismet_count += $akismetmeta;
}
public function settings_label() {
return __('Clean comment meta data', 'wp-optimize');
}
public function get_auto_option_description() {
return __('Clean comment meta data', 'wp-optimize');
}
}

View File

@@ -0,0 +1,32 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_tags extends WP_Optimization {
public $available_for_auto = false;
public $auto_default = false;
public $ui_sort_order = 12000;
public function optimize() {
}
public function get_info() {
}
public function settings_label() {
return __('Remove unused tags', 'wp-optimize');
}
/**
* Return description
* N.B. This is not currently used; it was commented out in 1.9.1
*
* @return string|void
*/
public function get_auto_option_description() {
}
}

View File

@@ -0,0 +1,186 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_optimizetables extends WP_Optimization {
protected $auto_id = 'optimize';
protected $setting_id = 'optimize';
protected $dom_id = 'optimize-db';
public $available_for_saving = true;
public $available_for_auto = true;
public $setting_default = true;
public $changes_table_data = true;
public $ui_sort_order = 500;
public $run_sort_order = 100000;
public $run_multisite = true;
public $support_preview = false;
private $table_information = array();
/**
* Optimize method.
*/
public function optimize() {
// We don't need run anything in this method to avoid issues on multisite installations.
}
/**
* Run optimization.
*/
public function after_optimize() {
// check if force optimize sent.
$force = (isset($this->data['optimization_force']) && $this->data['optimization_force']) ? true : false;
// check if single table name posted or optimize all tables.
if (isset($this->data['optimization_table']) && '' != $this->data['optimization_table']) {
$table = $this->optimizer->get_table($this->data['optimization_table']);
if (false !== $table) {
$this->optimize_table($table, $force);
// Exit if the UI elements aren't required
if (isset($this->data['include_ui_elements']) && !$this->data['include_ui_elements']) return;
$wp_optimize = WP_Optimize();
$tablestatus = $wp_optimize->get_db_info()->get_table_status($table->Name, true);
$is_optimizable = $wp_optimize->get_db_info()->is_table_optimizable($table->Name);
$tableinfo = array(
'rows' => number_format_i18n($tablestatus->Rows),
'data_size' => $wp_optimize->format_size($tablestatus->Data_length),
'index_size' => $wp_optimize->format_size($tablestatus->Index_length),
'overhead' => $is_optimizable ? $wp_optimize->format_size($tablestatus->Data_free) : '-',
'type' => $table->Engine,
'is_optimizable' => $is_optimizable,
);
$this->register_meta('tableinfo', $tableinfo);
$tables = $this->optimizer->get_tables(true);
$overhead_usage = 0;
foreach ($tables as $table) {
if ($table->is_optimizable) {
$overhead_usage += $table->Data_free;
}
}
$this->register_meta('overhead', $overhead_usage);
$this->register_meta('overhead_formatted', $wp_optimize->format_size($overhead_usage));
} else {
$this->register_meta('error', 1);
$this->register_meta('message', sprintf(__('The table "%s" does not exist.', 'wp-optimize'), $this->data['optimization_table']));
return false;
}
} else {
$tables = $this->optimizer->get_tables();
foreach ($tables as $table) {
$this->optimize_table($table, $force);
}
}
}
/**
* Optimize table and generate log and output information.
*
* @param object $table_obj table object returned by $this->optimizer->get_tables().
* @param bool $force if true then will optimize
*/
private function optimize_table($table_obj, $force = false) {
// if not forced and table is not optimizable then exit.
if (false == $force && (false == $table_obj->is_optimizable || false == $table_obj->is_type_supported)) return;
if ($table_obj->is_type_supported) {
$this->logger->info('Optimizing: ' . $table_obj->Name);
$this->query('OPTIMIZE TABLE `' . $table_obj->Name . '`');
// For InnoDB Data_free doesn't contain free size.
if ('InnoDB' != $table_obj->Engine) {
$this->optimizer->update_total_cleaned(strval($table_obj->Data_free));
}
$this->register_output(__('Optimized table:', 'wp-optimize') . ' ' . $table_obj->Name);
}
}
/**
* Before get_info() actions.
*/
public function before_get_info() {
$this->table_information['total_gain'] = 0;
$this->table_information['inno_db_tables'] = 0;
$this->table_information['non_inno_db_tables'] = 0;
$this->table_information['table_list'] = '';
$this->table_information['is_optimizable'] = true;
}
/**
* Get information to be disbalyed onscreen before optimization.
*/
public function get_info() {
$table_information = $this->optimizer->get_table_information(get_current_blog_id());
$this->table_information['total_gain'] += $table_information['total_gain'];
$this->table_information['inno_db_tables'] += $table_information['inno_db_tables'];
$this->table_information['non_inno_db_tables'] += $table_information['non_inno_db_tables'];
$this->table_information['table_list'] .= $table_information['table_list'];
if (!$table_information['is_optimizable']) {
$this->table_information['is_optimizable'] = false;
}
}
/**
* Return info about optimization.
*/
public function after_get_info() {
// This gathers information to be displayed onscreen before optimization.
$tablesstatus = $this->table_information;
// Check if database is not optimizable.
if (false === $tablesstatus['is_optimizable']) {
if (isset($this->data['optimization_table']) && '' != $this->data['optimization_table']) {
// This is used for grabbing information before optimizations.
$this->register_output(__('Total gain:', 'wp-optimize').' '.WP_Optimize()->format_size(($tablesstatus['total_gain'])));
}
if ($tablesstatus['inno_db_tables'] > 0) {
// Output message for how many InnoDB tables will not be optimized.
$this->register_output(sprintf(__('Tables using the InnoDB engine (%d) will not be optimized.'), $tablesstatus['inno_db_tables']));
if ($tablesstatus['non_inno_db_tables'] > 0) {
$this->register_output(sprintf(__('Other tables will be optimized (%s).', 'wp-optimize'), $tablesstatus['non_inno_db_tables']));
}
$faq_url = apply_filters('wpo_faq_url', 'https://getwpo.com/faqs/');
$force_db_option = $this->options->get_option('innodb-force-optimize', 'false');
$this->register_output('<input id="innodb_force_optimize" name="innodb-force-optimize" type="checkbox" value="true" '.checked($force_db_option, 'true').'><label for="innodb_force_optimize">'.__('Optimize InnoDB tables anyway.', 'wp-optimize').'</label><br><a href="'.$faq_url.'" target="_blank">'.__('Warning: you should read the FAQ on the risks of this operation first.', 'wp-optimize').'</a>');
}
} else {
$this->register_output(sprintf(__('Tables will be optimized (%s).', 'wp-optimize'), $tablesstatus['non_inno_db_tables'] + $tablesstatus['inno_db_tables']));
}
}
public function get_auto_option_description() {
return __('Optimize database tables', 'wp-optimize');
}
public function settings_label() {
return __('Optimize database tables', 'wp-optimize');
}
}

View File

@@ -0,0 +1,67 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_orphandata extends WP_Optimization {
public $ui_sort_order = 10000;
public $available_for_saving = true;
public $support_preview = false;
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s orphaned relationship data deleted', '%s orphaned relationship data deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
$clean = "DELETE FROM `" . $this->wpdb->term_relationships . "` WHERE term_taxonomy_id=1 AND object_id NOT IN (SELECT id FROM `" . $this->wpdb->posts . "`);";
$orphandata = $this->query($clean);
$this->processed_count += $orphandata;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count > 0) {
$message = sprintf(_n('%s orphaned relationship data in your database', '%s orphaned relationship data in your database', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No orphaned relationship data in your database', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->register_output($message);
}
/**
* Get count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->term_relationships . "` WHERE term_taxonomy_id=1 AND object_id NOT IN (SELECT id FROM `" . $this->wpdb->posts . "`);";
$orphandata = $this->wpdb->get_var($sql);
$this->found_count += $orphandata;
}
public function settings_label() {
return __('Clean orphaned relationship data', 'wp-optimize');
}
}

View File

@@ -0,0 +1,196 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_orphanedtables extends WP_Optimization {
public $available_for_auto = false;
public $setting_default = true;
public $changes_table_data = true;
public $run_multisite = false;
private $last_message;
/**
* Display or hide optimization in optimizations list.
*
* @return bool
*/
public function display_in_optimizations_list() {
return false;
}
/**
* Run optimization.
*/
public function optimize() {
// check if the data contain action attribute then lead to innoDb conversion.
if (isset($this->data['optimization_action']) && 'toinnodb' == $this->data['optimization_action']) {
$table = $this->optimizer->get_table($this->data['optimization_table']);
if (false === $table) {
$this->register_meta('error', 1);
$this->register_meta('message', sprintf(__('The table "%s" does not exist.', 'wp-optimize'), $this->data['optimization_table']));
return false;
}
$result = $this->convert_table($table);
if (false === $result) {
$this->register_meta('message', $this->last_message);
return false;
}
$this->register_meta('success', 1);
return true;
}
// check if single table name posted or optimize all tables.
if (isset($this->data['optimization_table']) && '' != $this->data['optimization_table']) {
$table = $this->optimizer->get_table($this->data['optimization_table']);
if (false === $table) {
$this->register_meta('error', 1);
$this->register_meta('message', sprintf(__('The table "%s" does not exist.', 'wp-optimize'), $this->data['optimization_table']));
return false;
}
$result = $this->delete_table($table);
if (false === $result) {
$this->register_meta('message', $this->last_message);
return false;
}
$this->register_meta('success', 1);
} else {
// delete all orphaned tables if table name was not selected.
$tables = $this->optimizer->get_tables();
$deleted = 0;
foreach ($tables as $table) {
if ($table->is_using) continue;
if ($this->delete_table($table)) {
$deleted++;
}
}
$this->register_output(sprintf(_n('%s orphaned table deleted', '%s orphaned tables deleted', $deleted), $deleted));
if ($deleted > 0) {
$this->register_output(sprintf(_n('Deleting %s orphaned table was unsuccessful', 'Repairing %s orphaned tables were unsuccessful', $deleted), $deleted));
}
}
}
/**
* Alter table engine to InnoDB.
*
* @param object $table_obj object contains information about database table.
*
* @return bool
*/
private function convert_table($table_obj) {
global $wpdb;
$inno_db = 0;
// check InnoDB is Active
$mysql_engine = $wpdb->get_results('SHOW ENGINES');
foreach ($mysql_engine as $check) {
if ('InnoDB' == $check->Engine && ('DEFAULT' == $check->Support || 'YES' == $check->Support)) {
$inno_db=1;
}
}
if (0 == $inno_db) return false;
// If InnoDB is active then convert MyISAM to InnoDB.
else {
$table_name = sanitize_text_field($table_obj->Name);
$sql_query = $wpdb->prepare("ALTER TABLE `%1s` ENGINE=InnoDB", $table_name);
$this->logger->info($sql_query);
$result = $wpdb->query($sql_query);
}
// check if alter query finished successfully.
if ('' != $wpdb->last_error) {
$this->last_message = $wpdb->last_error;
$this->logger->info($wpdb->last_error);
}
return $result;
}
/**
* Drop table from database.
*
* @param object $table_obj object contains information about database table.
*
* @return bool
*/
private function delete_table($table_obj) {
global $wpdb;
// don't delete table if it in use and plugin active.
if (!$table_obj->can_be_removed) return true;
$table_name = sanitize_text_field($table_obj->Name);
$sql_query = $wpdb->prepare("DROP TABLE `%1s`", $table_name);
$this->logger->info($sql_query);
$result = $wpdb->query($sql_query);
// check if drop query finished successfully.
if ('' != $wpdb->last_error) {
$this->last_message = $wpdb->last_error;
$this->logger->info($wpdb->last_error);
}
return $result;
}
/**
* Get count of unused database tables, i.e. not using by any of installed plugin.
*
* @return int
*/
public function get_unused_tables_count() {
$tablesinfo = $this->optimizer->get_tables();
$unused_tables = 0;
if (!empty($tablesinfo)) {
foreach ($tablesinfo as $tableinfo) {
if (false == $tableinfo->is_using) {
$unused_tables++;
}
}
}
return $unused_tables;
}
/**
* Register info about optimization.
*/
public function get_info() {
$corrupted_tables = $this->get_unused_tables_count();
if (0 == $corrupted_tables) {
$this->register_output(__('No corrupted tables found', 'wp-optimize'));
} else {
$this->register_output(sprintf(_n('%s corrupted table found', '%s corrupted tables found', $corrupted_tables), $corrupted_tables));
}
}
/**
* Returns settings label.
*
* @return string
*/
public function settings_label() {
return __('Delete orphaned database tables', 'wp-optimize');
}
}

View File

@@ -0,0 +1,141 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_pingbacks extends WP_Optimization {
public $ui_sort_order = 6000;
public $available_for_saving = true;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT comment_ID, comment_author, SUBSTR(comment_content, 1, 128) AS comment_content FROM `" . $this->wpdb->comments . "`".
" WHERE comment_type = 'pingback'".
" ORDER BY `comment_ID` LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($posts)) {
foreach ($posts as $key => $post) {
$posts[$key]['post_title'] = array(
'text' => '' == $post['post_title'] ? '('.__('no title', 'wp-optimize').')' : $post['post_title'],
'url' => get_edit_post_link($post['ID']),
);
}
}
// get total count comments for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_type = 'pingback';";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'comment_ID',
'columns' => array(
'comment_ID' => __('ID', 'wp-optimize'),
'comment_author' => __('Author', 'wp-optimize'),
'comment_content' => __('Comment', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('comment_ID')),
'message' => $total > 0 ? '' : __('No pingbacks found', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s pingback deleted', '%s pingbacks deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
$clean = "DELETE FROM `" . $this->wpdb->comments . "` WHERE comment_type = 'pingback'";
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND comment_ID in ('.join(',', $this->data['ids']).')';
}
$clean .= ";";
$comments = $this->query($clean);
$this->processed_count += $comments;
// update comment count
$update = "UPDATE `" . $this->wpdb->posts . "` as p
INNER JOIN (SELECT comment_post_ID as cid, COUNT(comment_post_ID) as cc
FROM `" . $this->wpdb->comments . "` GROUP BY comment_post_ID) AS c ON p.ID = c.cid
SET p.comment_count = c.cc
WHERE p.ID = c.cid";
$this->query($update);
// clean orphaned comment meta
$clean = "DELETE cm FROM `" . $this->wpdb->commentmeta . "` cm LEFT JOIN `" . $this->wpdb->comments . "` c ON cm.comment_id = c.comment_ID WHERE c.comment_ID IS NULL";
$this->query($clean);
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count > 0) {
$message = sprintf(_n('%s pingback found', '%s pingbacks found', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No pingbacks found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link to message.
if ($this->found_count > 0) {
$message = $this->get_preview_link($message);
}
$this->register_output($message);
}
/**
* Get count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_type='pingback';";
$comments = $this->wpdb->get_var($sql);
$this->found_count += $comments;
}
public function settings_label() {
return __('Remove pingbacks', 'wp-optimize');
}
}

View File

@@ -0,0 +1,133 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_postmeta extends WP_Optimization {
public $ui_sort_order = 8000;
public $available_for_auto = false;
public $available_for_saving = true;
public $auto_default = false;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT pm.* FROM `" . $this->wpdb->postmeta . "` pm".
" LEFT JOIN `" . $this->wpdb->posts . "` wp ON wp.ID = pm.post_id".
" WHERE wp.ID IS NULL".
" ORDER BY pm.meta_id LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// get total count post meta for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->postmeta . "` pm LEFT JOIN `" . $this->wpdb->posts . "` wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL;";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'meta_id',
'columns' => array(
'meta_id' => __('ID', 'wp-optimize'),
'post_id' => __('Post ID', 'wp-optimize'),
'meta_key' => __('Meta Key', 'wp-optimize'),
'meta_value' => __('Meta Value', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('ID')),
'message' => $total > 0 ? '' : __('No orphaned post meta data in your database', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s orphaned post meta data deleted', '%s orphaned post meta data deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
$clean = "DELETE pm FROM `" . $this->wpdb->postmeta . "` pm LEFT JOIN `" . $this->wpdb->posts . "` wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL";
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND pm.meta_id in ('.join(',', $this->data['ids']).')';
}
$clean .= ";";
$postmeta = $this->query($clean);
$this->processed_count += $postmeta;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count) {
$message = sprintf(_n('%s orphaned post meta data in your database', '%s orphaned post meta data in your database', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No orphaned post meta data in your database', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link to message.
if ($this->found_count > 0) {
$message = $this->get_preview_link($message);
}
$this->register_output($message);
}
/**
* Get count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->postmeta . "` pm LEFT JOIN `" . $this->wpdb->posts . "` wp ON wp.ID = pm.post_id WHERE wp.ID IS NULL;";
$postmeta = $this->wpdb->get_var($sql);
$this->found_count += $postmeta;
}
public function settings_label() {
return __('Clean post meta data', 'wp-optimize');
}
/**
* N.B. This is not currently used; it was commented out in 1.9.1
*
* @return string Returns the description once auto remove option has ran
*/
public function get_auto_option_description() {
return __('Remove orphaned post meta', 'wp-optimize');
}
}

View File

@@ -0,0 +1,159 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_repairtables extends WP_Optimization {
public $available_for_auto = false;
public $setting_default = true;
public $changes_table_data = true;
public $run_multisite = false;
public $support_preview = false;
/**
* Display or hide optimization in optimizations list.
*
* @return bool
*/
public function display_in_optimizations_list() {
return false;
}
/**
* Run optimization.
*/
public function optimize() {
// check if single table name posted or optimize all tables.
if (isset($this->data['optimization_table']) && '' != $this->data['optimization_table']) {
$table = $this->optimizer->get_table($this->data['optimization_table']);
$result = (false === $table) ? false : $this->repair_table($table);
if ($result) {
$wp_optimize = WP_Optimize();
$tablestatus = $wp_optimize->get_db_info()->get_table_status($table->Name, true);
$is_optimizable = $wp_optimize->get_db_info()->is_table_optimizable($table->Name);
$is_type_supported = $wp_optimize->get_db_info()->is_table_type_optimize_supported($table->Name);
$tableinfo = array(
'rows' => number_format_i18n($tablestatus->Rows),
'data_size' => $wp_optimize->format_size($tablestatus->Data_length),
'index_size' => $wp_optimize->format_size($tablestatus->Index_length),
'overhead' => $is_optimizable ? $wp_optimize->format_size($tablestatus->Data_free) : '-',
'type' => $tablestatus->Engine,
'is_optimizable' => $is_optimizable,
'is_type_supported' => $is_type_supported,
);
$this->register_meta('tableinfo', $tableinfo);
}
$this->register_meta('success', $result);
} else {
$tables = $this->optimizer->get_tables();
$repaired = $corrupted = 0;
foreach ($tables as $table) {
if (false == $table->is_needing_repair) continue;
if ($this->repair_table($table)) {
$repaired++;
} else {
$corrupted++;
}
}
$this->register_output(sprintf(_n('%s table repaired', '%s tables repaired', $repaired), $repaired));
if ($corrupted > 0) {
$this->register_output(sprintf(_n('Repairing %s table was unsuccessful', 'Repairing %s tables were unsuccessful', $corrupted), $corrupted));
}
}
}
/**
* Repair table.
*
* @param object $table_obj object contains information about database table.
*
* @return bool
*/
private function repair_table($table_obj) {
global $wpdb;
$success = false;
if (false == $table_obj->is_needing_repair) return true;
$this->logger->info('REPAIR TABLE `'.$table_obj->Name. '`');
$results = $wpdb->get_results('REPAIR TABLE `'.$table_obj->Name . '`');
if (!empty($results)) {
foreach ($results as $row) {
if ('status' == strtolower($row->Msg_type) && 'ok' == strtolower($row->Msg_text)) {
$success = true;
}
$this->logger->info($row->Msg_text);
}
}
// update info in options table and use it to notify user about corrupted tables.
$this->get_corrupted_tables_count();
return $success;
}
/**
* Returns count of corrupted tables and update corrupted-tables-count value in options used to show
* information for user in sidebar about corrupted tables count.
*/
public function get_corrupted_tables_count() {
$tablesinfo = $this->optimizer->get_tables();
$corrupted_tables = 0;
if (!empty($tablesinfo)) {
foreach ($tablesinfo as $tableinfo) {
if ($tableinfo->is_needing_repair) {
$corrupted_tables++;
}
}
}
// save results to options table and use it to notify user about corrupted tables.
$this->options->update_option('corrupted-tables-count', $corrupted_tables);
return $corrupted_tables;
}
/**
* Register info about optimization.
*/
public function get_info() {
$corrupted_tables = $this->get_corrupted_tables_count();
if (0 == $corrupted_tables) {
$this->register_output(__('No corrupted tables found', 'wp-optimize'));
} else {
$this->register_output(sprintf(_n('%s corrupted table found', '%s corrupted tables found', $corrupted_tables), $corrupted_tables));
}
}
/**
* Returns settings label.
*
* @return string
*/
public function settings_label() {
return __('Repair database tables', 'wp-optimize');
}
}

View File

@@ -0,0 +1,244 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_revisions extends WP_Optimization {
public $ui_sort_order = 1000;
public $available_for_auto = true;
public $auto_default = true;
public $setting_default = true;
public $available_for_saving = true;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
$retention_subquery = '';
if ('true' == $this->retention_enabled) {
$retention_subquery = ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT `ID`, `post_title`, `post_date`".
" FROM `" . $this->wpdb->posts . "`".
" WHERE post_type = 'revision'".
$retention_subquery.
" ORDER BY `ID` LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($posts)) {
foreach ($posts as $key => $post) {
$posts[$key]['post_title'] = '' == $post['post_title'] ? '('.__('no title', 'wp-optimize').')' : $post['post_title'];
}
}
// get total count revisions for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` WHERE post_type = 'revision'".$retention_subquery.";";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'ID',
'columns' => array(
'ID' => __('ID', 'wp-optimize'),
'post_title' => __('Title', 'wp-optimize'),
'post_date' => __('Date', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('ID')),
'message' => $total > 0 ? '' : __('No post revisions found', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s post revision deleted', '%s post revisions deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
if ('true' == $this->revisions_retention_enabled) {
$this->optimize_by_posts();
return;
}
$clean = "DELETE FROM `" . $this->wpdb->posts . "` WHERE post_type = 'revision'";
if ('true' == $this->retention_enabled) {
$clean .= '
AND post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND `ID` in ('.join(',', $this->data['ids']).')';
}
$clean .= ';';
$revisions = $this->query($clean);
$this->processed_count += $revisions;
// clean orphaned post meta.
$clean = "DELETE pm FROM `" . $this->wpdb->postmeta . "` pm LEFT JOIN `" . $this->wpdb->posts . "` p ON pm.post_id = p.ID WHERE p.ID IS NULL";
$this->query($clean);
}
/**
* Optimize post revisions but keep `x` revisions for each post
*/
private function optimize_by_posts() {
// get data requested for preview.
$sql = "SELECT `post_parent`, GROUP_CONCAT(`ID`)".
" FROM `" . $this->wpdb->posts . "`".
" WHERE post_type = 'revision'".
" GROUP BY `post_parent`".
" ORDER BY `post_parent`";
$results = $this->wpdb->get_results($sql, ARRAY_N);
$post_parents = array();
$revisions = '';
foreach ($results as $row) {
array_push($post_parents, $row[0]);
$tmp = explode(',', $row[1]);
rsort($tmp);
$tmp = implode(',', array_slice($tmp, $this->revisions_retention_count));
if ('' !== $tmp) {
$revisions .= $tmp . ',';
}
}
$revisions = rtrim($revisions, ',');
$revisions = explode(',', $revisions);
while (count($revisions) > 0) {
$delete_this_time = array_splice($revisions, 0, min(count($revisions), 250));
$clean = "DELETE FROM `" . $this->wpdb->posts . "` WHERE `ID` IN (" . implode(',', $delete_this_time) . ")";
$count = $this->query($clean);
$this->processed_count += $count;
}
// clean orphaned post meta.
$clean = "DELETE pm FROM `" . $this->wpdb->postmeta . "` pm LEFT JOIN `" . $this->wpdb->posts . "` p ON pm.post_id = p.ID WHERE p.ID IS NULL";
$this->query($clean);
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count > 0) {
$message = sprintf(_n('%s post revision in your database', '%s post revisions in your database', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No post revisions found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' '.sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link to message.
if ($this->found_count > 0) {
$message = $this->get_preview_link($message);
}
$this->register_output($message);
}
public function get_info() {
if ('true' == $this->revisions_retention_enabled) {
$sql = "SELECT `post_parent`, GROUP_CONCAT(`ID`)".
" FROM `" . $this->wpdb->posts . "`".
" WHERE post_type = 'revision'".
" GROUP BY `post_parent`".
" ORDER BY `post_parent`";
$results = $this->wpdb->get_results($sql, ARRAY_N);
$post_parents = array();
$revisions = '';
foreach ($results as $row) {
array_push($post_parents, $row[0]);
$tmp = explode(',', $row[1]);
rsort($tmp);
$tmp = implode(',', array_slice($tmp, $this->revisions_retention_count));
if (!empty($tmp)) {
$revisions .= $tmp . ',';
}
}
$revisions = rtrim($revisions, ',');
if (!empty($revisions)) {
$revisions = explode(',', $revisions);
$this->found_count += count($revisions);
}
} else {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` WHERE post_type = 'revision'";
if ('true' == $this->retention_enabled) {
$sql .= ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql .= ';';
$revisions = $this->wpdb->get_var($sql);
$this->found_count += $revisions;
}
}
/**
* Returns appropriate label string based on option value
*
* @return string
*/
public function settings_label() {
if ('true' == $this->retention_enabled && 'true' == $this->revisions_retention_enabled) {
return sprintf(__('Clean post revisions which are older than %d weeks and keep at least %d revisions', 'wp-optimize'), $this->retention_period, $this->revisions_retention_count);
}
if ('true' == $this->retention_enabled && 'false' == $this->revisions_retention_enabled) {
return sprintf(__('Clean post revisions which are older than %d weeks', 'wp-optimize'), $this->retention_period);
}
if ('false' == $this->retention_enabled && 'true' == $this->revisions_retention_enabled) {
return sprintf(__('Clean post revisions but keep at least %d revisions', 'wp-optimize'), $this->revisions_retention_count);
}
return __('Clean all post revisions', 'wp-optimize');
}
public function get_auto_option_description() {
return __('Clean all post revisions', 'wp-optimize');
}
}

View File

@@ -0,0 +1,260 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_spam extends WP_Optimization {
public $available_for_auto = true;
public $auto_default = true;
public $setting_default = true;
public $available_for_saving = true;
public $ui_sort_order = 3500;
protected $dom_id = 'clean-comments';
protected $setting_id = 'spams';
protected $auto_id = 'spams';
private $processed_spam_count;
private $processed_trash_count;
private $found_spam_count;
private $found_trash_count;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get clicked comment type link.
$type = isset($params['type']) && 'spam' == $params['type'] ? 'spam' : 'trash';
$retention_subquery = '';
if ('true' == $this->retention_enabled) {
$retention_subquery = ' and comment_date < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT comment_ID, comment_author, SUBSTR(comment_content, 1, 128) AS comment_content FROM".
" `" . $this->wpdb->comments . "`".
" WHERE comment_approved = '{$type}'".
$retention_subquery.
" ORDER BY `comment_ID` LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$comments = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($comments)) {
foreach ($comments as $key => $comment) {
$args = array(
'comment_status' => $type,
);
$comments[$key]['comment_content'] = array(
'text' => $comment['comment_content'],
'url' => add_query_arg($args, 'edit-comments.php'),
);
}
}
// get total count comments for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_approved = '{$type}' ".$retention_subquery.";";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'comment_ID',
'columns' => array(
'comment_ID' => __('ID', 'wp-optimize'),
'comment_author' => __('Author', 'wp-optimize'),
'comment_content' => __('Comment', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($comments, array('comment_ID')),
'message' => $total > 0 ? '' : __('No spam or trashed comments found', 'wp-optimize'),
);
}
/**
* Do actions before optimize() function.
*/
public function before_optimize() {
$this->processed_spam_count = 0;
$this->processed_trash_count = 0;
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s spam comment deleted', '%s spam comments deleted', $this->processed_spam_count, 'wp-optimize'), number_format_i18n($this->processed_spam_count));
$message1 = sprintf(_n('%s comment removed from Trash', '%s comments removed from Trash', $this->processed_trash_count, 'wp-optimize'), number_format_i18n($this->processed_trash_count));
if ($this->is_multisite_mode()) {
$blogs_count_text = sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
$message .= ' '.$blogs_count_text;
$message1 .= ' '.$blogs_count_text;
}
$this->logger->info($message);
$this->logger->info($message1);
$this->register_output($message);
$this->register_output($message1);
}
/**
* Do optimization.
*/
public function optimize() {
// remove spam comments.
$this->processed_spam_count += $this->get_count_comments('spam');
$this->delete_comments_by_type('spam');
$this->processed_trash_count += $this->get_count_comments('trash');
$this->delete_comments_by_type('trash');
}
/**
* Delete comments by $type along with comments meta from database.
*
* @param string $type comment type.
* @return array
*/
public function delete_comments_by_type($type) {
$clean = "DELETE c, cm FROM `" . $this->wpdb->comments . "` c LEFT JOIN `" . $this->wpdb->commentmeta . "` cm ON c.comment_ID = cm.comment_id WHERE c.comment_approved = '{$type}'";
if ('true' == $this->retention_enabled) {
$clean .= ' and c.comment_date < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND c.comment_ID in ('.join(',', $this->data['ids']).')';
}
$clean .= ';';
return $this->query($clean);
}
/**
* Do actions before get_info() function.
*/
public function before_get_info() {
$this->found_spam_count = 0;
$this->found_trash_count = 0;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_spam_count > 0) {
$message = sprintf(_n('%s spam comment found', '%s spam comments found', $this->found_spam_count, 'wp-optimize'), number_format_i18n($this->found_spam_count));
// if current version is not premium and Preview feature not supported then
// add to message Review link to comments page
if (!WP_Optimize::is_premium()) {
$message .= ' | <a id="wp-optimize-edit-comments-spam" href="'.admin_url('edit-comments.php?comment_status=spam').'">'.' '.__('Review', 'wp-optimize').'</a>';
}
} else {
$message = __('No spam comments found', 'wp-optimize');
}
if ($this->found_trash_count > 0) {
$message1 = sprintf(_n('%s trashed comment found', '%s trashed comments found', $this->found_trash_count, 'wp-optimize'), number_format_i18n($this->found_trash_count));
// if current version is not premium and Preview feature not supported then
// add to message Review link to comments page
if (!WP_Optimize::is_premium()) {
$message1 .= ' | <a id="wp-optimize-edit-comments-trash" href="'.admin_url('edit-comments.php?comment_status=trash').'">'.' '.__('Review', 'wp-optimize').'</a>';
}
} else {
$message1 = __('No trashed comments found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$blogs_count_text = sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
$message .= ' '.$blogs_count_text;
$message1 .= ' '.$blogs_count_text;
}
// add preview link to message.
if ($this->found_spam_count > 0) {
$message = $this->get_preview_link($message, array('data-type' => 'spam'));
}
// add preview link to message.
if ($this->found_trash_count > 0) {
$message1 = $this->get_preview_link($message1, array('data-type' => 'trash'));
}
$this->register_output($message);
$this->register_output($message1);
}
/**
* Count records those can be optimized.
*/
public function get_info() {
$this->found_spam_count += $this->get_count_comments('spam');
$this->found_trash_count += $this->get_count_comments('trash');
}
/**
* Returns count comments by $type.
*
* @param string $type comment type.
* @return mixed
*/
public function get_count_comments($type) {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_approved = '{$type}'";
if ('true' == $this->retention_enabled) {
$sql .= ' and comment_date < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql .= ';';
return $this->wpdb->get_var($sql);
}
/**
* Do actions after get_info() function.
*/
public function settings_label() {
if ('true' == $this->retention_enabled) {
return sprintf(__('Remove spam and trashed comments which are older than %d weeks', 'wp-optimize'), $this->retention_period);
} else {
return __('Remove spam and trashed comments', 'wp-optimize');
}
}
public function get_auto_option_description() {
return __('Remove spam and trashed comments', 'wp-optimize');
}
}

View File

@@ -0,0 +1,135 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_trackbacks extends WP_Optimization {
public $ui_sort_order = 7000;
public $available_for_saving = true;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT comment_ID, comment_author, SUBSTR(comment_content, 1, 128) AS comment_content".
" FROM `" . $this->wpdb->comments . "`".
" WHERE comment_type = 'trackback'".
" ORDER BY `comment_ID` LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($posts)) {
foreach ($posts as $key => $post) {
$posts[$key]['post_title'] = array(
'text' => '' == $post['post_title'] ? '('.__('no title', 'wp-optimize').')' : $post['post_title'],
'url' => get_edit_post_link($post['ID']),
);
}
}
// get total count comments for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_type = 'trackback';";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'comment_ID',
'columns' => array(
'comment_ID' => __('ID', 'wp-optimize'),
'comment_author' => __('Author', 'wp-optimize'),
'comment_content' => __('Comment', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('comment_ID')),
'message' => $total > 0 ? '' : __('No trackbacks found', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s trackback deleted', '%s trackbacks deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' '. sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link for output.
if (0 != $this->found_count && null != $this->found_count) {
$message = $this->get_preview_link($message);
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
$clean = "DELETE c, cm FROM `" . $this->wpdb->comments . "` c LEFT JOIN `" . $this->wpdb->commentmeta . "` cm ON c.comment_ID = cm.comment_id WHERE comment_type = 'trackback'";
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND comment_ID in ('.join(',', $this->data['ids']).')';
}
$clean .= ";";
$comments = $this->query($clean);
$this->processed_count += $comments;
// update comment count
$update = "UPDATE `" . $this->wpdb->posts . "` as p
INNER JOIN (SELECT comment_post_ID as cid, COUNT(comment_post_ID) as cc
FROM `" . $this->wpdb->comments . "` GROUP BY comment_post_ID) AS c ON p.ID = c.cid
SET p.comment_count = c.cc
WHERE p.ID = c.cid";
$this->query($update);
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count) {
$message = sprintf(_n('%s Trackback found', '%s Trackbacks found', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No trackbacks found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->register_output($message);
}
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_type='trackback';";
$comments = $this->wpdb->get_var($sql);
$this->found_count += $comments;
}
public function settings_label() {
return __('Remove trackbacks', 'wp-optimize');
}
}

View File

@@ -0,0 +1,484 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_transient extends WP_Optimization {
public $available_for_auto = true;
public $available_for_saving = true;
public $auto_default = false;
public $ui_sort_order = 5000;
public $run_multisite = true;
public $support_preview = true;
private $found_count_all = 0;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
// get type of data for return single site or multisite.
$type = isset($params['type']) && 'multisite' == $params['type'] ? 'multisite' : 'single';
// set remove_all_transients for correctly handling "all" checkbox for preview transients.
if (isset($params['remove_all_transients'])) {
$this->data['remove_all_transients'] = $params['remove_all_transients'];
}
// get data requested for preview.
if ('single' == $type) {
$sql = $this->wpdb->prepare("
SELECT
a.option_id,
a.option_name,
SUBSTR(a.option_value, 1, 128) as option_value
FROM
" . $this->wpdb->options . " a
LEFT JOIN
" . $this->wpdb->options . " b
ON
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_transient_') + 1
)
)
WHERE
a.option_name LIKE '_transient_%' AND
a.option_name NOT LIKE '_transient_timeout_%'
". ($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "").
" ORDER BY a.option_id LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$sql_count = "
SELECT
COUNT(*)
FROM
" . $this->wpdb->options . " a
LEFT JOIN
" . $this->wpdb->options . " b
ON
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_transient_') + 1
)
)
WHERE
a.option_name LIKE '_transient_%'
". ($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "");
} else {
$sql = $this->wpdb->prepare("
SELECT
a.meta_id,
a.meta_key,
SUBSTR(a.meta_value, 1, 128) as meta_value
FROM
".$this->wpdb->sitemeta." a
LEFT JOIN
".$this->wpdb->sitemeta." b
ON
b.meta_key = CONCAT(
'_site_transient_timeout_',
SUBSTRING(
a.meta_key,
CHAR_LENGTH('_site_transient_') + 1
)
)
WHERE
a.meta_key LIKE '_site_transient_%' AND
a.meta_key NOT LIKE '_site_transient_timeout_%'
".($this->remove_only_expired() ? " AND b.meta_value < UNIX_TIMESTAMP()" : "").
" ORDER BY a.meta_id LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$sql_count = "
SELECT
COUNT(*)
FROM
".$this->wpdb->sitemeta." a
LEFT JOIN ".$this->wpdb->sitemeta." b
ON
b.meta_key = CONCAT(
'_site_transient_timeout_',
SUBSTRING(
a.meta_key,
CHAR_LENGTH('_site_transient_') + 1
)
)
WHERE
a.meta_key LIKE '_site_transient_%' AND
a.meta_key NOT LIKE '_site_transient_timeout_%'
".($this->remove_only_expired() ? " AND b.meta_value < UNIX_TIMESTAMP()" : "");
}
$posts = $this->wpdb->get_results($sql, ARRAY_A);
$total = $this->wpdb->get_var($sql_count);
// define columns array depends on source type of request.
if ('single' == $type) {
$columns = array(
'option_id' => __('ID', 'wp-optimize'),
'option_name' => __('Name', 'wp-optimize'),
'option_value' => __('Value', 'wp-optimize'),
);
} else {
$columns = array(
'meta_id' => __('ID', 'wp-optimize'),
'meta_key' => __('Name', 'wp-optimize'),
'meta_value' => __('Value', 'wp-optimize'),
);
}
return array(
'id_key' => ('single' == $type) ? 'option_id' : 'meta_id',
'columns' => $columns,
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('option_id', 'meta_id')),
'message' => $total > 0 ? '' : __('No transient options found', 'wp-optimize'),
);
}
/**
* Do actions before optimize() function.
*/
public function before_optimize() {
$this->processed_count = 0;
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s transient option deleted', '%s transient options deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
// Delete transients from multisite, if configured as such.
if (is_multisite() && is_main_network()) {
if (isset($this->data['ids'])) {
// clean timeouts rows by transient option ids, before deleting transients.
// this is done for correct counting deleted transient options.
$clean2_timeouts = "
DELETE
b
FROM
" . $this->wpdb->sitemeta . " a
LEFT JOIN " . $this->wpdb->sitemeta . " b
ON
b.meta_key = CONCAT(
'_site_transient_timeout_',
SUBSTRING(
a.meta_key,
CHAR_LENGTH('_site_transient_') + 1
)
)
WHERE
a.meta_id IN (".join(',', $this->data['ids']).")";
// run clean timeouts query.
$this->query($clean2_timeouts);
// reset clean timeouts query to avoid future run.
$clean2_timeouts = '';
// clean transients rows by id.
$clean2 = "
DELETE
a
FROM
" . $this->wpdb->sitemeta . " a
WHERE
a.meta_id IN (".join(',', $this->data['ids']).")
". ($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "");
} else {
$clean2 = "
DELETE
a
FROM
".$this->wpdb->sitemeta." a, ".$this->wpdb->sitemeta." b
WHERE
a.meta_key LIKE '_site_transient_%' AND
a.meta_key NOT LIKE '_site_transient_timeout_%' AND
b.meta_key = CONCAT(
'_site_transient_timeout_',
SUBSTRING(
a.meta_key,
CHAR_LENGTH('_site_transient_') + 1
)
)
".($this->remove_only_expired() ? " AND b.meta_value < UNIX_TIMESTAMP()" : "");
$clean2_timeouts = "
DELETE
b
FROM
" . $this->wpdb->options . " b
WHERE
b.option_name LIKE '_site_transient_timeout_%'
".($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "");
}
$sitemeta_table_transients_deleted = $this->query($clean2);
if ('' != $clean2_timeouts) $this->query($clean2_timeouts);
$message2 = sprintf(_n('%s network-wide transient option deleted', '%s network-wide transient options deleted', $sitemeta_table_transients_deleted, 'wp-optimize'), number_format_i18n($sitemeta_table_transients_deleted));
$this->logger->info($message2);
$this->register_output($message2);
}
}
/**
* Optimize transients options
*/
public function optimize() {
// if posted ids then build sql queries for deleting selected data.
if (isset($this->data['ids'])) {
// clean timeouts rows by transient option ids, before deleting transients.
// this is done for correct counting deleted transient options.
$clean_timeouts = "
DELETE
b
FROM
" . $this->wpdb->options . " a
LEFT JOIN " . $this->wpdb->options . " b
ON
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_transient_') + 1
)
)
WHERE
a.option_id IN (".join(',', $this->data['ids']).")";
// run clean timeouts query.
$this->query($clean_timeouts);
// reset clean timeouts query to avoid future run.
$clean_timeouts = '';
// clean transients rows by id.
$clean = "
DELETE
a
FROM
" . $this->wpdb->options . " a
WHERE
a.option_id IN (".join(',', $this->data['ids']).")
". ($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "");
} else {
// clean transients rows.
$clean = "
DELETE
a
FROM
" . $this->wpdb->options . " a
LEFT JOIN " . $this->wpdb->options . " b
ON
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_transient_') + 1
)
)
WHERE
a.option_name LIKE '_transient_%' AND
a.option_name NOT LIKE '_transient_timeout_%'
". ($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "");
// clean transient timeouts rows.
$clean_timeouts = "
DELETE
b
FROM
" . $this->wpdb->options . " b
WHERE
b.option_name LIKE '_transient_timeout_%'
".($this->remove_only_expired() ? " AND b.option_value < UNIX_TIMESTAMP()" : "");
}
// run clean transients query and get count of deleted rows.
$options_table_transients_deleted = $this->query($clean);
$this->processed_count += $options_table_transients_deleted;
if ('' != $clean_timeouts) $this->query($clean_timeouts);
}
/**
* Do actions before get_info() function.
*/
public function before_get_info() {
$this->found_count = 0;
$this->found_count_all = 0;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if (is_multisite() && is_main_network()) {
$sitemeta_table_sql = "
SELECT
COUNT(*)
FROM
".$this->wpdb->sitemeta." a
LEFT JOIN
".$this->wpdb->sitemeta." b
ON
b.meta_key = CONCAT(
'_site_transient_timeout_',
SUBSTRING(
a.meta_key,
CHAR_LENGTH('_site_transient_') + 1
)
)
WHERE
a.meta_key LIKE '_site_transient_%' AND
a.meta_key NOT LIKE '_site_transient_timeout_%'";
$expired_suffix_sql = " AND b.meta_value < UNIX_TIMESTAMP()";
// get count of expired transients.
$sitemeta_table_transients = $this->wpdb->get_var($sitemeta_table_sql . $expired_suffix_sql);
// get count of all transients.
$sitemeta_table_transients_all = $this->wpdb->get_var($sitemeta_table_sql);
} else {
$sitemeta_table_transients = 0;
$sitemeta_table_transients_all = 0;
}
if ($this->found_count_all > 0) {
$message = sprintf(_n('%1$d of %2$d transient option expired', '%1$d of %2$d transient options expired', $this->found_count_all, 'wp-optimize'), number_format_i18n($this->found_count), number_format_i18n($this->found_count_all));
} else {
$message = __('No transient options found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %d site', 'across %d sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link to $message.
if ($this->found_count_all > 0) {
$message = $this->get_preview_link($message, array('data-type' => 'single'));
}
$this->register_output($message);
if ($this->is_multisite_mode()) {
if ($sitemeta_table_transients_all > 0) {
$message2 = sprintf(_n('%1$d of %2$d network-wide transient option found', '%1$d of %2$d network-wide transient options found', $sitemeta_table_transients_all, 'wp-optimize'), number_format_i18n($sitemeta_table_transients), number_format_i18n($sitemeta_table_transients_all));
$message2 = $this->get_preview_link($message2, array('data-type' => 'multisite'));
} else {
$message2 = __('No site-wide transient options found', 'wp-optimize');
}
$this->register_output($message2);
}
// If any kind of transients exists then
if ($this->found_count_all > 0 || ($sitemeta_table_transients + $sitemeta_table_transients_all > 0)) {
$remove_all_transients = $this->options->get_option('remove_all_transients', 'false');
$this->register_output('<input id="remove_all_transients" name="remove_all_transients" type="checkbox" value="true" '.checked($remove_all_transients, 'true').'><label for="remove_all_transients" style="color: inherit;">'.__('Remove all transient options (not only expired)', 'wp-optimize').'</label>');
}
}
/**
* Returns info about possibility to optimize transient options.
*/
public function get_info() {
$blogs = $this->get_optimization_blogs();
foreach ($blogs as $blog_id) {
$this->switch_to_blog($blog_id);
$options_table_sql = "
SELECT
COUNT(*)
FROM
" . $this->wpdb->options . " a
LEFT JOIN
" . $this->wpdb->options . " b
ON
b.option_name = CONCAT(
'_transient_timeout_',
SUBSTRING(
a.option_name,
CHAR_LENGTH('_transient_') + 1
)
)
WHERE
a.option_name LIKE '_transient_%' AND
a.option_name NOT LIKE '_transient_timeout_%'
";
$expired_suffix_sql = " AND b.option_value < UNIX_TIMESTAMP()";
// get count of expired transients.
$options_table_transients = $this->wpdb->get_var($options_table_sql . $expired_suffix_sql);
$this->found_count += $options_table_transients;
// get count of all transients.
$options_table_transients = $this->wpdb->get_var($options_table_sql);
$this->found_count_all += $options_table_transients;
$this->restore_current_blog();
}
}
public function settings_label() {
return __('Remove expired transient options', 'wp-optimize');
}
public function get_auto_option_description() {
return __('Remove expired transient options', 'wp-optimize');
}
/**
* Check optimization param and return true if we should remove only expired transients.
*
* @return bool
*/
private function remove_only_expired() {
if (isset($this->data['remove_all_transients']) && 'true' == $this->data['remove_all_transients']) {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,222 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
/**
* Class WP_Optimization_trash
*/
class WP_Optimization_trash extends WP_Optimization {
public $available_for_auto = true;
public $auto_default = true;
public $setting_default = true;
public $available_for_saving = true;
public $ui_sort_order = 3010;
protected $setting_id = 'trash';
protected $auto_id = 'trash';
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
$retention_subquery = '';
if ('true' == $this->retention_enabled) {
$retention_subquery = ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// get data requested for preview.
$sql = $this->wpdb->prepare(
"SELECT `ID`, `post_title`, `post_date`".
" FROM `" . $this->wpdb->posts . "`".
" WHERE post_status = 'trash'".
$retention_subquery.
" ORDER BY `ID` LIMIT %d, %d;",
array(
$params['offset'],
$params['limit'],
)
);
$posts = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($posts)) {
foreach ($posts as $key => $post) {
$args = array(
'post_status' => 'trash',
'post_type' => 'post',
);
$posts[$key]['post_title'] = array(
'text' => '' == $post['post_title'] ? '('.__('no title', 'wp-optimize').')' : $post['post_title'],
'url' => add_query_arg($args, 'edit.php'),
);
}
}
// get total count auto-draft for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` WHERE post_status = 'trash'";
if ('true' == $this->retention_enabled) {
$sql .= ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql .= ';';
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'ID',
'columns' => array(
'ID' => __('ID', 'wp-optimize'),
'post_title' => __('Title', 'wp-optimize'),
'post_date' => __('Date', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($posts, array('ID')),
'message' => $total > 0 ? '' : __('No trashed posts found', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s post removed from Trash', '%s posts removed from Trash', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
}
/**
* Do optimization.
*/
public function optimize() {
$remove_ids_sql = "SELECT ID FROM `" . $this->wpdb->posts . "` WHERE post_status = 'trash'";
if ('true' == $this->retention_enabled) {
$remove_ids_sql .= ' AND post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// get trashed post ids.
$post_remove_ids = $this->wpdb->get_col($remove_ids_sql);
// if optimize called from preview dialog then get posted ids.
if (isset($this->data['ids'])) {
$post_remove_ids = array_intersect($post_remove_ids, $this->data['ids']);
}
// remove related data for trashed posts.
if (!empty($post_remove_ids)) {
$post_remove_ids = join(',', $post_remove_ids);
// remove related postmeta.
$clean = "DELETE FROM `" . $this->wpdb->postmeta . "` WHERE post_id IN (" . $post_remove_ids . ");";
$this->wpdb->query($clean);
// remove related term relationships.
$clean = "DELETE FROM `" . $this->wpdb->term_relationships . "` WHERE object_id IN (" . $post_remove_ids . ");";
$this->wpdb->query($clean);
// remove related comments and commentmeta.
$clean = "DELETE c, cm FROM `" . $this->wpdb->comments . "` c LEFT JOIN `" . $this->wpdb->commentmeta . "` cm ON c.comment_ID = cm.comment_id WHERE c.comment_post_ID IN (" . $post_remove_ids . ");";
$this->wpdb->query($clean);
}
$clean = "DELETE FROM `" . $this->wpdb->posts . "` WHERE post_status = 'trash'";
if ('true' == $this->retention_enabled) {
$clean .= ' AND post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND `ID` in ('.join(',', $this->data['ids']).')';
}
$clean .= ';';
// remove trashed posts.
$posttrash = $this->query($clean);
$this->processed_count += $posttrash;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count > 0) {
$message = sprintf(_n('%s trashed post in your database', '%s trashed posts in your database', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No trashed posts found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link for output.
if (0 != $this->found_count && null != $this->found_count) {
$message = $this->get_preview_link($message);
}
$this->register_output($message);
}
/**
* Return info about not optimized records
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->posts . "` WHERE post_status = 'trash'";
if ('true' == $this->retention_enabled) {
$sql .= ' and post_modified < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql .= ';';
$trash = $this->wpdb->get_var($sql);
$this->found_count += $trash;
}
/**
* Return settings label
*
* @return string|void
*/
public function settings_label() {
if ('true' == $this->retention_enabled) {
return sprintf(__('Clean trashed posts which are older than %d weeks', 'wp-optimize'), $this->retention_period);
} else {
return __('Clean all trashed posts', 'wp-optimize');
}
}
/**
* Return description
*
* @return string|void
*/
public function get_auto_option_description() {
return __('Remove trashed posts', 'wp-optimize');
}
}

View File

@@ -0,0 +1,185 @@
<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
class WP_Optimization_unapproved extends WP_Optimization {
public $available_for_auto = true;
public $auto_default = false;
public $setting_default = true;
public $available_for_saving = true;
public $ui_sort_order = 4000;
/**
* Prepare data for preview widget.
*
* @param array $params
*
* @return array
*/
public function preview($params) {
$retention_subquery = '';
if ('true' == $this->retention_enabled) {
$retention_subquery = ' and comment_date < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// get data requested for preview.
$sql = $this->wpdb->prepare("
SELECT
c.comment_ID,
c.comment_author,
c.comment_content,
p.post_title,
p.ID,
c.comment_date".
" FROM " . $this->wpdb->comments . " c" .
" INNER JOIN " . $this->wpdb->posts . " p" .
" ON c.comment_post_ID = p.ID" .
" WHERE c.comment_approved = '0'".
$retention_subquery.
" ORDER BY `comment_ID` LIMIT %d, %d",
array(
$params['offset'],
$params['limit'],
)
);
$comments = $this->wpdb->get_results($sql, ARRAY_A);
// fix empty revision titles.
if (!empty($comments)) {
foreach ($comments as $key => $comment) {
$comments[$key]['post_title'] = array(
'text' => '' == $comment['post_title'] ? '('.__('no title', 'wp-optimize').')' : $comment['post_title'],
'url' => get_edit_post_link($comment['ID'], ''),
);
$args = array(
'action' => 'editcomment',
'c' => $comment['comment_ID'],
);
$comments[$key]['comment_content'] = array(
'text' => $comment['comment_content'],
'url' => add_query_arg($args, 'comment.php'),
);
}
}
// get total count comments for optimization.
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_approved = '0' ".$retention_subquery.";";
$total = $this->wpdb->get_var($sql);
return array(
'id_key' => 'comment_ID',
'columns' => array(
'comment_ID' => __('ID', 'wp-optimize'),
'comment_author' => __('Author', 'wp-optimize'),
'comment_content' => __('Comment', 'wp-optimize'),
'post_title' => __('Post', 'wp-optimize'),
'comment_date' => __('Date', 'wp-optimize'),
),
'offset' => $params['offset'],
'limit' => $params['limit'],
'total' => $total,
'data' => $this->htmlentities_array($comments, array('comment_ID')),
'message' => $total > 0 ? '' : __('No unapproved comments found', 'wp-optimize'),
);
}
/**
* Do actions after optimize() function.
*/
public function after_optimize() {
$message = sprintf(_n('%s unapproved comment deleted', '%s unapproved comments deleted', $this->processed_count, 'wp-optimize'), number_format_i18n($this->processed_count));
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
$this->logger->info($message);
$this->register_output($message);
$awaiting_mod = wp_count_comments();
$awaiting_mod = $awaiting_mod->moderated;
$this->register_meta('awaiting_mod', $awaiting_mod);
}
/**
* Unapproved-comments / unapproved
* need to check what IDs were previously used before (dom ID, settings ID),
* as there was a note about unapproved-comments in the source, which isn't in use now here.
*/
public function optimize() {
$clean = "DELETE c, cm FROM `" . $this->wpdb->comments . "` c LEFT JOIN `" . $this->wpdb->commentmeta . "` cm ON c.comment_ID = cm.comment_id WHERE comment_approved = '0' ";
if ('true' == $this->retention_enabled) {
$clean .= ' and c.comment_date < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
// if posted ids in params, then remove only selected items. used by preview widget.
if (isset($this->data['ids'])) {
$clean .= ' AND c.comment_ID in ('.join(',', $this->data['ids']).')';
}
$clean .= ';';
$comments = $this->query($clean);
$this->processed_count += $comments;
}
/**
* Do actions after get_info() function.
*/
public function after_get_info() {
if ($this->found_count) {
$message = sprintf(_n('%s unapproved comment found', '%s unapproved comments found', $this->found_count, 'wp-optimize'), number_format_i18n($this->found_count));
} else {
$message = __('No unapproved comments found', 'wp-optimize');
}
if ($this->is_multisite_mode()) {
$message .= ' ' . sprintf(_n('across %s site', 'across %s sites', count($this->blogs_ids), 'wp-optimize'), count($this->blogs_ids));
}
// add preview link for output.
if (0 != $this->found_count && null != $this->found_count) {
$message = $this->get_preview_link($message);
}
$this->register_output($message);
}
/**
* Get count of unoptimized items.
*/
public function get_info() {
$sql = "SELECT COUNT(*) FROM `" . $this->wpdb->comments . "` WHERE comment_approved = '0'";
if ('true' == $this->retention_enabled) {
$sql .= ' and comment_date < NOW() - INTERVAL ' . $this->retention_period . ' WEEK';
}
$sql .= ';';
$comments = $this->wpdb->get_var($sql);
$this->found_count += $comments;
}
public function settings_label() {
if ('true' == $this->retention_enabled) {
return sprintf(__('Remove unapproved comments which are older than %d weeks', 'wp-optimize'), $this->retention_period);
} else {
return __('Remove unapproved comments', 'wp-optimize');
}
}
public function get_auto_option_description() {
return __('Remove unapproved comments', 'wp-optimize');
}
}