Пример #1
0
function createLabelCache()
{
    global $opt;
    foreach ($opt['locale'] as $sLanguage => $v) {
        // cheating a little bit
        $opt['template']['locale'] = $sLanguage;
        labels::CreateCacheFile();
        // change to file owner
        $sFilename = $opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php';
        chown($sFilename, $opt['httpd']['user']);
        chgrp($sFilename, $opt['httpd']['group']);
    }
}
Пример #2
0
if ($cache->allowView() == false) {
    $tpl->error(ERROR_NO_ACCESS);
}
$bCrypt = isset($_REQUEST['nocrypt']) ? $_REQUEST['nocrypt'] != 1 : true;
$tpl->assign('crypt', $bCrypt);
if (isset($_REQUEST['desclang'])) {
    $sPreferedDescLang = $_REQUEST['desclang'] . ',' . $opt['template']['locale'] . ',EN';
} else {
    $sPreferedDescLang = $opt['template']['locale'] . ',EN';
}
//get cache record
$rs = sql("SELECT\t`caches`.`cache_id` AS `cacheid`,\n\t\t\t\t`caches`.`user_id` AS `userid`,\n\t\t\t\t`caches`.`status` AS `status`,\n\t\t\t\t`caches`.`latitude` AS `latitude`,\n\t\t\t\t`caches`.`longitude` AS `longitude`,\n\t\t\t\t`caches`.`name` AS `name`,\n\t\t\t\t`caches`.`type` AS `type`,\n\t\t\t\t`caches`.`size` AS `size`,\n\t\t\t\t`caches`.`search_time` AS `searchtime`,\n\t\t\t\t`caches`.`way_length` AS `waylength`,\n\t\t\t\t`caches`.`country` AS `countryCode`,\n\t\t\t\tIFNULL(`ttCountry`.`text`, `countries`.`name`) AS `country`, \n\t\t\t\t`caches`.`logpw` AS `logpw`,\n\t\t\t\t`caches`.`date_hidden` AS `datehidden`,\n\t\t\t\t`caches`.`wp_oc` AS `wpoc`,\n\t\t\t\t`caches`.`wp_gc` AS `wpgc`,\n\t\t\t\t`caches`.`wp_nc` AS `wpnc`,\n\t\t\t\t`caches`.`date_created` AS `datecreated`,\n\t\t\t\t`caches`.`difficulty` AS `difficulty`,\n\t\t\t\t`caches`.`terrain` AS `terrain`,\n\t\t\t\t`cache_desc`.`language` AS `desclanguage`,\n\t\t\t\t`cache_desc`.`short_desc` AS `shortdesc`,\n\t\t\t\t`cache_desc`.`desc` AS `desc`,\n\t\t\t\t`cache_desc`.`hint` AS `hint`,\n\t\t\t\t`cache_desc`.`desc_html` AS `deschtml`,\n\t\t\t\tIFNULL(`stat_caches`.`found`, 0) AS `found`,\n\t\t\t\tIFNULL(`stat_caches`.`notfound`, 0) AS `notfound`,\n\t\t\t\tIFNULL(`stat_caches`.`note`, 0) AS `note`,\n\t\t\t\tIFNULL(`stat_caches`.`will_attend`, 0) AS `willattend`,\n\t\t\t\tIFNULL(`stat_caches`.`watch`, 0) AS `watcher`,\n\t\t\t\t`caches`.`desc_languages` AS `desclanguages`,\n\t\t\t\tIFNULL(`stat_caches`.`ignore`, 0) AS `ignorercount`,\n\t\t\t\tIFNULL(`stat_caches`.`toprating`, 0) AS `topratings`,\n\t\t\t\tIFNULL(`cache_visits`.`count`, 0) AS `visits`,\n\t\t\t\t`user`.`username` AS `username`,\n\t\t\t\tIFNULL(`cache_location`.`code1`, '') AS `code1`,\n\t\t\t\tIFNULL(`cache_location`.`adm1`, '') AS `adm1`,\n\t\t\t\tIFNULL(`cache_location`.`adm2`, '') AS `adm2`,\n\t\t\t\tIFNULL(`cache_location`.`adm3`, '') AS `adm3`,\n\t\t\t\tIFNULL(`cache_location`.`adm4`, '') AS `adm4`\n\t\t     FROM `caches`\n\t\t    INNER JOIN `user` ON `caches`.`user_id`=`user`.`user_id`\n\t\t    INNER JOIN `cache_desc` ON `caches`.`cache_id`=`cache_desc`.`cache_id` AND `cache_desc`.`language`=PREFERED_LANG(`caches`.`desc_languages`, '&3')\n\t\t     LEFT JOIN `countries` ON `caches`.`country`=`countries`.`short`\n\t\t     LEFT JOIN `sys_trans` AS `tCountry` ON `countries`.`trans_id`=`tCountry`.`id` AND `countries`.`name`=`tCountry`.`text`\n\t\t     LEFT JOIN `sys_trans_text` AS `ttCountry` ON `tCountry`.`id`=`ttCountry`.`trans_id` AND `ttCountry`.`lang`='&2'\n\t\t     LEFT JOIN `cache_visits` ON `cache_visits`.`cache_id`=`caches`.`cache_id` AND `user_id_ip`='0'\n\t\t     LEFT JOIN `stat_caches` ON `caches`.`cache_id`=`stat_caches`.`cache_id`\n\t\t     LEFT JOIN `cache_location` ON `caches`.`cache_id` = `cache_location`.`cache_id`\n\t\t    WHERE `caches`.`cache_id`='&1'", $cacheid, $opt['template']['locale'], $sPreferedDescLang, $login->userid);
$rCache = sql_fetch_assoc($rs);
sql_free_result($rs);
if ($rCache === false) {
    $tpl->error(ERROR_CACHE_NOT_EXISTS);
}
// not published?
if ($rCache['status'] == 5) {
    $tpl->caching = false;
    $login->verify();
    if ($rCache['userid'] != $login->userid) {
        $tpl->error(ERROR_CACHE_NOT_PUBLISHED);
    }
}
$rCache['sizeName'] = labels::getLabelValue('cache_size', $rCache['size']);
$rCache['statusName'] = labels::getLabelValue('cache_status', $rCache['status']);
$rCache['typeName'] = labels::getLabelValue('cache_type', $rCache['type']);
$tpl->assign('cache', $rCache);
$tpl->title = $rCache['name'];
$tpl->display();
Пример #3
0
 function display($dummy1 = null, $dummy2 = null, $dummy3 = null)
 {
     global $opt, $db, $cookie, $login, $menu, $sqldebugger, $translate;
     global $useragent_msie;
     $cookie->close();
     // if the user is an admin, dont cache the content
     if (isset($login)) {
         if ($login->admin) {
             $this->caching = false;
         }
     }
     //Give Smarty access to the whole options array.
     $this->assign('siteSettings', $opt);
     //Should we remove this whole block since we now have
     //access using the siteSettings above?
     // assign main template vars
     // ... and some of the $opt
     $locale = $opt['template']['locale'];
     $optn['debug'] = $opt['debug'];
     $optn['template']['locales'] = $opt['template']['locales'];
     $optn['template']['locale'] = $opt['template']['locale'];
     $optn['template']['style'] = $opt['template']['style'];
     $optn['template']['country'] = $login->getUserCountry();
     $optn['page']['subtitle1'] = isset($opt['locale'][$locale]['page']['subtitle1']) ? $opt['locale'][$locale]['page']['subtitle1'] : $opt['page']['subtitle1'];
     $optn['page']['subtitle2'] = isset($opt['locale'][$locale]['page']['subtitle2']) ? $opt['locale'][$locale]['page']['subtitle2'] : $opt['page']['subtitle2'];
     $optn['page']['headimagepath'] = $opt['page']['headimagepath'];
     $optn['page']['headoverlay'] = $opt['page']['headoverlay'];
     $optn['page']['max_logins_per_hour'] = $opt['page']['max_logins_per_hour'];
     $optn['page']['absolute_url'] = $opt['page']['absolute_url'];
     $optn['page']['absolute_urlpath'] = parse_url($opt['page']['absolute_url'], PHP_URL_PATH);
     $optn['page']['target'] = $this->target;
     $optn['page']['showdonations'] = $opt['page']['showdonations'];
     $optn['page']['title'] = $opt['page']['title'];
     $optn['page']['nowpsearch'] = $this->nowpsearch;
     $optn['page']['header_javascript'] = $this->header_javascript;
     $optn['page']['body_load'] = $this->body_load;
     $optn['page']['body_unload'] = $this->body_unload;
     $optn['page']['sponsor'] = $opt['page']['sponsor'];
     $optn['page']['showsocialmedia'] = $opt['page']['showsocialmedia'];
     $optn['template']['title'] = $this->title;
     $optn['template']['caching'] = $this->caching;
     $optn['template']['popup'] = $this->popup;
     $optn['template']['popupmargin'] = $this->popupmargin;
     $optn['format'] = $opt['locale'][$opt['template']['locale']]['format'];
     $optn['mail'] = $opt['mail'];
     $optn['lib'] = $opt['lib'];
     $optn['cms'] = $opt['cms'];
     $optn['geokrety'] = $opt['geokrety'];
     $optn['template']['usercountrieslist'] = labels::getLabels('usercountrieslist');
     $optn['help']['oconly'] = helppagelink('oconly', 'OConly');
     $optn['msie'] = $useragent_msie;
     // url-sessions? (for session timout display)
     $optn['session']['url'] = false;
     if ($opt['session']['mode'] == SAVE_SESSION && $login->userid != 0) {
         if (isset($_GET['SESSION']) || isset($_POST['SESSION'])) {
             $optn['session']['url'] = true;
         }
         $optn['session']['id'] = session_id();
     }
     if (isset($login)) {
         $loginn['username'] = $login->username;
         $loginn['userid'] = $login->userid;
         $loginn['admin'] = $login->admin;
     } else {
         $loginn['username'] = '';
         $loginn['userid'] = '';
         $loginn['admin'] = '';
     }
     // build menu
     if ($this->menuitem == null) {
         $menu->SetSelectItem(MNU_ROOT);
     } else {
         $menu->SetSelectItem($this->menuitem);
     }
     $this->assign('topmenu', $menu->getTopMenu());
     $this->assign('submenu', $menu->getSubMenu());
     $this->assign('breadcrumb', $menu->getBreadcrumb());
     $this->assign('menucolor', $menu->getMenuColor());
     $this->assign('helplink', helppagelink($this->name));
     $this->assign('greybg', !$this->caching && $loginn['username'] == 'HWR-Info');
     if ($this->title == '') {
         $optn['template']['title'] = $menu->GetMenuTitle();
     }
     // build address for switching locales
     $locale_pageadr = $_SERVER['REQUEST_URI'];
     // workaround for http://redmine.opencaching.de/issues/703
     $strange_things_pos = strpos($locale_pageadr, ".php/");
     if ($strange_things_pos) {
         $locale_pageadr = substr($locale_pageadr, 0, $strange_things_pos + 4);
     }
     $lpos = strpos($locale_pageadr, "locale=");
     if ($lpos) {
         $locale_pageadr = substr($locale_pageadr, 0, $lpos);
     } else {
         $urx = explode('#', $locale_pageadr);
         $locale_pageadr = $urx[0];
         if (strpos($locale_pageadr, '?') == 0) {
             $locale_pageadr .= '?';
         } else {
             $locale_pageadr .= '&';
         }
     }
     $this->assign('locale_pageadr', $locale_pageadr);
     if ($opt['logic']['license']['disclaimer']) {
         if (isset($opt['locale'][$locale]['page']['license_url'])) {
             $lurl = $opt['locale'][$locale]['page']['license_url'];
         } else {
             $lurl = $opt['locale']['EN']['page']['license_url'];
         }
         if (isset($opt['locale'][$locale]['page']['license'])) {
             $ltext = $opt['locale'][$locale]['page']['license'];
         } else {
             $ltext = $opt['locale']['EN']['page']['license'];
         }
         $this->assign('license_disclaimer', mb_ereg_replace('%1', $lurl, $ltext));
     } else {
         $this->assign('license_disclaimer', '');
     }
     $this->assign('opt', $optn);
     $this->assign('login', $loginn);
     if ($db['connected'] == true) {
         $this->assign('sys_dbconnected', true);
     } else {
         $this->assign('sys_dbconnected', false);
     }
     $this->assign('sys_dbslave', $db['slave_id'] != -1);
     if ($this->template_exists($this->name . '.tpl')) {
         $this->assign('template', $this->name);
     } else {
         if ($this->name != 'sys_error') {
             $this->error(ERROR_TEMPLATE_NOT_FOUND);
         }
     }
     $this->bench->stop();
     $this->assign('sys_runtime', $this->bench->diff());
     $this->assign('screen_css_time', filemtime($opt['rootpath'] . "resource2/" . $opt['template']['style'] . "/css/style_screen.css"));
     $this->assign('screen_msie_css_time', filemtime($opt['rootpath'] . "resource2/" . $opt['template']['style'] . "/css/style_screen_msie.css"));
     $this->assign('print_css_time', filemtime($opt['rootpath'] . "resource2/" . $opt['template']['style'] . "/css/style_print.css"));
     // check if the template is compiled
     // if not, check if translation works correct
     $_smarty_compile_path = $this->_get_compile_path($this->name);
     if (!$this->_is_compiled($this->name, $_smarty_compile_path) && $this->name != 'error') {
         $internal_lang = $translate->t('INTERNAL_LANG', 'all', 'OcSmarty.class.php', '');
         if ($internal_lang != $opt['template']['locale'] && $internal_lang != 'INTERNAL_LANG') {
             $this->error(ERROR_COMPILATION_FAILED);
         }
     }
     if ($this->is_cached() == true) {
         $this->assign('sys_cached', true);
     } else {
         $this->assign('sys_cached', false);
     }
     if (($opt['debug'] & DEBUG_SQLDEBUGGER) == DEBUG_SQLDEBUGGER) {
         require_once $opt['rootpath'] . 'lib2/sqldebugger.class.php';
         parent::fetch($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
         $this->clear_all_assign();
         $this->main_template = 'sys_sqldebugger';
         $this->assign('commands', $sqldebugger->getCommands());
         $this->assign('cancel', $sqldebugger->getCancel());
         unset($sqldebugger);
         $this->assign('opt', $optn);
         $this->assign('login', $loginn);
         $this->caching = false;
         // unset sqldebugger to allow proper translation of sqldebugger template
         $opt['debug'] = $opt['debug'] & ~DEBUG_SQLDEBUGGER;
         $this->header();
         parent::display($this->main_template . '.tpl');
     } else {
         $this->header();
         parent::display($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
     }
     exit;
 }
Пример #4
0
 function display()
 {
     global $opt, $db, $cookie, $login, $menu, $sqldebugger, $translate;
     $cookie->close();
     //		// if the user is an admin, dont cache the content
     //		if (isset($login))
     //			if ($login->admin)
     //				$this->caching = false;
     //Give Smarty access to the whole options array.
     $this->assign('siteSettings', $opt);
     //Should we remove this whole block since we now have
     //access using the siteSettings above?
     // assign main template vars
     // ... and some of the $opt
     $optn['debug'] = $opt['debug'];
     $optn['template']['locales'] = $opt['template']['locales'];
     $optn['template']['locale'] = $opt['template']['locale'];
     $optn['template']['style'] = $opt['template']['style'];
     $optn['template']['country'] = $login->getUserCountry();
     $optn['page']['subtitle1'] = isset($opt['locale'][$opt['template']['locale']]['page']['subtitle1']) ? $opt['locale'][$opt['template']['locale']]['page']['subtitle1'] : $opt['page']['subtitle1'];
     $optn['page']['subtitle2'] = isset($opt['locale'][$opt['template']['locale']]['page']['subtitle2']) ? $opt['locale'][$opt['template']['locale']]['page']['subtitle2'] : $opt['page']['subtitle2'];
     $optn['page']['max_logins_per_hour'] = $opt['page']['max_logins_per_hour'];
     $optn['page']['absolute_url'] = $opt['page']['absolute_url'];
     $optn['page']['target'] = $this->target;
     $optn['page']['showdonations'] = $opt['page']['showdonations'];
     $optn['page']['title'] = $opt['page']['title'];
     $optn['page']['nowpsearch'] = $this->nowpsearch;
     $optn['page']['header_javascript'] = $this->header_javascript;
     $optn['page']['body_load'] = $this->body_load;
     $optn['page']['body_unload'] = $this->body_unload;
     $optn['page']['sponsor'] = $opt['page']['sponsor'];
     $optn['template']['title'] = $this->title;
     $optn['template']['caching'] = $this->caching;
     $optn['template']['popup'] = $this->popup;
     $optn['template']['popupmargin'] = $this->popupmargin;
     $optn['format'] = $opt['locale'][$opt['template']['locale']]['format'];
     $optn['mail'] = $opt['mail'];
     $optn['lib'] = $opt['lib'];
     $optn['geokrety'] = $opt['geokrety'];
     $optn['template']['usercountrieslist'] = labels::getLabels('usercountrieslist');
     // url-sessions? (for session timout display)
     $optn['session']['url'] = false;
     if ($opt['session']['mode'] == SAVE_SESSION && $login->userid != 0) {
         if (isset($_GET['SESSION']) || isset($_POST['SESSION'])) {
             $optn['session']['url'] = true;
         }
         $optn['session']['id'] = session_id();
     }
     if (isset($login)) {
         $loginn['username'] = $login->username;
         $loginn['userid'] = $login->userid;
         $loginn['admin'] = $login->admin;
     } else {
         $loginn['username'] = '';
         $loginn['userid'] = '';
         $loginn['admin'] = '';
     }
     // build menu
     if ($this->menuitem == null) {
         $menu->SetSelectItem(MNU_ROOT);
     } else {
         $menu->SetSelectItem($this->menuitem);
     }
     $this->assign('topmenu', $menu->getTopMenu());
     $this->assign('mainmenu', $menu->getSubMenuItems(MNU_START));
     $this->assign('my_menu', $menu->getSubMenuItems(MNU_MYPROFILE));
     $this->assign('breadcrumb', $menu->getBreadcrumb());
     $this->assign('menucolor', $menu->getMenuColor());
     if ($this->title == '') {
         $optn['template']['title'] = $menu->GetMenuTitle();
     }
     $this->assign('opt', $optn);
     $this->assign('login', $loginn);
     if ($db['connected'] == true) {
         $this->assign('sys_dbconnected', true);
     } else {
         $this->assign('sys_dbconnected', false);
     }
     $this->assign('sys_dbslave', $db['slave_id'] != -1);
     if ($this->template_exists($this->name . '.tpl')) {
         $this->assign('template', $this->name);
     } else {
         if ($this->name != 'sys_error') {
             $this->error(ERROR_TEMPLATE_NOT_FOUND);
         }
     }
     $this->bench->stop();
     $this->assign('sys_runtime', $this->bench->diff());
     // check if the template is compiled
     // if not, check if translation works correct
     $_smarty_compile_path = $this->_get_compile_path($this->name);
     if (!$this->_is_compiled($this->name, $_smarty_compile_path) && $this->name != 'error') {
         $internal_lang = $translate->t('INTERNAL_LANG', 'all', 'OcSmarty.class.php', '');
         if ($internal_lang != $opt['template']['locale'] && $internal_lang != 'INTERNAL_LANG') {
             $this->error(ERROR_COMPILATION_FAILED);
         }
     }
     if ($this->is_cached() == true) {
         $this->assign('sys_cached', true);
     } else {
         $this->assign('sys_cached', false);
     }
     $this->assignFeeds();
     if (($opt['debug'] & DEBUG_SQLDEBUGGER) == DEBUG_SQLDEBUGGER) {
         parent::fetch($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
         $this->clear_all_assign();
         $this->main_template = 'sys_sqldebugger';
         $this->assign('commands', $sqldebugger->getCommands());
         $this->assign('cancel', $sqldebugger->getCancel());
         unset($sqldebugger);
         $this->assign('opt', $optn);
         $this->assign('login', $loginn);
         $this->caching = false;
         // unset sqldebugger to allow proper translation of sqldebugger template
         $opt['debug'] = $opt['debug'] & ~DEBUG_SQLDEBUGGER;
         $this->header();
         parent::display($this->main_template . '.tpl');
     } else {
         $this->header();
         parent::display($this->main_template . '.tpl', $this->get_cache_id(), $this->get_compile_id());
     }
     exit;
 }
Пример #5
0
<?php

/***************************************************************************
 *  For license information see doc/license.txt
 *
 *  Unicode Reminder メモ
 ***************************************************************************/
// try to include cache file
if (!file_exists($opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php')) {
    labels::CreateCacheFile();
}
require $opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php';
class labels
{
    static $aLabels = array();
    static function CreateCacheFile()
    {
        global $opt;
        $f = fopen($opt['rootpath'] . 'cache2/labels-' . $opt['template']['locale'] . '.inc.php', 'w');
        fwrite($f, "<?php\n");
        $a = array();
        $rs = sql("SELECT `cache_attrib`.`id`, IFNULL(`sys_trans_text`.`text`, `cache_attrib`.`name`) AS `name`\n\t\t             FROM `cache_attrib`\n\t\t        LEFT JOIN `sys_trans` ON `cache_attrib`.`trans_id`=`sys_trans`.`id` AND `cache_attrib`.`name`=`sys_trans`.`text`\n\t\t        LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'", $opt['template']['locale']);
        while ($r = sql_fetch_assoc($rs)) {
            $a[$r['id']] = $r['name'];
        }
        sql_free_result($rs);
        fwrite($f, 'labels::addLabels("cache_attrib", "' . str_replace('"', '\\"', serialize($a)) . '");' . "\n");
        $a = array();
        $rs = sql("SELECT `cache_size`.`id`, IFNULL(`sys_trans_text`.`text`, `cache_size`.`name`) AS `name`\n\t\t             FROM `cache_size`\n\t\t        LEFT JOIN `sys_trans` ON `cache_size`.`trans_id`=`sys_trans`.`id` AND `cache_size`.`name`=`sys_trans`.`text`\n\t\t        LEFT JOIN `sys_trans_text` ON `sys_trans`.`id`=`sys_trans_text`.`trans_id` AND `sys_trans_text`.`lang`='&1'", $opt['template']['locale']);
        while ($r = sql_fetch_assoc($rs)) {
            $a[$r['id']] = $r['name'];
Пример #6
0
function get_archive_data($caches)
{
    $cachelist = "(" . implode(",", $caches) . ")";
    $data = array();
    $admins = array();
    // make waypoint index
    $rs = sql("SELECT `cache_id`, `wp_oc` FROM `caches` WHERE `cache_id` IN " . $cachelist);
    while ($r = sql_fetch_assoc($rs)) {
        $wp_oc[$r['cache_id']] = $r['wp_oc'];
    }
    sql_free_result($rs);
    // cache coordinates
    $rs = sql("SELECT\n            `cache_id`,\n            LEFT(`date_created`,10) AS `date_modified`,\n            `longitude`,\n            `latitude`,\n            `restored_by`\n        FROM `cache_coordinates`\n        WHERE `cache_id` IN " . $cachelist . "\n        ORDER BY `date_created` ASC");
    // order is relevant, because multiple changes per day possible
    $lastcoord = array();
    while ($r = sql_fetch_assoc($rs)) {
        $coord = new coordinate($r['latitude'], $r['longitude']);
        $coord = $coord->getDecimalMinutes();
        $coord = $coord['lat'] . " " . $coord['lon'];
        if (isset($lastcoord[$r['cache_id']]) && $coord != $lastcoord[$r['cache_id']]) {
            // the database contains lots of old coord records with unchanged coords, wtf?
            append_data($data, $admins, $wp_oc, $r, "coord", $lastcoord[$r['cache_id']], $coord);
        }
        $lastcoord[$r['cache_id']] = $coord;
    }
    sql_free_result($rs);
    // cache country
    $rs = sql("SELECT `cache_id`, LEFT(`date_created`,10) AS `date_modified`, `country`, `restored_by`\n               FROM `cache_countries`\n                         WHERE `cache_id` IN " . $cachelist . "\n                         ORDER BY `date_created` ASC");
    // order is relevant, because multiple changes per day possible
    $lastcountry = array();
    while ($r = sql_fetch_assoc($rs)) {
        if (isset($lastcountry[$r['cache_id']]) && $r['country'] != $lastcountry[$r['cache_id']]) {
            // the database contains some old country records with unchanged coords, wtf?
            append_data($data, $admins, $wp_oc, $r, "country", $lastcountry[$r['cache_id']], $r['country']);
        }
        $lastcountry[$r['cache_id']] = $r['country'];
    }
    sql_free_result($rs);
    // all other cache data
    // first the current data ...
    $nextcd = array();
    $rs = sql("SELECT * FROM `caches` WHERE `cache_id` IN " . $cachelist);
    while ($r = sql_fetch_assoc($rs)) {
        $nextcd[$r['wp_oc']] = $r;
        $user_id = $r['user_id'];
        // is used later for logs
    }
    sql_free_result($rs);
    // .. and then the changes
    $rs = sql("SELECT * FROM `caches_modified`\n        WHERE `cache_id` IN " . $cachelist . "\n        ORDER BY `date_modified` DESC");
    while ($r = sql_fetch_assoc($rs)) {
        $wp = $wp_oc[$r['cache_id']];
        if ($r['name'] != $nextcd[$wp]['name']) {
            append_data($data, $admins, $wp_oc, $r, "name", $r['name'], $nextcd[$wp]['name']);
        }
        if ($r['type'] != $nextcd[$wp]['type']) {
            append_data($data, $admins, $wp_oc, $r, "type", labels::getLabelValue('cache_type', $r['type']), labels::getLabelValue('cache_type', $nextcd[$wp]['type']));
        }
        if ($r['size'] != $nextcd[$wp]['size']) {
            append_data($data, $admins, $wp_oc, $r, "size", labels::getLabelValue('cache_size', $r['size']), labels::getLabelValue('cache_size', $nextcd[$wp]['size']));
        }
        if ($r['difficulty'] != $nextcd[$wp]['difficulty']) {
            append_data($data, $admins, $wp_oc, $r, "D", $r['difficulty'] / 2, $nextcd[$wp]['difficulty'] / 2);
        }
        if ($r['terrain'] != $nextcd[$wp]['terrain']) {
            append_data($data, $admins, $wp_oc, $r, "T", $r['terrain'] / 2, $nextcd[$wp]['terrain'] / 2);
        }
        if ($r['search_time'] != $nextcd[$wp]['search_time']) {
            append_data($data, $admins, $wp_oc, $r, "time", $r['search_time'] . '&nbsp;h', $nextcd[$wp]['search_time'] . '&nbsp;h');
        }
        if ($r['way_length'] != $nextcd[$wp]['way_length']) {
            append_data($data, $admins, $wp_oc, $r, "way", $r['way_length'] . '&nbsp;km', $nextcd[$wp]['way_length'] . '&nbsp;km');
        }
        if ($r['wp_gc'] != $nextcd[$wp]['wp_gc']) {
            append_data($data, $admins, $wp_oc, $r, "GC ", format_wp($r['wp_gc']), format_wp($nextcd[$wp]['wp_gc']));
        }
        if ($r['wp_nc'] != $nextcd[$wp]['wp_nc']) {
            append_data($data, $admins, $wp_oc, $r, "GC ", format_wp($r['wp_nc']), format_wp($nextcd[$wp]['wp_nc']));
        }
        if ($r['date_hidden'] != $nextcd[$wp]['date_hidden']) {
            append_data($data, $admins, $wp_oc, $r, "hidden", $r['date_hidden'], $nextcd[$wp]['date_hidden']);
        }
        $nextcd[$wp] = $r;
    }
    sql_free_result($rs);
    // attributes
    $rs = sql("SELECT * FROM `caches_attributes_modified`\n         WHERE `cache_id` IN " . $cachelist . "  /* OConly attrib is shown, but not restorable */\n         ORDER BY `date_modified` ASC");
    // order doesn't matter as long it is date only
    while ($r = sql_fetch_assoc($rs)) {
        append_data($data, $admins, $wp_oc, $r, "attrib", ($r['was_set'] ? "-" : "+") . labels::getLabelValue('cache_attrib', $r['attrib_id']), '');
    }
    sql_free_result($rs);
    // descriptions
    // first the current data ...
    $nextdesc = array();
    $rs = sql("SELECT\n            `cache_id`,\n            `language`,\n            LENGTH(`desc`) AS `dl`,\n            LENGTH(`hint`) AS `hl`,\n            LENGTH(`short_desc`) AS `sdl`\n        FROM `cache_desc`\n        WHERE `cache_id` IN " . $cachelist);
    while ($r = sql_fetch_assoc($rs)) {
        if (!isset($nextdesc[$r['cache_id']])) {
            $nextdesc[$r['cache_id']] = [];
        }
        $nextdesc[$r['cache_id']][$r['language']] = $r;
    }
    sql_free_result($rs);
    // ... and then the changes
    $rs = sql("SELECT\n            `cache_id`,\n            `date_modified`,\n            `language`,\n            LENGTH(`desc`) AS `dl`,\n            LENGTH(`hint`) AS `hl`,\n            LENGTH(`short_desc`) AS `sdl`,\n            `restored_by`\n        FROM `cache_desc_modified`\n        WHERE `cache_id` IN " . $cachelist . "\n        ORDER BY `date_modified` DESC");
    // order doesn't matter as long only one change per day is recorded
    while ($r = sql_fetch_assoc($rs)) {
        $wp = $wp_oc[$r['cache_id']];
        if (!isset($nextdesc[$r['cache_id']]) || !isset($nextdesc[$r['cache_id']][$r['language']])) {
            $next = ['dl' => 0, 'hl' => 0, 'sdl' => 0];
        } else {
            $next = $nextdesc[$r['cache_id']][$r['language']];
        }
        if ($r['dl'] + 0 != $next['dl'] + 0) {
            append_data($data, $admins, $wp_oc, $r, "desc(" . $r['language'] . ")", $r['dl'] + 0, $next['dl'] + 0 . ' bytes');
        }
        if ($r['hl'] + 0 != $next['hl'] + 0) {
            append_data($data, $admins, $wp_oc, $r, "hint(" . $r['language'] . ")", $r['hl'] + 0, $next['hl'] + 0 . ' bytes');
        }
        if ($r['sdl'] + 0 != $next['sdl'] + 0) {
            append_data($data, $admins, $wp_oc, $r, "shortdesc(" . $r['language'] . ")", $r['sdl'] + 0, $next['sdl'] + 0 . ' bytes');
        }
        $nextdesc[$r['cache_id']][$r['language']] = $r;
    }
    sql_free_result($rs);
    // logs
    $rs = sql("SELECT\n            `op`,\n            LEFT(`date_modified`,10) AS `date_modified`,\n            `cache_id`,\n            `logs`.`user_id`,\n            `type`,\n            `date`,\n            `restored_by`,\n            `username`\n        FROM\n              (SELECT 1 AS `op`, `deletion_date` AS `date_modified`, `cache_id`,\n                    `user_id`, `type`, `date`, `restored_by`\n                   FROM `cache_logs_archived`\n                  WHERE `cache_id` IN " . $cachelist . "AND `deleted_by`='&1' AND `user_id`<>'&1'\n                  UNION\n                  SELECT 2 AS `op`, `date_modified`, `cache_id`,\n                       (SELECT `user_id` FROM `cache_logs_archived` WHERE `id`=`original_id`),\n                       (SELECT `type` FROM `cache_logs_archived` WHERE `id`=`original_id`),\n                       (SELECT `date` FROM `cache_logs_archived` WHERE `id`=`original_id`),\n                       `restored_by`\n                 FROM `cache_logs_restored`\n                  WHERE `cache_id` IN " . $cachelist . ") `logs`\n                INNER JOIN `user` ON `user`.`user_id`=`logs`.`user_id`\n              ORDER BY `logs`.`date_modified` ASC", $user_id);
    while ($r = sql_fetch_assoc($rs)) {
        append_data($data, $admins, $wp_oc, $r, $r["op"] == 1 ? "dellog" : "restorelog", "<a href='viewprofile.php?userid=" . $r['user_id'] . "' target='_blank'>" . $r['username'] . "</a>/" . $r['date'], '');
    }
    sql_free_result($rs);
    // pictures
    /* For sake of simplification, we
     *   - have stored the name of inserted pictures in pictures_modified
     *   - give no detailed information on picture property changes. This will be very
     *       rare in case of vandalism ...
     */
    $piccacheid = "IF(`object_type`=2, `object_id`, IF(`object_type`=1, IFNULL((SELECT `cache_id` FROM `cache_logs` WHERE `id`=`object_id`),(SELECT `cache_id` FROM `cache_logs_archived` WHERE `id`=`object_id`)), 0))";
    $rs = sql("SELECT *, " . $piccacheid . "AS `cache_id` FROM `pictures_modified`\n         WHERE " . $piccacheid . " IN " . $cachelist . "\n         ORDER BY `date_modified` ASC");
    // order is relevant for the case of restore-reverts
    while ($r = sql_fetch_assoc($rs)) {
        $r['date_modified'] = substr($r['date_modified'], 0, 10);
        switch ($r['operation']) {
            case 'I':
                $picchange = "add";
                break;
            case 'U':
                $picchange = "mod";
                break;
            case 'D':
                $picchange = "del";
                break;
        }
        switch ($r['object_type']) {
            case 1:
                $picchange .= "-log";
                break;
            case 2:
                $picchange .= "-cache";
                break;
        }
        append_data($data, $admins, $wp_oc, $r, $picchange . "pic", $r['title'], '');
    }
    sql_free_result($rs);
    // admins
    foreach ($admins as $adate => $adata) {
        foreach ($adata as $awp => $alist) {
            $data[$adate][$awp] .= "<br /><strong class='adminrestore'>admins:</strong> " . implode(',', $alist);
        }
    }
    // done
    ksort($data);
    return array_reverse($data, true);
}