Commit 0c94d108 authored by Chris Graham's avatar Chris Graham
Browse files

Fixed MANTIS-4511 (Fix Cron block caching)

parent cae8fee5
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -662,6 +662,7 @@ We have the following which are either unlikely to be useful, or potentially uns
  - [tt]flush_cache_on_action[/tt] -- set this to '1' to automatically flush the static cache when actions are performed
  - [tt]allow_admin_in_other_zones[/tt] -- set this to '1' if you want to allow admin and CMS modules to run in other zones (small performance cost)
  - [tt]memory_limit_simulate_hard[/tt] -- set this to '1' if you do not want the memory limit to be disableable; useful for testing compatibility with hosts that have low limits
  - [tt]cron_block_caching_careful_contexts[/tt] -- set this to '1' if you want Cron generated block-caching to use the requested theme and language to fill the cache; this requires loopback HTTP requests
 - Easter eggs
  - [tt]stupidity_mode[/tt] -- set to [tt]leet[/tt] or [tt]bork[/tt], for a fun April Fools-style Comcode joke (clear the Comcode cache after you're done though)
 - Experimental functionality
+1 −1
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ function request_via_cron($codename, $map, $special_cache_flags, $tempcode)
        'c_codename' => $codename,
        'c_map' => serialize($map),
        'c_staff_status' => (($special_cache_flags & CACHE_AGAINST_STAFF_STATUS) != 0) ? $GLOBALS['FORUM_DRIVER']->is_staff(get_member()) : null,
        'c_member' => (($special_cache_flags & CACHE_AGAINST_BOT_STATUS) != 0) ? get_member() : null,
        'c_member' => (($special_cache_flags & CACHE_AGAINST_MEMBER) != 0) ? get_member() : null,
        'c_groups' => (($special_cache_flags & CACHE_AGAINST_PERMISSIVE_GROUPS) != 0) ? permissive_groups_cache_signature() : '',
        'c_is_bot' => (($special_cache_flags & CACHE_AGAINST_BOT_STATUS) != 0) ? (is_null(get_bot_type()) ? 0 : 1) : null,
        'c_timezone' => (($special_cache_flags & CACHE_AGAINST_TIMEZONE) != 0) ? get_users_timezone(get_member()) : '',
+67 −37
Original line number Diff line number Diff line
@@ -28,42 +28,71 @@ class Hook_cron_block_caching
     */
    public function run()
    {
        $test = $GLOBALS['SITE_DB']->query_select_value_if_there('cron_caching_requests', 'c_theme');
        if ($test === null) {
        if (get_value('cron_block_caching_careful_contexts') === '1') {
            $request_contexts = $GLOBALS['SITE_DB']->query('SELECT DISTINCT c_theme,c_lang FROM ' . get_table_prefix() . 'cron_caching_requests');
            if (empty($request_contexts)) {
                return;
            }

        if ((get_param_string('keep_lang', null) === null) || (get_param_string('keep_theme', null) === null)) {
            // We need to run this for each language and for each theme
            $langs = find_all_langs();
            require_code('themes2');
            $themes = find_all_themes();
            foreach (array_keys($langs) as $lang) {
                foreach (array_keys($themes) as $theme) {
                    if (($theme == 'default') || (has_category_access(get_member(), 'theme', $theme))) {

            // Remove anything tied to a context that no longer exists
            foreach ($request_contexts as $i => $request_context) {
                $lang = $request_context['c_lang'];
                $theme = $request_context['c_theme'];

                if ((!isset($langs[$lang])) || (!isset($themes[$theme]))) {
                    unset($request_contexts[$i]);
                    $GLOBALS['SITE_DB']->query_delete('cron_caching_requests', array('c_theme' => $theme, 'c_lang' => $lang));
                }
            }

            if ((get_param_string('keep_lang', null) === null) || (get_param_string('keep_theme', null) === null)) {
                // We need to recurse into a new call for each context (language and theme combination)
                $done_something = false;
                $more_to_do = false;
                foreach ($request_contexts as $request_context) {
                    $lang = $request_context['c_lang'];
                    $theme = $request_context['c_theme'];

                    if (($theme != $GLOBALS['FORUM_DRIVER']->get_theme()) || ($lang != user_lang())) {
                        $where = array('c_theme' => $theme, 'c_lang' => $lang);
                        $count = $GLOBALS['SITE_DB']->query_select_value('cron_caching_requests', 'COUNT(*)', $where);
                        if ($count > 0) {
                            $url = get_base_url() . '/data/cron_bridge.php?limit_hook=block_caching&keep_lang=' . urlencode($lang) . '&keep_theme=' . urlencode($theme);
                            http_download_file($url, null, false);
                        }
                            $url = get_base_url() . '/data/cron_bridge.php?limit_hook=block_caching&keep_lang=' . urlencode($lang) . '&keep_theme=' . urlencode($theme) . '&force=1';
                            http_download_file($url, null, false, false, 'Composr', null, null, null, null, null, null, null, null, 180.0);
                            $done_something = true;
                        }
                    } else {
                        $more_to_do = true;
                    }
                }

                // Force re-loading of values that we use to mark progress (as above calls probably resulted in changes happening)
                if ($done_something) {
                    global $VALUE_OPTIONS_CACHE;
                    $VALUE_OPTIONS_CACHE = $GLOBALS['SITE_DB']->query_select('values', array('*'));
                    $VALUE_OPTIONS_CACHE = list_to_map('the_name', $VALUE_OPTIONS_CACHE);
                }

                if (!$more_to_do) {
                    return;
                }
            }

            $where = array('c_theme' => $GLOBALS['FORUM_DRIVER']->get_theme(), 'c_lang' => user_lang());
        $requests = $GLOBALS['SITE_DB']->query_select('cron_caching_requests', array('*'), $where);
        foreach ($requests as $request) {
        } else {
            $where = array();
        }

        // Execute all in current context...

        $GLOBALS['NO_QUERY_LIMIT'] = true;

        $requests = $GLOBALS['SITE_DB']->query_select('cron_caching_requests', array('*'), $where);
        foreach ($requests as $request) {
            $codename = $request['c_codename'];
            $map = unserialize($request['c_map']);

@@ -97,28 +126,29 @@ class Hook_cron_block_caching
                    }
                    $ttl = $info['ttl'];

                    $_cache_identifier = array();
                    $cache_on = $info['cache_on'];
                    if (is_array($cache_on)) {
                        $_cache_identifier = call_user_func($cache_on[0], $map);
                    } else {
                        if ($cache_on != '') {
                            $_cache_on = eval('return ' . $cache_on . ';'); // NB: This uses $map, as $map is referenced inside $cache_on
                            if (is_null($_cache_on)) {
                                return null;
                            }
                            foreach ($_cache_on as $on) {
                                $_cache_identifier[] = $on;
                            }
                        }
                    }
                    $cache_identifier = serialize($_cache_identifier);
                    $cache_identifier = do_block_get_cache_identifier($info['cache_on'], $map);

                    require_code('caches2');
                    if ($request['c_store_as_tempcode'] == 1) {
                        $cache = make_string_tempcode($cache->evaluate());
                    }
                    put_into_cache($codename, $ttl, $cache_identifier, $request['c_staff_status'], $request['c_member'], $request['c_groups'], $request['c_is_bot'], $request['c_timezone'], $cache, array_keys($LANGS_REQUESTED), array_keys($JAVASCRIPTS), array_keys($CSSS), true);
                    put_into_cache(
                        $codename,
                        $ttl,
                        $cache_identifier,
                        $request['c_staff_status'],
                        $request['c_member'],
                        $request['c_groups'],
                        $request['c_is_bot'],
                        $request['c_timezone'],
                        $cache,
                        array_keys($LANGS_REQUESTED),
                        array_keys($JAVASCRIPTS),
                        array_keys($CSSS),
                        true,
                        $request['c_theme'],
                        $request['c_lang']
                    );
                }
                $LANGS_REQUESTED += $backup_langs_requested;
                $REQUIRED_ALL_LANG += $backup_required_all_lang;