Add name attribute for cronjobs
authorMatthias Schmidt <gravatronics@live.com>
Sat, 23 May 2015 07:25:51 +0000 (09:25 +0200)
committerMatthias Schmidt <gravatronics@live.com>
Sat, 23 May 2015 07:25:51 +0000 (09:25 +0200)
CHANGELOG.md
com.woltlab.wcf/cronjob.xml
wcfsetup/install/files/lib/data/cronjob/Cronjob.class.php
wcfsetup/install/files/lib/data/cronjob/CronjobEditor.class.php
wcfsetup/install/files/lib/system/package/plugin/CronjobPackageInstallationPlugin.class.php
wcfsetup/setup/db/install.sql

index 9a1ba55aec8970ef019450711d1225a0181f7c18..9fc7e2caa2fbf8481ca43a52ca065fec36dcab49 100644 (file)
@@ -5,6 +5,7 @@
 ### 2.2.0 Alpha 1 (XXXX-YY-ZZ)
 
 * `options` support for cronjobs.
+* `name` attribute for cronjob PIP (`cronjobName` for cronjob objects).
 * `permissions` and `options` support for event listeners.
 * `name` attribute for event listener PIP (`listenerName` for event listener objects).
 * `permissions` and `options` support for template listeners.
index 00a2771b30efd6a78daa04c8c058720bfd87ff83..ef8c93d74470d8b6c4f3cd9bfb25494a6fa8ca79 100644 (file)
@@ -1,6 +1,185 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com http://www.woltlab.com/XSD/maelstrom/cronjob.xsd">
        <import>
