Plugin Directory

Changeset 714127


Ignore:
Timestamp:
05/17/2013 12:00:24 AM (13 years ago)
Author:
WebsiteBakery
Message:

1.2.0 bug fixes, support for TEC 3.0

Location:
the-events-calendar-housekeeper
Files:
8 added
3 edited

Legend:

Unmodified
Added
Removed
  • the-events-calendar-housekeeper/trunk/config/settingstab.php

    r621079 r714127  
    1313        'info-box-description' => array(
    1414            'type' => 'html',
    15             'html' => '<p>'.__('Keep your calendar clean and efficient by scheduling regular garbage collection of expired events.', 'events-housekeeper').' '.ECHousekeeper::instance()->expiredItemsAlert().' '.__('Garbage collection takes place once a day &ndash; so changes may not be instant.', 'events-housekeeper').'</p>'
     15            'html' => '<p>'.__('Keep your calendar clean and efficient by scheduling regular garbage collection of expired events. ', 'events-housekeeper')
     16                .ECHousekeeper::instance()->expiredItemsAlert().' '
     17                .__('Garbage collection takes place once a day when enabled and, by default, a maximum of 100 events will be collected in a single sweep. ', 'events-housekeeper').'</p>'
     18                .'<ul><li>'.__('Events are considered to be expired after they have started, <em>not when once they have ended,</em> so you should set the expiry criteria accordingly.', 'events-housekeeper').'</li>'
     19                .'<li>'.__('The collection will not take place immediately after saving/updating &ndash; there is normally a short delay first of all.', 'events-housekeeper').'</li></ul>'
    1620        ),
    1721        'info-end' => array(
  • the-events-calendar-housekeeper/trunk/housekeeper.php

    r621079 r714127  
    22/*
    33Plugin Name: The Events Calendar Housekeeper
    4 Description: Adds tools to keep your events under control.
    5 Version: 1.0.3
     4Description: Adds tools to keep your events under control. This version targets Events Calendar PRO 3.x.
     5Version: 1.2.0
    66Author: Barry Hughes
    77Author URI: http://freshlybakedwebsites.net
     
    5353
    5454    /**
    55      * The maximum number of events to tackle in a single clean up operation.
    56      * This can be adjusted directly (obtain the current object via the
    57      * instance() method) by using an appropriate action and priority, such
    58      * as init/1.
     55     * The maximum number of events to tackle in a single clean up operation. This can be adjusted directly (obtain the
     56     * current object via the instance() method) by using an appropriate action and priority (ie, early during init).
    5957     *
    6058     * @var int
     
    8482
    8583    /**
    86      * Creates a new instance of ECHousekeeper, which can then be accessed via
    87      * the instance() method.
     84     * Creates a new instance of ECHousekeeper, which can then be accessed via the instance() method.
    8885     *
    8986     * @static
     
    9895
    9996    /**
    100      * Initializes and sets up actions to conduct prerequisite checks, integrate
    101      * with The Events Calendar settings pages and run scheduled tasks.
     97     * Initializes and sets up actions to conduct prerequisite checks, integrate with The Events Calendar settings pages and run scheduled tasks.
    10298     *
    10399     * @return ECHousekeeper
     
    121117
    122118    /**
    123      * We require WP 3.4.2 and any requirements inherited by virtue of that,
    124      * plus The Events Calendar 2.0.9 or later.
     119     * We require WP 3.4.2 and any requirements inherited by virtue of that, plus The Events Calendar 2.0.9 or later.
    125120     *
    126121     * Sets the $preflightCheck property to true if we are all good here.
     
    130125        $missingRequirements = false;
    131126
    132         if (version_compare($wp_version, '3.4.2') < 0)
    133             $missingRequirements = true;
    134 
    135         if (class_exists('TribeEvents') === false)
    136             $missingRequirements = true;
    137 
    138         if (version_compare(TribeEvents::VERSION, '2.0.9') < 0)
    139             $missingRequirements = true;
    140 
    141         if ($missingRequirements === false)
    142             $this->preflightCheck = true;
    143     }
    144 
    145 
    146     /**
    147      * Checks that the prerequisites were met then hooks into The Events
    148      * Calendar to display and save settings.
     127        if (version_compare($wp_version, '3.4.2') < 0) $missingRequirements = true;
     128        if (class_exists('TribeEvents') === false) $missingRequirements = true;
     129        if (version_compare(TribeEvents::VERSION, '2.0.9') < 0) $missingRequirements = true;
     130        if ($missingRequirements === false) $this->preflightCheck = true;
     131    }
     132
     133
     134    /**
     135     * Checks that the prerequisites were met then hooks into The Events Calendar to display and save settings.
    149136     */
    150137    public function start() {
     
    166153
    167154    /**
    168      * Builds an alert message to indicate if expired events are sitting in the
    169      * database.
     155     * Builds an alert message to indicate if expired events are sitting in the database.
    170156     *
    171157     * @return string
    172158     */
    173159    public function expiredItemsAlert() {
    174         $count = $this->expiredItemsCount();
    175         $message = sprintf(__('There are currently %d expired events (this includes remnants of deleted events).',
    176             'events-housekeeper'), $count);
    177 
    178         if ($count > 0) $message = "<strong> $message </strong>";
     160        $criteriaCount = (int) $this->expiredItemsCount(true, true);
     161        $totalCount = (int) $this->expiredItemsCount(false, true);
     162
     163        $message = sprintf(_n('1 event currently meets the expiry criteria.',
     164            '%d events currently meet the expiry criteria.', $criteriaCount, 'events-housekeeper'), $criteriaCount);
     165
     166        $message = "<strong> $message </strong>";
    179167        return $message;
    180168    }
     
    182170
    183171    /**
    184      * Counts the number of expired events in the database.
    185      *
     172     * Counts the number of expired events in the database. Setting $meetingCriteria to true means only events falling
     173     * fowl of the current expiry criteria will be counted; setting $allInstances to true means individual recurring
     174     * instances will be counted - not just 'primary' events.
     175     *
     176     * @param bool $meetingCriteria
     177     * @param bool $allInstances
    186178     * @return int
    187179     */
    188     protected function expiredItemsCount() {
    189         global $wpdb;
     180    protected function expiredItemsCount($meetingCriteria, $allInstances) {
     181        global $wpdb;
     182        $cutoff = $meetingCriteria ? $this->criteriaCutOffDate() : date('Y-m-d');
     183        $include = $allInstances ? '' : 'DISTINCT';
    190184
    191185        $expiredEvents = $wpdb->get_var($wpdb->prepare("
    192             SELECT COUNT(DISTINCT post_id)
    193             FROM {$wpdb->prefix}postmeta
    194             WHERE meta_key = '_EventEndDate'
     186            SELECT COUNT($include post_id)
     187            FROM {$wpdb->postmeta}
     188            WHERE meta_key = '_EventStartDate'
    195189            AND meta_value < '%s';
    196         ", date('Y-m-d')));
     190        ", $cutoff));
    197191
    198192        return (int) $expiredEvents;
     
    205199    public function updateSettings() {
    206200        $settings = (array) get_option(self::SETTINGS);
    207         $settings = array_merge(array('enableGarbageCollection' => false), $settings);
    208 
    209         if ($settings['enableGarbageCollection'] === false) $this->clearCollection();
    210         else $this->enableCollection($settings['expiryCollection']);
    211     }
    212 
    213 
    214     /**
    215      * Remove our scheduled task.
    216      */
    217     protected function clearCollection() {
    218         wp_clear_scheduled_hook(self::SCHEDULE);
    219     }
    220 
    221 
    222     /**
    223      * (Re-)establish our scheduled task - it will normally run almost
    224      * immediately after this, except in the case of busy/slow systems.
    225      *
    226      * @param $frequency
    227      */
    228     protected function enableCollection($frequency) {
     201
     202        if (isset($settings['enableGarbageCollection']) and $settings['enableGarbageCollection'] === false)
     203            wp_clear_scheduled_hook(self::SCHEDULE);
     204        else $this->enableCollection();
     205    }
     206
     207
     208    /**
     209     * (Re-)establish our scheduled task - it will normally run almost immediately after this, except in the case of
     210     * busy/slow systems.
     211     */
     212    protected function enableCollection() {
    229213        // Clear then reschedule to ensure a collection happens quickly after a change of settings
    230214        if (wp_next_scheduled(self::SCHEDULE) !== false)
    231215            wp_clear_scheduled_hook(self::SCHEDULE);
    232216
    233         wp_schedule_event(time(), 'daily', self::SCHEDULE);
    234     }
    235 
    236 
    237     /**
    238      * Carry out the actual collection, interpret the criteria specified in the
    239      * settings tab and do the clean up.
     217        // Next cleanup 10secs from now then daily. The 10sec buffer prevents confusion - otherwise the Housekeeper
     218        // settings tab typically reloads part way through a clean-up and looks as if it has only done half a job
     219        wp_schedule_event(time() + 10, 'daily', self::SCHEDULE);
     220    }
     221
     222
     223    /**
     224     * Carry out the actual collection, interpret the criteria specified in the settings tab and do the clean up.
    240225     */
    241226    public function doCollection() {
     227        $this->expiryDate = $this->criteriaCutOffDate();
     228        $this->cleanUpAllBefore();
     229    }
     230
     231
     232    protected function criteriaCutOffDate() {
    242233        $settings = (array) get_option(self::SETTINGS);
    243234        $settings = array_merge(array('expiryCriteria' => 'allExpired'), $settings);
     
    251242        }
    252243
    253         $this->expiryDate = date('Y-m-d', $criteria);
    254         $this->cleanUpAllBefore();
    255     }
    256 
    257 
    258     /**
    259      * Cleans up expired events/event instances, with special handling for
    260      * recurring events.
    261      *
    262      * Note: recurring instance handling is likely to require significant
    263      * revision in time for The Events Calendar 3.0 release.
     244        return date('Y-m-d', $criteria);
     245    }
     246
     247
     248    /**
     249     * Cleans up expired events/event instances, with special handling for recurring events.
    264250     */
    265251    protected function cleanUpAllBefore() {
    266         foreach ($this->listExpiredPostIDs() as $id) {
    267             if ($this->isRecurringEvent($id)) {
    268                 $this->killRecurringInstances($id);
    269             }
    270             else {
    271                 $this->killPost($id);
    272                 $this->killPostMeta($id);
    273             }
    274         }
     252        foreach ($this->listExpiredPostIDs() as $id)
     253            if ($this->isRecurringEvent($id)) $this->killRecurringInstances($id);
     254            else wp_delete_post($id, true);
    275255    }
    276256
     
    279259     * Tries to determine if the event has recurring instances.
    280260     *
    281      * This can be seen in the database where there is A) an _EventRecurrence
    282      * meta entry and B) multiple _EventStartDate entries. For expediency, we
    283      * test only for A.
     261     * This can be seen in the database where there is A) an _EventRecurrence meta entry and B) multiple _EventStartDate
     262     * entries. For expediency, we test only for A.
    284263     *
    285264     * @param $id
     
    289268        global $wpdb;
    290269
    291         $recurrence = $wpdb->get_var("
     270        $recurrence = $wpdb->get_var($wpdb->prepare("
    292271            SELECT meta_value
    293             FROM {$wpdb->prefix}postmeta
     272            FROM {$wpdb->postmeta}
    294273            WHERE meta_key = '_EventRecurrence'
    295274            AND LENGTH(meta_value) > 0
     275            AND post_id = '%d'
    296276            LIMIT 1;
    297         ");
     277        ", $id));
    298278
    299279        if ($recurrence === null) return false;
     
    314294            SELECT DISTINCT post_id
    315295            FROM {$wpdb->prefix}postmeta
    316             WHERE meta_key = '_EventEndDate'
     296            WHERE meta_key = '_EventStartDate'
    317297            AND meta_value < '%s'
    318298            LIMIT %d;
     
    324304
    325305    /**
    326      * Deletes the specified post.
    327      *
    328      * @param $id
    329      */
    330     protected function killPost($id) {
    331         global $wpdb;
     306     * Intelligently removes recurring instances of an event, where those instances have expired. The initial
     307     * _EventEndDate is also adjusted to compensate for this.
     308     *
     309     * @param $id
     310     */
     311    protected function killRecurringInstances($id) {
     312        global $wpdb;
     313
     314        $eventInterval = $this->determineEventInterval($id);
    332315
    333316        $wpdb->query($wpdb->prepare("
    334             DELETE FROM {$wpdb->prefix}posts
    335             WHERE ID = '%d'
    336         ", $id));
    337     }
    338 
    339 
    340     /**
    341      * Deletes meta data associated with the specified post.
    342      *
    343      * @param $id
    344      */
    345     protected function killPostMeta($id) {
    346         global $wpdb;
    347 
    348         $wpdb->query($wpdb->prepare("
    349             DELETE FROM {$wpdb->prefix}postmeta
    350             WHERE post_id = '%d'
    351         ", $id));
    352     }
    353 
    354 
    355     /**
    356      * Intelligently removes recurring instances of an event, where those
    357      * instances have expired. The initial _EventEndDate is also adjusted to
    358      * compensate for this.
    359      *
    360      * @param $id
    361      */
    362     protected function killRecurringInstances($id) {
    363         global $wpdb;
    364 
    365         $eventInterval = $this->determineEventInterval($id);
    366 
    367         $wpdb->query($wpdb->prepare("
    368             DELETE FROM {$wpdb->prefix}postmeta
     317            DELETE FROM {$wpdb->postmeta}
    369318            WHERE post_id = '%d'
    370319            AND meta_key = '_EventStartDate'
     
    377326
    378327    /**
    379      * Calculates the length of time for the event (could be hours, all day or
    380      * days).
     328     * Calculates the length of time for the event (could be hours, all day or days).
    381329     *
    382330     * @param $id
     
    391339
    392340    /**
    393      * Adjusts the _EventEndDate so that it is the correct interval ahead of the
    394      * oldest surviving _EventStartDate.
     341     * Adjusts the _EventEndDate so that it is the correct interval ahead of the oldest surviving _EventStartDate.
    395342     *
    396343     * @param $id
     
    403350        $newEndTime = date('Y-m-d H:i:s', $currentStart + $interval);
    404351
    405         $wpdb->query($wpdb->prepare("
    406             UPDATE wp_postmeta
     352        // End time in the past? Kill the entire post
     353        if ($newEndTime < date('Y-m-d H:i:s'))
     354            wp_delete_post($id, true);
     355
     356        // Otherwise adjust the end date
     357        else $wpdb->query($wpdb->prepare("
     358            UPDATE {$wpdb->postmeta}
    407359            SET meta_value = '%s'
    408360            WHERE meta_key = '_EventEndDate'
     
    423375        return $wpdb->get_var($wpdb->prepare("
    424376            SELECT MIN(meta_value)
    425             FROM {$wpdb->prefix}postmeta
     377            FROM {$wpdb->postmeta}
    426378            WHERE meta_key = '_EventStartDate'
    427379            AND post_id = '%d';
     
    441393        return $wpdb->get_var($wpdb->prepare("
    442394            SELECT MIN(meta_value)
    443             FROM {$wpdb->prefix}postmeta
     395            FROM {$wpdb->postmeta}
    444396            WHERE meta_key = '_EventEndDate'
    445397            AND post_id = '%d';
     
    449401
    450402    /**
    451      * Loads the specified config array, allowing it to be pulled directly into
    452      * the scope of the calling method.
     403     * Loads the specified config array, allowing it to be pulled directly into the scope of the calling method.
    453404     *
    454405     * @param $config
  • the-events-calendar-housekeeper/trunk/readme.txt

    r621079 r714127  
    33Donate link: http://freshlybakedwebsites.net/say-thanks-with-a-beer/
    44Tags: events, calendar, housekeeping, clean up, database, tidy
    5 Requires at least: 3.4.2
    6 Tested up to: 3.4.2
    7 Stable tag: 1.0.3
     5Requires at least: 3.5.1
     6Tested up to: 3.5.1
     7Stable tag: 1.2.0
    88License: GPL3 or later
    99License URI: http://www.gnu.org/licenses/gpl.html
     
    1313== Description ==
    1414
    15 Developed to work with The Events Calendar 2.0.9, this plugin allows for expired events to be automatically vacuumed up rather than leaving them to clutter up your database.
     15Developed to work with The Events Calendar 3.0, this plugin allows for expired events to be automatically vacuumed up rather than leaving them to clutter up your database.
     16_If you are still using The Events Calendar 2.x then you should use [this older version of Housekeeper](http://downloads.wordpress.org/plugin/the-events-calendar-housekeeper.1.0.3.zip)_,
     17noting that it still has some minor bugs and of course remembering that awesome people use the latest and greatest.
    1618
    1719* Configurable: clean up events almost as soon as they have expired or enforce a buffer period of 1 week upto 6 months
     
    2123
    2224= Author =
    23 This plugin was written by [Barry Hughes](http://freshlybakedwebsites.net). Go on, [buy him a beer!](http://freshlybakedwebsites.net/say-thanks-with-a-beer/) More than anything, it will make you feel good about yourself.
     25This plugin was written by [Barry Hughes](http://codingkills.me "WordPress and PHP Developer based in BC, Canada") (it _is not_ an official plugin by Modern Tribe, so don't go pestering them for support). If this helps you out then
     26[buy the plugin author a beer!](http://freshlybakedwebsites.net/say-thanks-with-a-beer/) More than anything, it will make you feel good about yourself.
    2427
    2528== Installation ==
     
    2730Like any other plugin you simply upload the plugin directory to the wp-content/plugins directory. You can also upload and install it through the WordPress plugins admin page.
    2831
    29 *Remember that a prerequisite is the existence of The Events Calendar 2.0.9* (and possibly later versions).
     32*Remember that a prerequisite is the existence of The Events Calendar 2.0.9* (though the latest version targets The Events Calendar 3.0).
    3033
    3134Once installed and activated a new "Housekeeping" tab will appear on the Events > Settings page. You must enable garbage collection via this tab or it will not do anything.
     
    3437
    3538= How are recurring events handled? =
    36 First of all, recurring events may be overhauled as of The Events Calendar 3.0 and hopefully this will be revised in time to accommodate any such changes.
    37 
    38 For the time being however, any instances of recurring events meeting the _Expiry Criteria_ are deleted - those instances not meeting the criteria are preserved. This seemed like the most logical way to approach recurring events but any other ideas are welcome.
     39Any instances of recurring events meeting the _Expiry Criteria_ are deleted - those instances not meeting the criteria are preserved. This seemed like the most logical way to approach recurring events but any other ideas are welcome.
    3940
    4041= What if the wrong events are deleted? =
    41 That's completely possible for a variety of reasons. First of all, ensure your server and WordPress date/time settings are correct. Second, but more importantly, back-up before you use it and then keep on backing-up, frequently and often. You _should_ be doing this anyway - and remember! - a back-up is useless unless you know how to restore it.
     42That's completely possible for a variety of reasons. First of all, ensure your server and WordPress date/time settings are correct. Second, but more importantly, back-up before you use it and then keep on backing-up, frequently and often.
     43You _should_ be doing this anyway - and remember! - a back-up is useless unless you know how to restore it.
    4244
    4345= Are they trashed or deleted out-right? =
    44 They are not trashed in the same way that you might trash an event from the admin interface (which allows you to recover them after the fact). When this plugin runs any events it scoops up are effectively wiped out forever.
     46They are deleted out right. So don't confuse this with the "Trash" function WordPress provides for pages, posts and many custom post types. With this plugin, any events deemed to have expired will effectively be wiped out forever.
     47
     48= Does an event expire after it has started or after it has ended? =
     49In the eyes of this plugin an event has expired after it has started and this is flagged up in the settings tab. That may not always be ideal - and for those cases you
     50can adjust the expiry criteria appropriately or just deactivate this plugin.
     51
     52= I found a bug =
     53Please post details on the forum. Better yet, post a fix and add appropriate details. This is free and open source software and comes with no guarantees, so bear that
     54in mind first of all.
    4555
    4656= I need help! =
Note: See TracChangeset for help on using the changeset viewer.