<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Publish new geocaches that are marked for timed publish ***************************************************************************/ checkJob(new user_delete()); class user_delete { public $name = 'user_delete'; public $interval = 86400; public function run() { sql("set @allowdelete=1"); sql("DELETE FROM `user`\n WHERE `date_created`<DATE_ADD(NOW(), INTERVAL -21 DAY)\n AND `is_active_flag`=0 AND `activation_code`!=''"); } }
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Deletes orphan data which are left over due to software bugs or * system failures. ***************************************************************************/ checkJob(new orphan_cleanup()); class orphan_cleanup { public $name = 'orphan_cleanup'; public $interval = 86400; // once per day public function run() { // cleanup XML session data sql_temp_table('tmpsessiondata'); sql('CREATE TEMPORARY TABLE &tmpsessiondata ENGINE=MEMORY SELECT DISTINCT `xmlsession_data`.`session_id` FROM `xmlsession_data` LEFT JOIN `xmlsession` ON `xmlsession`.`id`=`xmlsession_data`.`session_id` WHERE `xmlsession`.`id` IS NULL'); $count = sql_value('SELECT COUNT(*) FROM `xmlsession_data` WHERE `session_id` IN (SELECT `session_id` FROM &tmpsessiondata)', 0); if ($count) { sql("DELETE FROM `xmlsession_data`\n WHERE `session_id` IN (SELECT `session_id` FROM &tmpsessiondata)"); echo 'orphan_cleanup: dropped ' . $count . " record(s) from xmlsession_data\n"; } sql_drop_temp_table('tmpsessiondata');
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Import new data from geokrety.org. * * See util2/geokrety for check and repair functions. * See discussion in http://redmine.opencaching.de/issues/18. ***************************************************************************/ checkJob(new geokrety()); class geokrety { public $name = 'geokrety'; public $interval = 900; public function run() { global $opt; if ($opt['cron']['geokrety']['run']) { $xmlfile = $this->loadXML(); if ($xmlfile == false) { return; } $this->importXML($xmlfile); if (!$opt['cron']['geokrety']['xml_archive']) { $this->removeXML($xmlfile); } } }
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Delete old log entries with personal user data for data privacy ***************************************************************************/ checkJob(new purge_logs()); class purge_logs { public $name = 'purge_logs'; public $interval = 86400; // daily public function run() { global $opt; if ($opt['logic']['logs']['purge_email'] > 0) { sql("DELETE FROM `email_user` WHERE date_created < NOW() - INTERVAL &1 DAY", $opt['logic']['logs']['purge_email']); sql("DELETE FROM `logentries` WHERE date_created < NOW() - INTERVAL &1 DAY AND eventid IN (1,2,3,8)", $opt['logic']['logs']['purge_email']); } if ($opt['logic']['logs']['purge_userdata'] > 0) { sql("DELETE FROM `logentries` WHERE date_created < NOW() - INTERVAL &1 DAY AND eventid IN (6,7)", $opt['logic']['logs']['purge_userdata']); } // Type 5 events = adoptions are still recorded here and preliminary archived, // but may be discarded after verifying that they are not used anywhere. // Adoptions are now in cache_adoptions table. } }
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Cleanup the table sys_temptables from entries of dead threads * * run it once a day * ***************************************************************************/ checkJob(new cleanup_temptables()); class cleanup_temptables { var $name = 'cleanup_temptables'; var $interval = 86400; function run() { $nIds = array(); $rs = sqlf("SHOW PROCESSLIST"); while ($r = sql_fetch_assoc($rs)) { $nIds[$r['Id']] = $r['Id']; } sql_free_result($rs); $rs = sqlf("SELECT DISTINCT `threadid` FROM `sys_temptables`"); while ($r = sql_fetch_assoc($rs)) { if (!isset($nIds[$r['threadid']])) { sqlf("DELETE FROM `sys_temptables` WHERE `threadid`='&1'", $r['threadid']); } }
<?php /*************************************************************************** * You can find the license in the docs directory * * Unicode Reminder メモ * * Cleanup the table sys_temptables from entries of dead threads * * run it once a day * ***************************************************************************/ require_once $opt['rootpath'] . 'lib2/logic/gis.class.php'; checkJob(new cache_location()); class cache_location { var $name = 'cache_location'; var $interval = 0; function run() { global $opt; $rsCache = sql("SELECT `caches`.`cache_id`, `caches`.`latitude`, `caches`.`longitude` FROM `caches` LEFT JOIN `cache_location` ON `caches`.`cache_id`=`cache_location`.`cache_id` WHERE ISNULL(`cache_location`.`cache_id`) UNION SELECT `caches`.`cache_id`, `caches`.`latitude`, `caches`.`longitude` FROM `caches` INNER JOIN `cache_location` ON `caches`.`cache_id`=`cache_location`.`cache_id` WHERE `caches`.`last_modified`>`cache_location`.`last_modified`"); while ($rCache = sql_fetch_assoc($rsCache)) { $sCode = ''; $rsLayers = sql("SELECT `level`, `code`, AsText(`shape`) AS `geometry` FROM `nuts_layer` WHERE WITHIN(GeomFromText('&1'), `shape`) ORDER BY `level` DESC", 'POINT(' . $rCache['longitude'] . ' ' . $rCache['latitude'] . ')'); while ($rLayers = sql_fetch_assoc($rsLayers)) { if (gis::ptInLineRing($rLayers['geometry'], 'POINT(' . $rCache['longitude'] . ' ' . $rCache['latitude'] . ')')) { $sCode = $rLayers['code']; break; } }
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Publish new geocaches that are marked for timed publish ***************************************************************************/ checkJob(new publish_caches()); class publish_caches { var $name = 'publish_caches'; var $interval = 60; function run() { global $login; $rsPublish = sql("SELECT `cache_id`, `user_id` FROM `caches` WHERE `status`=5 AND NOT ISNULL(`date_activate`) AND `date_activate`<=NOW()"); while ($rPublish = sql_fetch_array($rsPublish)) { $userid = $rPublish['user_id']; $cacheid = $rPublish['cache_id']; // update cache status to active sql("SET @STATUS_CHANGE_USER_ID='&1'", $login->userid); sql("UPDATE `caches` SET `status`=1, `date_activate`=NULL WHERE `cache_id`='&1'", $cacheid); } sql_free_result($rsPublish); } }
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Update top rating statistics ***************************************************************************/ checkJob(new rating_tops()); class rating_tops { var $name = 'rating_tops'; var $interval = 86400; function run() { sql("DELETE FROM `rating_tops`"); sql_temp_table('topLocationCaches'); sql_temp_table('topRatings'); sql_temp_table('topResult'); sql("CREATE TEMPORARY TABLE &topLocationCaches (`cache_id` INT(11) PRIMARY KEY) ENGINE=MEMORY"); sql("CREATE TEMPORARY TABLE &topRatings (`cache_id` INT(11) PRIMARY KEY, `ratings` INT(11)) ENGINE=MEMORY"); sql("CREATE TEMPORARY TABLE &topResult (`idx` INT(11), `cache_id` INT(11) PRIMARY KEY, `ratings` INT(11), `founds` INT(11)) ENGINE=MEMORY"); $rsCountry = sql('SELECT SQL_BUFFER_RESULT SQL_SMALL_RESULT DISTINCT `country` FROM `caches`'); while ($rCountry = sql_fetch_assoc($rsCountry)) { $rsAdm3 = sql("\n\t\t\t\tSELECT SQL_BUFFER_RESULT SQL_SMALL_RESULT DISTINCT \n\t\t\t\t IF(`cache_location`.`code1`=`caches`.`country`,`cache_location`.`code3`,NULL) `code3`\n\t\t\t\tFROM `caches`\n\t\t\t\tLEFT JOIN `cache_location` ON `caches`.`cache_id`=`cache_location`.`cache_id`\n\t\t\t\tWHERE `caches`.`country`='&1'", $rCountry['country']); while ($rAdm3 = sql_fetch_assoc($rsAdm3)) { sql("TRUNCATE TABLE &topLocationCaches"); sql("TRUNCATE TABLE &topRatings"); sql("TRUNCATE TABLE &topResult"); // Alle Caches für diese Gruppe finden
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ ***************************************************************************/ checkJob(new push_waypoint_reports()); class push_waypoint_reports { public $name = 'push_waypoint_reports'; public $interval = 120; public function run() { global $opt; if ($opt['cron']['gcwp']['report']) { $rs = sql('SELECT * FROM `waypoint_reports` WHERE `gcwp_processed`=0 ORDER BY `date_reported`'); while ($r = sql_fetch_assoc($rs)) { if (substr($r['wp_external'], 0, 2) != 'GC') { $result = 'ok'; } else { $result = @file_get_contents($opt['cron']['gcwp']['report'] . '?ocwp=' . urlencode($r['wp_oc']) . '&gcwp=' . urlencode($r['wp_external']) . '&source=' . urlencode($r['source'])); $result = trim($result); } if ($result != 'ok') { echo "could not push GC waypoint report (id " . $r['report_id'] . "): " . $result . "\n"; break; } else { sql("\n UPDATE `waypoint_reports`\n SET `gcwp_processed`=1\n WHERE `report_id`='&1'", $r['report_id']);
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * This cronjob fills the table cache_waypoint_pool with waypoints that * can be assigned to new caches. The code is cpu intensive on database * server. ***************************************************************************/ checkJob(new cache_waypoint_pool()); class cache_waypoint_pool { public $name = 'cache_waypoint_pool'; public $interval = 604800; // once a week public function run() { global $opt; $nLastInsertsCount = 1; // check if the pool needs to be filled up and repeat until the $nPoolSize = $this->getCurrentPoolSize(); if ($nPoolSize < $opt['logic']['waypoint_pool']['min_count']) { while ($nPoolSize < $opt['logic']['waypoint_pool']['max_count'] && $nLastInsertsCount > 0) { $nLastInsertsCount = $this->fill($opt['logic']['waypoint_pool']['max_count'] - $nPoolSize); $nPoolSize = $this->getCurrentPoolSize(); } } } public function getCurrentPoolSize()
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Process system maillog to detect email delivery problems ***************************************************************************/ checkJob(new maillog()); class maillog { var $name = 'maillog'; var $interval = 600; // every 10 minutes function run() { global $opt; if ($opt['system']['maillog']['syslog_db_host'] != '') { if ($opt['system']['maillog']['syslog_mta'] != 'postfix/smtp') { echo $this->name . ": unknown MTA '" . $opt['system']['maillog']['syslog_mta'] . "'\n"; return; } else { $this->process_syslog(); } } } function process_syslog() { global $opt; $dbc = @mysql_connect($opt['system']['maillog']['syslog_db_host'], $opt['system']['maillog']['syslog_db_user'], $opt['system']['maillog']['syslog_db_password'], TRUE);
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Replicate database contents between different OC installations/nodes ***************************************************************************/ checkJob(new replicate()); class replicate { public $name = 'replicate'; public $interval = 3600; public function run() { global $opt; if ($opt['cron']['replicate']['delete_hidden_caches']['url']) { // This is used to remove unwanted data from test.opencaching.de // (where any users may have admin rights and see hidden caches). $hidden_caches = file_get_contents($opt['cron']['replicate']['delete_hidden_caches']['url']); $hc = explode("\n", trim($hidden_caches)); $hc_imploded_and_escaped = "'" . implode("','", array_map('sql_escape', $hc)) . "'"; sql("SET @allowdelete = 1"); sql("DELETE FROM `caches` WHERE `wp_oc` IN (" . $hc_imploded_and_escaped . ")"); // All dependent data in other tables is deleted via trigger. } } }
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Delete duplicate log pictures (produced e.g. by Ocprop) ***************************************************************************/ checkJob(new picture_cleanup()); class picture_cleanup { public $name = 'picture_cleanup'; public $interval = 86400; public function run() { $rsDuplicatePic = sql('SELECT `object_id`, `title` FROM `pictures` WHERE `object_type`=1 GROUP BY `object_id`, `title` HAVING COUNT(*) > 1'); while ($rDuplicatePic = sql_fetch_assoc($rsDuplicatePic)) { $rsInstances = sql(" SELECT `pictures`.`id` `picid`, `cache_logs`.`cache_id` `cache_id`\n FROM `pictures`\n LEFT JOIN `cache_logs` ON `cache_logs`.`id` = `pictures`.`object_id`\n WHERE `pictures`.`object_type`=1 AND `pictures`.`object_id`='&1' AND `pictures`.`title`='&2'\n ORDER BY `pictures`.`date_created`", $rDuplicatePic['object_id'], $rDuplicatePic['title']); $instances = sql_fetch_assoc_table($rsInstances); foreach ($instances as &$instance) { $instance['pic'] = new picture($instance['picid']); $instance['filesize'] = @filesize($instance['pic']->getFilename()); } $countInstances = count($instances); for ($n = 1; $n < $countInstances; ++$n) { if ($instances[$n]['filesize'] !== false) {
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * - check all slaves and manage table sys_repl_slaves * - check all slaves and purge master logs * - send warning when too many logs stay on master (file size) ***************************************************************************/ checkJob(new replication_monitor()); class replication_monitor { public $name = 'replication_monitor'; public $interval = 0; //var $interval = 60; public function run() { global $opt; $known_ids = []; foreach ($opt['db']['slaves'] as $k => $v) { $this->check_slave($k); $known_ids[] = "'" . sql_escape($k) . "'"; } if (count($known_ids) > 0) { sql("DELETE FROM `sys_repl_slaves` WHERE `id` NOT IN (" . implode(',', $known_ids) . ")"); } else { sql("DELETE FROM `sys_repl_slaves`"); } // now, clean up sys_repl_exclude
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Update GC waypoint data from external sources ***************************************************************************/ checkJob(new gcwp_update()); class gcwp_update { var $name = 'gcwp_update'; var $interval = 3600; // every hour function run() { global $opt; $ocwp_imported = array(); $errors = false; foreach ($opt['cron']['gcwp']['sources'] as $source) { $wpdata = @file($source); if ($wpdata === FALSE) { echo "gcwp_update: error reading " . $source . "\n"; $errors = true; } else { foreach ($wpdata as $line) { $waypoints = explode(",", trim($line)); if (count($waypoints) == 2) { sql("UPDATE `caches` SET `wp_gc_maintained`='&2' WHERE `wp_oc`='&1'", $waypoints[0], $waypoints[1]); $ocwp_imported[] = sql_escape($waypoints[0]);
<?php /*************************************************************************** * You can find the license in the docs directory * * Unicode Reminder メモ ***************************************************************************/ checkJob(new slave_cleanup()); class slave_cleanup { var $name = 'slave_cleanup'; var $interval = 300; function run() { global $opt; $rs = sql("SELECT `id` FROM `sys_repl_slaves` WHERE `active`=1 AND `online`=1 AND (TIMESTAMP(NOW())-TIMESTAMP(`last_check`)+`time_diff`<'&1')", $opt['db']['slave']['max_behind']); while ($r = sql_fetch_assoc($rs)) { $this->cleanup_slave($r['id']); } sql_free_result($rs); $this->cleanup_slave(-1); } function cleanup_slave($slaveId) { // ensure old slave is disconnected sql_disconnect_slave(); // connect the slave if ($slaveId == -1) { sql_connect_master_as_slave(); } else { sql_connect_slave($slaveId);
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Publish new geocaches that are marked for timed publish ***************************************************************************/ checkJob(new phpbbtopics()); class phpbbtopics { var $name = 'phpbbtopics'; var $interval = 600; var $topiclist = array(); function run() { global $opt; foreach ($opt['cron']['phpbbtopics']['forumids'] as $id) { $url = $opt['cron']['phpbbtopics']['url']; $url = str_replace('{id}', $id, $url); if ($this->processUrl($url) == false) { return; } } usort($this->topiclist, 'sort_compare_updated'); $this->topiclist = array_slice($this->topiclist, 0, $opt['cron']['phpbbtopics']['count']); $f = fopen($opt['rootpath'] . 'cache2/phpbb.inc.php', 'w'); fwrite($f, '<?php' . "\n"); fwrite($f, '$phpbb_topics = unserialize("' . str_replace('"', '\\"', serialize($this->topiclist)) . '");' . "\n"); fwrite($f, '?>');
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Generate sitemap.xml as specified by http://www.sitemaps.org * And send ping to search engines ***************************************************************************/ checkJob(new sitemaps()); class sitemaps { public $name = 'sitemaps'; public $interval = 604800; // once a week public $oSitemapXML = false; public function run() { global $opt; if ($opt['cron']['sitemaps']['generate'] == true) { $this->oSitemapXML = new sitemapxml(); $this->oSitemapXML->open($opt['rootpath'], $opt['page']['https']['mode'] == HTTPS_ENFORCED ? $opt['page']['absolute_https_url'] : $opt['page']['absolute_http_url']); $this->oSitemapXML->write('index.php', time(), 'always'); $this->write_viewacache_urls(); $this->write_articles_urls(); $this->write_viewlogs_urls(); $this->write_viewprofile_urls(); $this->oSitemapXML->write('tops.php', time() - 24 * 60 * 60, 'daily'); $this->oSitemapXML->write('newcachesrest.php', time() - 24 * 60 * 60, 'daily'); $this->write_newcaches_urls();
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Automatic archiving of disabled caches ***************************************************************************/ checkJob(new autoarchive()); class autoarchive { public $name = 'autoarchive'; public $interval = 43200; // twice per day public function run() { global $opt, $login; if ($opt['cron']['autoarchive']['run']) { if (!$login->logged_in()) { echo $this->name . ": not logged in / no system user configured\n"; } elseif ($login->hasAdminPriv(ADMIN_USER)) { $this->archive_disabled_caches(); $this->archive_events(); } else { echo $this->name . ": user '" . $opt['logic']['systemuser']['user'] . "' cannot maintain caches\n"; } } } public function archive_disabled_caches() {
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Cleanup the table sys_temptables from entries of dead threads * * run it once a day * ***************************************************************************/ require_once $opt['rootpath'] . 'lib2/logic/gis.class.php'; checkJob(new cache_npa_areas()); class cache_npa_areas { public $name = 'cache_npa_areas'; public $interval = 600; public function run() { $rsCache = sql("SELECT `cache_id`, `latitude`, `longitude` FROM `caches` WHERE `need_npa_recalc`=1"); while ($rCache = sql_fetch_assoc($rsCache)) { sql("DELETE FROM `cache_npa_areas` WHERE `cache_id`='&1' AND `calculated`=1", $rCache['cache_id']); $rsLayers = sql("SELECT `id`, `type_id`, AsText(`shape`) AS `geometry` \n FROM `npa_areas` WHERE `exclude`=0 AND MBRWITHIN(GeomFromText('&1'), `shape`)", 'POINT(' . $rCache['longitude'] . ' ' . $rCache['latitude'] . ')'); while ($rLayers = sql_fetch_assoc($rsLayers)) { if (gis::ptInLineRing($rLayers['geometry'], 'POINT(' . $rCache['longitude'] . ' ' . $rCache['latitude'] . ')')) { $bExclude = false; // prüfen, ob in ausgesparter Fläche $rsExclude = sql("SELECT `id`, AsText(`shape`) AS `geometry`\n FROM `npa_areas`\n WHERE `exclude` = 1\n AND `type_id`='&1'\n AND MBRWITHIN(GeomFromText('&2'), `shape`)", $rLayers['type_id'], 'POINT(' . $rCache['longitude'] . ' ' . $rCache['latitude'] . ')'); while (($rExclude = sql_fetch_assoc($rsExclude)) && $bExclude == false) { if (gis::ptInLineRing($rExclude['geometry'], 'POINT(' . $rCache['longitude'] . ' ' . $rCache['latitude'] . ')')) {
<?php /*************************************************************************** * For license information see doc/license.txt * * Unicode Reminder メモ * * Workaround for OKAPI issue #246 ***************************************************************************/ checkJob(new okapi_cleanup()); class okapi_cleanup { public $name = 'okapi_cleanup'; public $interval = 3600; public function run() { global $opt; $files = glob($opt['okapi']['var_dir'] . '/garmin*.zip'); foreach ($files as $file) { // delete old download files after 24 hours; this large interval filters out any // timezone mismatches in file sysytems (e.g. on unconventional development // environments) if (is_file($file) && time() - filemtime($file) > 24 * 3600) { unlink($file); } } } }