Commit 800f4bfd authored by Rolf Forst's avatar Rolf Forst
Browse files

Refactoring

parent bb669cb6
<?php
namespace RRZE\PostExpiration;
defined('ABSPATH') || exit;
class Expiration
{
protected $option_name;
protected $options;
protected $cron_hook;
protected $expiration_post_status = 'expired';
protected $expiration_date_key = 'expiration_date';
protected $expiration_date_gmt_key = 'expiration_date_gmt';
public function __construct()
{
$opt = new Options();
$this->option_name = $opt->get_option_name();
$this->options = $opt->get_options();
if (empty($this->options->post_types)) {
return;
}
foreach ($this->options->post_types as $post_type) {
add_filter('manage_' . $post_type . '_posts_columns', array($this, 'expiration_date_column'));
add_action('manage_' . $post_type . '_posts_custom_column', array($this, 'expiration_date_custom_column'), 10, 2);
add_filter('manage_edit-' . $post_type . '_sortable_columns', array($this, 'expiration_date_sortable_column'));
}
add_action('init', [$this, 'register_post_status']);
add_action('admin_footer-post.php', [$this, 'append_post_status_postbox']);
add_action('admin_footer-edit.php', [$this, 'append_post_status_quick_edit']);
add_action('pre_get_posts', array($this, 'expiration_date_orderby'));
add_action('post_submitbox_misc_actions', array($this, 'exp_meta_box'));
add_action('save_post', array($this, 'update_post_expiration_date'));
add_filter('cron_schedules', array($this, 'add_cron_schedule'));
$this->cron_hook = sprintf('%s_%s', $this->option_name, get_current_blog_id());
add_action($this->cron_hook, array($this, 'set_expired_posts'));
}
public function expiration_date_column($columns)
{
$columns['expiration_date'] = __('Expiration', 'rrze-post-expiration');
return $columns;
}
public function expiration_date_custom_column($column, $post_id)
{
if ($column != 'expiration_date') {
return;
}
$post = get_post($post_id);
$expiration_date = get_post_meta($post->ID, $this->expiration_date_key, true);
$expiration_date_gmt = get_post_meta($post->ID, $this->expiration_date_gmt_key, true);
if ($post->post_date == '0000-00-00 00:00:00' || !$expiration_date) {
echo '&#8212;';
} else {
$t_time = date(__('Y/m/d g:i:s A'), mysql2date('U', $expiration_date));
$m_time = $expiration_date;
$time = mysql2date('G', $expiration_date_gmt);
$time_diff = $time - time();
if ($time_diff > 0 && $time_diff < 24 * 60 * 60) {
$h_time = sprintf(__('in %s'), human_time_diff($time));
} elseif ($time_diff < 0 && abs($time_diff) < 24 * 60 * 60) {
$h_time = sprintf(__('%s ago'), human_time_diff($time));
} else {
$h_time = mysql2date(__('Y/m/d'), $m_time);
}
echo '<abbr title="' . $t_time . '">' . $h_time . '</abbr>';
if ($time_diff < 0) {
echo '<br/>', __('expired', 'rrze-post-expiration');
}
}
}
public function expiration_date_sortable_column($columns)
{
$columns['expiration_date'] = 'expiration_date';
return $columns;
}
public function expiration_date_orderby($query)
{
if (!is_admin()) {
return;
}
$orderby = $query->get('orderby');
if ('expiration_date' == $orderby) {
$query->set('orderby', 'meta_value');
$query->set(
'meta_query',
array(
'relation' => 'OR',
array(
'key' => $this->expiration_date_key,
'compare' => 'NOT EXISTS'
),
array(
'key' => $this->expiration_date_key,
'compare' => 'EXISTS'
),
)
);
}
}
public function register_post_status()
{
register_post_status($this->expiration_post_status, [
'label' => _x('Expired', 'post', 'rrze-post-expiration'),
'public' => false,
'private' => false,
'exclude_from_search' => true,
'show_in_admin_all_list' => false,
'show_in_admin_status_list' => true,
'label_count' => _n_noop('Expired <span class="count">(%s)</span>', 'Expired <span class="count">(%s)</span>', 'rrze-post-expiration')
]);
}
public function append_post_status_postbox()
{
$post = get_post();
if (! in_array($post->post_type, $this->options->post_types)) {
return;
}
$selected = '';
$post_status_display = '';
$title = __('Expired', 'rrze-post-expiration');
if ($post->post_status == $this->expiration_post_status) {
$post_status_display = '$(".misc-pub-post-status span#post-status-display").text("' . $title . '");';
$selected = ' selected=\"selected\"';
}
$script = '
<script>
jQuery(document).ready(function($){
$("select#post_status").append("<option value=\"expired\"' . $selected . '>' . $title. '</option>");
' . $post_status_display . '
});
</script>
';
echo str_replace(PHP_EOL, '', trim(preg_replace('/\s+/', ' ', $script)));
}
public function append_post_status_quick_edit()
{
if (! in_array(get_post_type(), $this->options->post_types)) {
return;
}
$title = __('Expired', 'rrze-post-expiration');
$script = "<script>
jQuery(document).ready(function($) {
$('select[name=\"_status\"]').append('<option value=\"expired\">" . $title . "</option>');
});
</script>";
echo str_replace(PHP_EOL, '', trim(preg_replace('/\s+/', ' ', $script)));
}
public function exp_meta_box()
{
global $post, $post_type, $post_type_object;
if (!in_array($post_type, $this->options->post_types)) {
return;
}
$can_publish = current_user_can($post_type_object->cap->publish_posts);
if ($can_publish) :
$cur_time = strtotime(current_time('mysql'));
$datef = __('M j, Y @ H:i');
$date = date_i18n($datef, $cur_time);
$stamp = __('Expiration <b>disabled</b>', 'rrze-post-expiration');
if (0 != $post->ID) {
$expiration_date = get_post_meta($post->ID, $this->expiration_date_key, true);
if ($expiration_date) {
$exp_time = strtotime($expiration_date);
if ($exp_time > $cur_time) {
$stamp = __('Expires on: <b>%s</b>', 'rrze-post-expiration');
} else {
$stamp = __('Expired on: <b>%s</b>', 'rrze-post-expiration');
}
$enabled = ' checked="checked"';
$date = date_i18n($datef, strtotime($expiration_date));
}
} ?>
<div class="misc-pub-section curtime misc-pub-curtime">
<span id="timestamp" class="exp_timestamp">
<?php printf($stamp, $date); ?></span>
<a href="#edit_exp_timestamp" class="edit-exp-timestamp hide-if-no-js" tabindex="4"><?php _e('Edit') ?></a>
<div id="exp_timestampdiv" class="hide-if-js">
<?php $this->select_expiration_time(); ?>
</div>
</div>
<?php
endif;
}
private static function select_expiration_time()
{
global $wp_locale, $post;
$expiration_date = get_post_meta($post->ID, 'expiration_date', true);
$expiration_date_gmt = get_post_meta($post->ID, 'expiration_date_gmt', true);
$enabled = '';
if ($expiration_date) {
$enabled = ' checked="checked"';
}
$edit = !(!$expiration_date);
$time_adj = current_time('timestamp');
$jj = ($edit) ? mysql2date('d', $expiration_date, false) : gmdate('d', $time_adj);
$mm = ($edit) ? mysql2date('m', $expiration_date, false) : gmdate('m', $time_adj);
$aa = ($edit) ? mysql2date('Y', $expiration_date, false) : gmdate('Y', $time_adj);
$hh = ($edit) ? mysql2date('H', $expiration_date, false) : gmdate('H', $time_adj);
$mn = ($edit) ? mysql2date('i', $expiration_date, false) : gmdate('i', $time_adj);
$ss = ($edit) ? mysql2date('s', $expiration_date, false) : gmdate('s', $time_adj);
$cur_jj = gmdate('d', $time_adj);
$cur_mm = gmdate('m', $time_adj);
$cur_aa = gmdate('Y', $time_adj);
$cur_hh = gmdate('H', $time_adj);
$cur_mn = gmdate('i', $time_adj);
$month = "<select id=\"exp_mm\" name=\"exp_mm\" tabindex=\"4\" style=\"height:20px; line-height:14px; padding:0; vertical-align:top;\">\n";
for ($i = 1; $i < 13; $i = $i +1) {
$monthnum = zeroise($i, 2);
$monthtext = $wp_locale->get_month_abbrev($wp_locale->get_month($i));
$month .= "\t\t\t" . '<option value="' . $monthnum . '" data-text="' . $monthtext . '" ' . selected($monthnum, $mm, false) . '>';
/* translators: 1: month number (01, 02, etc.), 2: month abbreviation */
$month .= sprintf(__('%1$s-%2$s'), $monthnum, $monthtext) . "</option>\n";
}
$month .= '</select>';
$day = '<input type="text" id="exp_jj" name="exp_jj" value="' . $jj . '" size="2" maxlength="2" tabindex="4" autocomplete="off" style="font-size:12px; padding:1px; width:2em;" />';
$year = '<input type="text" id="exp_aa" name="exp_aa" value="' . $aa . '" size="4" maxlength="4" tabindex="4" autocomplete="off" style="font-size:12px; padding:1px; width:3.4em;" />';
$hour = '<input type="text" id="exp_hh" name="exp_hh" value="' . $hh . '" size="2" maxlength="2" tabindex="4" autocomplete="off" style="font-size:12px; padding:1px; width:2em;" />';
$minute = '<input type="text" id="exp_mn" name="exp_mn" value="' . $mn . '" size="2" maxlength="2" tabindex="4" autocomplete="off" style="font-size:12px; padding:1px; width:2em;" />';
echo '<div class="exp-timestamp-wrap">';
echo '<p style="margin:0.5em 0;"><input type="checkbox" name="enable_expiration" id="enable_expiration" value="checked"' . $enabled . ' />';
echo '<label class="selectit" for="enable_expiration">' . __('Enable expiration', 'rrze-post-expiration') . '</label></p>';
/* translators: 1: month, 2: day, 3: year, 4: hour, 5: minute */
printf(__('%1$s %2$s, %3$s @ %4$s:%5$s'), $month, $day, $year, $hour, $minute);
echo '</div><input type="hidden" id="exp_ss" name="exp_ss" value="' . $ss . '" />';
echo "\n\n";
if ($enabled) {
echo '<input type="hidden" id="exp_enabled" name="exp_enabled" value="1" />';
} else {
echo '<input type="hidden" id="exp_enabled" name="exp_enabled" value="0" />';
}
echo "\n\n";
foreach (array('mm', 'jj', 'aa', 'hh', 'mn') as $timeunit) {
echo '<input type="hidden" id="exp_hidden_' . $timeunit . '" name="hidden_' . $timeunit . '" value="' . $$timeunit . '" />' . "\n";
$cur_timeunit = 'cur_' . $timeunit;
echo '<input type="hidden" id="exp_' . $cur_timeunit . '" name="exp_' . $cur_timeunit . '" value="' . $$cur_timeunit . '" />' . "\n";
} ?>
<p>
<a href="#edit_exp_timestamp" class="save-exp-timestamp hide-if-no-js button"><?php _e('OK'); ?></a>
<a href="#edit_exp_timestamp" class="cancel-exp-timestamp hide-if-no-js"><?php _e('Cancel'); ?></a>
</p>
<?php
}
public function update_post_expiration_date()
{
global $current_blog, $post;
if (!$post || !in_array($post->post_type, $this->options->post_types)) {
return;
}
delete_post_meta($post->ID, $this->expiration_date_key);
delete_post_meta($post->ID, $this->expiration_date_gmt_key);
if (isset($_POST['enable_expiration'])) {
$aa = $_POST['exp_aa'];
$mm = $_POST['exp_mm'];
$jj = $_POST['exp_jj'];
$hh = $_POST['exp_hh'];
$mn = $_POST['exp_mn'];
$ss = $_POST['exp_ss'];
$aa = ($aa <= 0) ? date('Y') : $aa;
$mm = ($mm <= 0) ? date('n') : $mm;
$jj = ($jj > 31) ? 31 : $jj;
$jj = ($jj <= 0) ? date('j') : $jj;
$hh = ($hh > 23) ? $hh - 24 : $hh;
$mn = ($mn > 59) ? $mn - 60 : $mn;
$ss = ($ss > 59) ? $ss - 60 : $ss;
$ts = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $aa, $mm, $jj, $hh, $mn, $ss);
update_post_meta($post->ID, $this->expiration_date_key, $ts, true);
$ts_gmt = get_gmt_from_date($ts);
update_post_meta($post->ID, $this->expiration_date_gmt_key, $ts_gmt, true);
wp_clear_scheduled_hook($this->cron_hook);
wp_schedule_event(time(), 'two-minutes', $this->cron_hook);
}
}
public function add_cron_schedule($schedules)
{
$schedules['two-minutes'] = array(
'interval' => 120,
'display' => __('Every Two Minutes')
);
return $schedules;
}
public function set_expired_posts()
{
global $wpdb;
$current_date = current_time('mysql');
$pt_sql = [];
foreach ($this->options->post_types as $post_type) {
$pt_sql[] = $wpdb->prepare('posts.post_type = %s', $post_type);
}
$pt_sql = implode(' OR ', $pt_sql);
$result = $wpdb->get_results(
$wpdb->prepare(
"SELECT post_id FROM {$wpdb->postmeta} as postmeta
LEFT JOIN {$wpdb->posts} as posts ON postmeta.post_id = posts.ID
WHERE posts.post_status = 'publish' AND ({$pt_sql})
AND postmeta.meta_key = %s
AND postmeta.meta_value <= %s",
$this->expiration_date_key,
$current_date
)
);
if (!empty($result)) {
$plugins = new Plugins();
foreach ($result as $row) {
wp_update_post(['ID' => $row->post_id, 'post_status' => $this->expiration_post_status]);
// rrze cache plugin support
$plugins->flush_rrze_cache(get_permalink($row->post_id));
}
}
}
}
<?php
namespace RRZE\PostExpiration;
defined('ABSPATH') || exit;
spl_autoload_register(function ($class) {
$prefix = 'RRZE\PostExpiration\\';
$base_dir = __DIR__ . '/RRZE/PostExpiration/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
...@@ -4,22 +4,17 @@ namespace RRZE\PostExpiration; ...@@ -4,22 +4,17 @@ namespace RRZE\PostExpiration;
defined('ABSPATH') || exit; defined('ABSPATH') || exit;
class Plugins class Functions
{ {
/** /**
* Flush the RRZE Cache * Flush the Cache for an Url.
* RRZE Cache plugin support. * RRZE Cache plugin support.
* @param string $url Post permalink * @param string $url Post permalink
* @return void
*/ */
public function flush_rrze_cache($url) public static function flush_cache_url(string $url)
{ {
if (empty($url)) { if (!empty($url) && has_action('rrzecache_flush_cache_url')) {
return;
}
if (has_action('rrzecache_flush_cache_url')) {
do_action('rrzecache_flush_cache_url', $url); do_action('rrzecache_flush_cache_url', $url);
} }
} }
......
...@@ -6,33 +6,45 @@ defined('ABSPATH') || exit; ...@@ -6,33 +6,45 @@ defined('ABSPATH') || exit;
class Main class Main
{ {
protected $plugin_basename; public function __construct()
{
//
}
public function __construct($plugin_basename) public function onLoaded()
{ {
$this->plugin_basename = $plugin_basename; $settings = new Settings;
$settings->onLoaded();
$expiration = new Expiration;
$expiration->onLoaded();
$update = new Update(); $update = new Update();
add_action('init', [$update, 'update_version']); add_action('init', [$update, 'update_version']);
add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts']); add_action('admin_enqueue_scripts', [$this, 'admin_enqueue_scripts']);
$settings = new Settings();
$expiration = new Expiration();
} }
public function admin_enqueue_scripts($hook) public function admin_enqueue_scripts($hook)
{ {
wp_register_style('rrze-post-expiration', plugins_url('css/post-expiration.min.css', $this->plugin_basename));
if ($hook == 'post.php') { if ($hook == 'post.php') {
wp_register_script('rrze-post-expiration', plugins_url('js/post-hook-suffix.min.js', $this->plugin_basename), ['jquery']); wp_enqueue_style(
'rrze-post-expiration',
plugins_url('assets/css/post-expiration.min.css', plugin()->getBasename()),
[],
plugin()->getVersion()
);
wp_enqueue_script(
'rrze-post-expiration',
plugins_url('assets/js/post-hook-suffix.min.js', plugin()->getBasename()),
['jquery'],
plugin()->getVersion()
);
wp_localize_script('rrze-post-expiration', 'expiration', [ wp_localize_script('rrze-post-expiration', 'expiration', [
'expiresOn' => __('Expires on', 'rrze-post-expiration'), 'expiresOn' => __('Expires on', 'rrze-post-expiration'),
'expiredOn' => __('Expired on:', 'rrze-post-expiration'), 'expiredOn' => __('Expired on:', 'rrze-post-expiration'),
'expirationDate' => __('Expiration <b>disabled</b>', 'rrze-post-expiration') 'expirationDate' => __('Expiration <b>disabled</b>', 'rrze-post-expiration')
]); ]);
wp_enqueue_script('rrze-post-expiration');
} }
} }
} }
...@@ -6,9 +6,17 @@ defined('ABSPATH') || exit; ...@@ -6,9 +6,17 @@ defined('ABSPATH') || exit;
class Options class Options
{ {
protected $option_name = 'rrze_post_expiration'; /**
* Option name
protected function default_options() * @var string
*/
protected static $optionName = 'rrze_post_expiration';
/**
* Default options
* @return array
*/
protected static function defaultOptions(): array
{ {
$options = [ $options = [
'post_types' => ['post'] 'post_types' => ['post']
...@@ -17,19 +25,28 @@ class Options ...@@ -17,19 +25,28 @@ class Options
return $options; return $options;
} }
public function get_options() /**
* Returns the options.
* @return object
*/
public static function getOptions(): object
{ {
$defaults = $this->default_options(); $defaults = self::defaultOptions();
$options = (array) get_option($this->option_name); $options = (array) get_option(self::$optionName);
$options = wp_parse_args($options, $defaults); $options = wp_parse_args($options, $defaults);
$options = array_intersect_key($options, $defaults); $options = array_intersect_key($options, $defaults);
return (object) $options; return (object) $options;
} }
public function get_option_name() /**
* Returns the name of the option.
* @return string
*/
public static function getOptionName(): string
{ {
return $this->option_name; return self::$optionName;
} }
} }
<?php
namespace RRZE\PostExpiration;
defined('ABSPATH') || exit;
class Plugin
{
/**
* The full path and filename of the plugin.
* @var string
*/
protected $pluginFile;
/**
* The basename of the plugin.
* @var string
*/
protected $basename;
/**
* The filesystem directory path (with trailing slash) for the plugin.
* @var string
*/
protected