+               <cronjob name="refreshPackageUpdates">
+                       <classname><![CDATA[wcf\system\cronjob\GetUpdateInfoCronjob]]></classname>
+                       <description><![CDATA[Updates package information]]></description>
+                       <description language="de"><![CDATA[Aktualisiert Paket-Informationen]]></description>
+                       <startminute>0</startminute>
+                       <starthour>2</starthour>
+                       <startdom>*/2</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="refreshSearchRobots">
+                       <classname><![CDATA[wcf\system\cronjob\RefreshSearchRobotsCronjob]]></classname>
+                       <description><![CDATA[Refreshes list of search robots]]></description>
+                       <description language="de"><![CDATA[Aktualisiert die Liste der Suchroboter]]></description>
+                       <startminute>0</startminute>
+                       <starthour>3</starthour>
+                       <startdom>1</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="dailyCleanUp">
+                       <classname><![CDATA[wcf\system\cronjob\DailyCleanUpCronjob]]></classname>
+                       <description><![CDATA[Executes daily Cleanup]]></description>
+                       <description language="de"><![CDATA[Führt tägliche Aufräumarbeiten aus]]></description>
+                       <startminute>0</startminute>
+                       <starthour>1</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="hourlyCleanUp">
+                       <classname><![CDATA[wcf\system\cronjob\HourlyCleanUpCronjob]]></classname>
+                       <description><![CDATA[Executes hourly Cleanup]]></description>
+                       <description language="de"><![CDATA[Führt stündliche Aufräumarbeiten aus]]></description>
+                       <startminute>0</startminute>
+                       <starthour>*</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="sessionCleanUp">
+                       <classname><![CDATA[wcf\system\cronjob\SessionCleanUpCronjob]]></classname>
+                       <description><![CDATA[Deletes expired sessions]]></description>
+                       <description language="de"><![CDATA[Löscht abgelaufene Sessions]]></description>
+                       <startminute>*/30</startminute>
+                       <starthour>*</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="attachmentCleanUp">
+                       <classname><![CDATA[wcf\system\cronjob\AttachmentCleanUpCronjob]]></classname>
+                       <description><![CDATA[Deletes orphaned attachments]]></description>
+                       <description language="de"><![CDATA[Löscht verwaiste Dateianhänge]]></description>
+                       <startminute>0</startminute>
+                       <starthour>2</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="lastActivityUpdate">
+                       <classname><![CDATA[wcf\system\cronjob\LastActivityCronjob]]></classname>
+                       <description><![CDATA[Updates last activity timestamp]]></description>
+                       <description language="de"><![CDATA[Aktualisiert Zeitpunkt der letzten Aktivität]]></description>
+                       <startminute>*/5</startminute>
+                       <starthour>*</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="userQuit">
+                       <classname><![CDATA[wcf\system\cronjob\UserQuitCronjob]]></classname>
+                       <description><![CDATA[Deletes canceled user accounts]]></description>
+                       <description language="de"><![CDATA[Löscht gekündigte Benutzer-Accounts]]></description>
+                       <startminute>0</startminute>
+                       <starthour>0</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="dailyMailNotification">
+                       <classname><![CDATA[wcf\system\cronjob\DailyMailNotificationCronjob]]></classname>
+                       <description><![CDATA[Sends daily mail notifications]]></description>
+                       <description language="de"><![CDATA[Versendet tägliche E-Mail-Benachrichtigungen]]></description>
+                       <startminute>*/30</startminute>
+                       <starthour>*</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="moderationQueueCleanup">
+                       <classname><![CDATA[wcf\system\cronjob\ModerationQueueCronjob]]></classname>
+                       <description><![CDATA[Moderation queue cleanup]]></description>
+                       <description language="de"><![CDATA[Löscht veraltete Einträge in der Moderation]]></description>
+                       <startminute>0</startminute>
+                       <starthour>1</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="statDailyBuilder">
+                       <classname><![CDATA[wcf\system\cronjob\StatDailyBuilderCronjob]]></classname>
+                       <description><![CDATA[Builds the daily statistics]]></description>
+                       <description language="de"><![CDATA[Generiert die täglichen Statistiken]]></description>
+                       <startminute>0</startminute>
+                       <starthour>1</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="userGroupAssignment">
+                       <classname><![CDATA[wcf\system\cronjob\UserGroupAssignmentCronjob]]></classname>
+                       <description><![CDATA[Automatically assigns users to user groups]]></description>
+                       <description language="de"><![CDATA[Ordnet Benutzer automatisch Benutzergruppen zu]]></description>
+                       <startminute>*/30</startminute>
+                       <starthour>*</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+               
+               <cronjob name="userBan">
+                       <classname><![CDATA[wcf\system\cronjob\UserBanCronjob]]></classname>
+                       <description><![CDATA[Unbans users and enables disabled avatars and disabled signatures]]></description>
+                       <description language="de"><![CDATA[Entsperrt gesperrte Benutzer, Avatare und Signaturen]]></description>
+                       <startminute>0</startminute>
+                       <starthour>1</starthour>
+                       <startdom>*</startdom>
+                       <startmonth>*</startmonth>
+                       <startdow>*</startdow>
+                       <active>1</active>
+                       <canbeedited>1</canbeedited>
+                       <canbedisabled>1</canbedisabled>
+               </cronjob>
+       </import>
+       
+       <delete>
+               <!-- cronjobs with names now -->
                <cronjob>
                        <classname><![CDATA[wcf\system\cronjob\GetUpdateInfoCronjob]]></classname>
                        <description><![CDATA[Updates package information]]></description>
                        <canbeedited>1</canbeedited>
                        <canbedisabled>1</canbedisabled>
                </cronjob>
-       </import>
-</data>
\ No newline at end of file
+               <!-- /cronjobs with names now -->
+       </delete>
+</data>
index 0a270a9cd0704acec53ef4bbf1e69ec7e074a0a4..d5b7f382fc9cf54d68055f4def48bca99938ad9a 100644 (file)
@@ -47,6 +47,13 @@ class Cronjob extends DatabaseObject {
         */
        const MAX_FAIL_COUNT = 3;
        
+       /**
+        * prefix of automatically created cronjob names
+        * @var string
+        * @deprecated  will be removed once cronjob names are mandatory
+        */
+       const AUTOMATIC_NAME_PREFIX = 'com.woltlab.wcf.cronjob';
+       
        /**
         * Returns timestamp of next execution.
         * 
index ce3ca8842e215fcfdd16291d168b242e964c1a1b..0ef999242eec1bcacebecb47531629a9c2a9fee6 100644 (file)
@@ -42,68 +42,110 @@ class CronjobEditor extends DatabaseObjectEditor implements IEditableCachedObjec
                
                // save cronjob description
                if (!empty($descriptions)) {
-                       // set default value
-                       if (isset($descriptions[''])) {
-                               $defaultValue = $descriptions[''];
-                       }
-                       else if (isset($descriptions['en'])) {
-                               // fallback to English
-                               $defaultValue = $descriptions['en'];
-                       }
-                       else if (isset($descriptions[WCF::getLanguage()->getFixedLanguageCode()])) {
-                               // fallback to the language of the current user
-                               $defaultValue = $descriptions[WCF::getLanguage()->getFixedLanguageCode()];
-                       }
-                       else {
-                               // fallback to first description
-                               $defaultValue = reset($descriptions);
-                       }
-                       
-                       // fetch data directly from database during framework installation
-                       if (!PACKAGE_ID) {
-                               $sql = "SELECT  *
-                                       FROM    wcf".WCF_N."_language_category
-                                       WHERE   languageCategory = ?";
-                               $statement = WCF::getDB()->prepareStatement($sql);
-                               $statement->execute(array('wcf.acp.cronjob'));
-                               $languageCategory = $statement->fetchObject('wcf\data\language\category\LanguageCategory');
-                               
-                               $languages = new LanguageList();
-                               $languages->readObjects();
-                       }
-                       else {
-                               $languages = LanguageFactory::getInstance()->getLanguages();
-                               $languageCategory = LanguageFactory::getInstance()->getCategory('wcf.acp.cronjob');
-                       }
-                       
-                       $sql = "INSERT INTO     wcf".WCF_N."_language_item
-                                               (languageID, languageItem, languageItemValue, languageCategoryID, packageID)
-                               VALUES          (?, ?, ?, ?, ?)";
+                       $cronjobEditor = new self($cronjob);
+                       $cronjobEditor->saveDescriptions($descriptions, false);
+               }
+               
+               return $cronjob;
+       }
+       
+       /**
+        * Saves the descriptions of the cronjob in language items.
+        * 
+        * @param       array<string>           $descriptions
+        * @param       boolean                 $deleteOldDescriptions
+        */
+       protected function saveDescriptions(array $descriptions, $deleteOldDescriptions = true) {
+               // set default value
+               if (isset($descriptions[''])) {
+                       $defaultValue = $descriptions[''];
+               }
+               else if (isset($descriptions['en'])) {
+                       // fallback to English
+                       $defaultValue = $descriptions['en'];
+               }
+               else if (isset($descriptions[WCF::getLanguage()->getFixedLanguageCode()])) {
+                       // fallback to the language of the current user
+                       $defaultValue = $descriptions[WCF::getLanguage()->getFixedLanguageCode()];
+               }
+               else {
+                       // fallback to first description
+                       $defaultValue = reset($descriptions);
+               }
+               
+               // fetch data directly from database during framework installation
+               if (!PACKAGE_ID) {
+                       $sql = "SELECT  *
+                               FROM    wcf".WCF_N."_language_category
+                               WHERE   languageCategory = ?";
                        $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute(array('wcf.acp.cronjob'));
+                       $languageCategory = $statement->fetchObject('wcf\data\language\category\LanguageCategory');
                        
-                       foreach ($languages as $language) {
-                               $value = $defaultValue;
-                               if (isset($descriptions[$language->languageCode])) {
-                                       $value = $descriptions[$language->languageCode];
-                               }
-                               
-                               $statement->execute(array(
-                                       $language->languageID,
-                                       'wcf.acp.cronjob.description.cronjob'.$cronjob->cronjobID,
-                                       $value,
-                                       $languageCategory->languageCategoryID,
-                                       $cronjob->packageID
-                               ));
+                       $languages = new LanguageList();
+                       $languages->readObjects();
+               }
+               else {
+                       $languages = LanguageFactory::getInstance()->getLanguages();
+                       $languageCategory = LanguageFactory::getInstance()->getCategory('wcf.acp.cronjob');
+               }
+               
+               // delete old descriptions first
+               if ($deleteOldDescriptions) {
+                       $sql = "DELETE FROM     wcf".WCF_N."_language_item
+                               WHERE           languageItem = ?";
+                       $statement = WCF::getDB()->prepareStatement($sql);
+                       $statement->execute([ 'wcf.acp.cronjob.description.cronjob'.$this->cronjobID ]);
+               }
+               
+               // save new descriptions
+               $sql = "INSERT INTO     wcf".WCF_N."_language_item
+                                       (languageID, languageItem, languageItemValue, languageCategoryID, packageID)
+                       VALUES          (?, ?, ?, ?, ?)";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               
+               foreach ($languages as $language) {
+                       $value = $defaultValue;
+                       if (isset($descriptions[$language->languageCode])) {
+                               $value = $descriptions[$language->languageCode];
                        }
                        
-                       // update cronjob
-                       $cronjobEditor = new CronjobEditor($cronjob);
-                       $cronjobEditor->update(array(
-                               'description' => 'wcf.acp.cronjob.description.cronjob'.$cronjob->cronjobID
+                       $statement->execute(array(
+                               $language->languageID,
+                               'wcf.acp.cronjob.description.cronjob'.$this->cronjobID,
+                               $value,
+                               $languageCategory->languageCategoryID,
+                               $this->packageID
                        ));
                }
                
-               return $cronjob;
+               // update cronjob
+               $this->update(array(
+                       'description' => 'wcf.acp.cronjob.description.cronjob'.$this->cronjobID
+               ));
+       }
+       
+       /**
+        * @see \wcf\data\IEditableObject::update()
+        */
+       public function update(array $parameters = array()) {
+               $descriptions = array();
+               if (isset($parameters['description']) && is_array($parameters['description'])) {
+                       if (count($parameters['description']) > 1) {
+                               $descriptions = $parameters['description'];
+                               $parameters['description'] = '';
+                       }
+                       else {
+                               $parameters['description'] = reset($parameters['description']);
+                       }
+               }
+               
+               parent::update($parameters);
+               
+               // save cronjob description
+               if (!empty($descriptions)) {
+                       $this->saveDescriptions($descriptions);
+               }
        }
        
        /**
index f8545ac681af0422c56e5020395f30bbde98b218..70bf865a5c1962fa8a7edfb236d218ff48f44e3b 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\system\package\plugin;
+use wcf\data\cronjob\Cronjob;
+use wcf\data\cronjob\CronjobEditor;
 use wcf\system\WCF;
 use wcf\util\CronjobUtil;
 
@@ -42,12 +44,26 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu
                $sql = "DELETE FROM     wcf".WCF_N."_".$this->tableName."
                        WHERE           className = ?
                                        AND packageID = ?";
+               $legacyStatement = WCF::getDB()->prepareStatement($sql);
+               
+               $sql = "DELETE FROM     wcf".WCF_N."_".$this->tableName."
+                       WHERE           cronjobName = ?
+                                       AND packageID = ?";
                $statement = WCF::getDB()->prepareStatement($sql);
+               
                foreach ($items as $item) {
-                       $statement->execute(array(
-                               $item['elements']['classname'],
-                               $this->installation->getPackageID()
-                       ));
+                       if (!isset($item['attributes']['name'])) {
+                               $legacyStatement->execute(array(
+                                       $item['elements']['classname'],
+                                       $this->installation->getPackageID()
+                               ));
+                       }
+                       else {
+                               $statement->execute(array(
+                                       $item['attributes']['name'],
+                                       $this->installation->getPackageID()
+                               ));
+                       }
                }
        }
        
@@ -59,6 +75,7 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu
                        'canBeDisabled' => (isset($data['elements']['canbedisabled'])) ? intval($data['elements']['canbedisabled']) : 1,
                        'canBeEdited' => (isset($data['elements']['canbeedited'])) ? intval($data['elements']['canbeedited']) : 1,
                        'className' => (isset($data['elements']['classname'])) ? $data['elements']['classname'] : '',
+                       'cronjobName' => (isset($data['attributes']['name']) ? $data['attributes']['name'] : ''),
                        'description' => (isset($data['elements']['description'])) ? $data['elements']['description'] : '',
                        'isDisabled' => (isset($data['elements']['isdisabled'])) ? intval($data['elements']['isdisabled']) : 0,
                        'options' => (isset($data['elements']['options'])) ? $data['elements']['options'] : '',
@@ -77,11 +94,50 @@ class CronjobPackageInstallationPlugin extends AbstractXMLPackageInstallationPlu
                CronjobUtil::validate($data['startMinute'], $data['startHour'], $data['startDom'], $data['startMonth'], $data['startDow']);
        }
        
+       /**
+        * @see \wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::import()
+        */
+       protected function import(array $row, array $data) {
+               // if a cronjob is updated without a name given, keep the old automatically
+               // assigned name
+               if (!empty($row) && !$data['cronjobName']) {
+                       unset($data['cronjobName']);
+               }
+               
+               $cronjob = parent::import($row, $data);
+               
+               // update event listener name
+               if (!$cronjob->cronjobName) {
+                       $cronjobEditor = new CronjobEditor($cronjob);
+                       $cronjobEditor->update(array(
+                               'cronjobName' => Cronjob::AUTOMATIC_NAME_PREFIX.$cronjob->cronjobID
+                       ));
+                       
+                       $cronjob = new Cronjob($cronjob->listenerID);
+               }
+               
+               return $cronjob;
+       }
+       
        /**
         * @see \wcf\system\package\plugin\AbstractXMLPackageInstallationPlugin::findExistingItem()
         */
        protected function findExistingItem(array $data) {
-               return null;
+               if (!$data['cronjobName']) return null;
+               
+               $sql = "SELECT  *
+                       FROM    wcf".WCF_N."_".$this->tableName."
+                       WHERE   packageID = ?
+                               AND cronjobName = ?";
+               $parameters = array(
+                       $this->installation->getPackageID(),
+                       $data['cronjobName']
+               );
+               
+               return array(
+                       'sql' => $sql,
+                       'parameters' => $parameters
+               );
        }
        
        /**
index 91525f3daf5d2a9b09b5e86ba3ffcc585baf653b..ebd39536f5b1678a4a00a418c0313c154e0c6459 100644 (file)
@@ -308,6 +308,7 @@ CREATE TABLE wcf1_cronjob (
        cronjobID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
        className varchar(255) NOT NULL DEFAULT '',
        packageID INT(10) NOT NULL,
+       cronjobName VARCHAR(255) NOT NULL,
        description varchar(255) NOT NULL DEFAULT '',
        startMinute varchar(255) NOT NULL DEFAULT '*',
        startHour varchar(255) NOT NULL DEFAULT '*',
@@ -322,7 +323,9 @@ CREATE TABLE wcf1_cronjob (
        canBeDisabled TINYINT(1) NOT NULL DEFAULT 1,
        state TINYINT(1) NOT NULL DEFAULT 0,
        failCount TINYINT(1) NOT NULL DEFAULT 0,
-       options TEXT
+       options TEXT,
+       
+       UNIQUE KEY cronjobName (cronjobName, packageID)
 );
 
 DROP TABLE IF EXISTS wcf1_cronjob_log;