/** * Get a splurghified version of the specified item. * * @param string The name of what the key we want to reference is in our array of maps (e.g. 'id') * @param array A row of maps for data we are splurghing; this is probably just the result of $GLOBALS['SITE_DB']->query_select * @param URLPATH The stub that links will be passed through * @param ID_TEXT The page name we will be saving customised HTML under * @param TIME The time we did our last change to the data being splurghed (so it can see if we can simply decache instead of deriving) * @param ?AUTO_LINK The ID that is at the root of our tree (NULL: db_get_first_id) * @return string A string of HTML that represents our splurghing (will desplurgh in the users browser) */ function splurgh_master_build($key_name, $map, $url_stub, $_cache_file, $last_change_time, $first_id = NULL) { if (is_null($first_id)) { $first_id = db_get_first_id(); } if (!array_key_exists($first_id, $map)) { return ''; } if (!has_js()) { warn_exit(do_lang_tempcode('MSG_JS_NEEDED')); } require_javascript('javascript_splurgh'); if (is_browser_decacheing()) { $last_change_time = time(); } $cache_file = zone_black_magic_filterer(get_custom_file_base() . '/' . get_zone_name() . '/pages/html_custom/' . filter_naughty(user_lang()) . '/' . filter_naughty($_cache_file) . '.htm'); if (!file_exists($cache_file) || is_browser_decacheing() || filesize($cache_file) == 0 || $last_change_time > filemtime($cache_file)) { $myfile = @fopen($cache_file, 'wt'); if ($myfile === false) { intelligent_write_error($cache_file); } $fulltable = array(); $splurgh = _splurgh_do_node($map, $first_id, '', $fulltable, 0); $page = do_template('SPLURGH', array('_GUID' => '8775edfc5a386fdf2cec69b0fc889952', 'KEY_NAME' => $key_name, 'URL_STUB' => $url_stub, 'SPLURGH' => str_replace('"', '\'', $splurgh))); $ev = $page->evaluate(); if (fwrite($myfile, $ev) < strlen($ev)) { warn_exit(do_lang_tempcode('COULD_NOT_SAVE_FILE')); } fclose($myfile); fix_permissions($cache_file); sync_file($cache_file); return $ev; } return file_get_contents($cache_file, FILE_TEXT); }
/** * Get the parsed contents of a comcode page. * * @param PATH The relative (to ocPortal's base directory) path to the page (e.g. pages/comcode/EN/start.txt) * @param ID_TEXT The zone the page is being loaded from * @param ID_TEXT The codename of the page * @param ?PATH The file base to load from (NULL: standard) * @param boolean Whether the page is being included from another * @return tempcode The page */ function load_comcode_page($string, $zone, $codename, $file_base = NULL, $being_included = false) { if ($file_base === NULL) { $file_base = get_file_base(); } if (!$being_included) { $GLOBALS['TITLE_CALLED'] = true; } $is_panel = substr($codename, 0, 6) == 'panel_' || strpos($codename, 'panel_') !== false && get_param_integer('keep_theme_test', 0) == 1; if ($zone == '' && $codename == '404') { global $EXTRA_HEAD; $EXTRA_HEAD->attach('<meta name="robots" content="noindex" />'); // XHTMLXHTML $GLOBALS['HTTP_STATUS_CODE'] = '404'; if (!headers_sent()) { if (!browser_matches('ie') && strpos(ocp_srv('SERVER_SOFTWARE'), 'IIS') === false) { header('HTTP/1.0 404 Not Found'); } } } if (($is_panel || $codename[0] == '_') && get_page_name() == $codename) { global $EXTRA_HEAD; $EXTRA_HEAD->attach('<meta name="robots" content="noindex" />'); // XHTMLXHTML } if ($zone == 'adminzone') { require_code('site_adminzone'); adminzone_special_cases($codename); } if ($codename == 'sitemap') { $GLOBALS['FEED_URL'] = find_script('backend') . '?mode=comcode_pages&filter=' . $zone; } global $PAGE_STRING, $COMCODE_PARSE_TITLE, $LAST_COMCODE_PARSED_TITLE; $COMCODE_PARSE_TITLE = NULL; if ($PAGE_STRING === NULL && !$being_included && !$is_panel) { $PAGE_STRING = $string; } $new_comcode_page_row = array('the_zone' => $zone, 'the_page' => $codename, 'p_parent_page' => '', 'p_validated' => 1, 'p_edit_date' => NULL, 'p_add_date' => NULL, 'p_submitter' => NULL, 'p_show_as_edit' => 0); if ((get_option('is_on_comcode_page_cache') == '1' || get_param_integer('keep_cache', 0) == 1 || get_param_integer('cache', 0) == 1 || get_param_integer('cache_blocks', 0) == 1) && get_param_integer('keep_cache', NULL) !== 0 && get_param_integer('cache_blocks', NULL) !== 0 && get_param_integer('cache', NULL) !== 0 && get_param_integer('keep_print', 0) == 0) { global $SITE_INFO; $support_smart_decaching = !isset($SITE_INFO['disable_smart_decaching']) || $SITE_INFO['disable_smart_decaching'] == '0'; if (is_browser_decacheing()) { $comcode_page = $GLOBALS['SITE_DB']->query_select('cached_comcode_pages', array('string_index', 'cc_page_title'), array('the_page' => $codename, 'the_zone' => $zone, 'the_theme' => $GLOBALS['FORUM_DRIVER']->get_theme()), '', 1, 0, false, array()); if (array_key_exists(0, $comcode_page)) { if ($comcode_page[0]['string_index'] !== NULL) { delete_lang($comcode_page[0]['string_index']); } $GLOBALS['SITE_DB']->query_delete('cached_comcode_pages', array('the_page' => $codename, 'the_zone' => $zone)); } } $theme = $GLOBALS['FORUM_DRIVER']->get_theme(); if ($GLOBALS['MEM_CACHE'] !== NULL) { if ($support_smart_decaching) { $mtime = filemtime($file_base . '/' . $string); if ($mtime > time()) { $mtime = time(); } // Timezone error, we have to assume that cache is ok rather than letting us get in a loop decacheing the file. It'll get fixed automatically in a few hours when the hours of the timezone difference passes. $pcache = persistant_cache_get(array('COMCODE_PAGE', $codename, $zone, $theme, user_lang()), $mtime); } else { $pcache = persistant_cache_get(array('COMCODE_PAGE', $codename, $zone, $theme, user_lang())); } } else { $pcache = NULL; } if ($pcache === NULL) { $comcode_page = $GLOBALS['SITE_DB']->query_select('cached_comcode_pages a JOIN ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'comcode_pages b ON (a.the_page=b.the_page AND a.the_zone=b.the_zone)', array('*'), array('a.the_page' => $codename, 'a.the_zone' => $zone, 'the_theme' => $theme), '', 1, NULL, false, array('string_index', 'cc_page_title')); if (array_key_exists(0, $comcode_page)) { if ($support_smart_decaching) { $mtime = filemtime($file_base . '/' . $string); if ($mtime > time()) { $mtime = time(); } // Timezone error, we have to assume that cache is ok rather than letting us get in a loop decacheing the file. It'll get fixed automatically in a few hours when the hours of the timezone difference passes. } if (!$support_smart_decaching || ($comcode_page[0]['p_edit_date'] !== NULL && $comcode_page[0]['p_edit_date'] >= $mtime || $comcode_page[0]['p_edit_date'] === NULL && $comcode_page[0]['p_add_date'] !== NULL && $comcode_page[0]['p_add_date'] >= $mtime)) { $comcode_page_row = $comcode_page[0]; $db_set = get_translated_tempcode($comcode_page[0]['string_index'], NULL, user_lang(), true, true, true); unset($GLOBALS['RECORDED_LANG_STRINGS_CONTENT'][$comcode_page[0]['string_index']]); } else { $mtime = filemtime($file_base . '/' . $string); if ($mtime > time()) { $mtime = time(); } // Timezone error, we have to assume that cache is ok rather than letting us get in a loop decacheing the file. It'll get fixed automatically in a few hours when the hours of the timezone difference passes. $GLOBALS['SITE_DB']->query_update('comcode_pages', array('p_edit_date' => $mtime), array('the_page' => $codename, 'the_zone' => $zone), '', 1); $GLOBALS['SITE_DB']->query_delete('cached_comcode_pages', array('the_zone' => $zone, 'the_page' => $codename)); delete_lang($comcode_page[0]['string_index']); $db_set = NULL; $comcode_page_row = NULL; } } else { $db_set = NULL; $comcode_page_row = NULL; } if ($db_set !== NULL) { $index = $comcode_page[0]['string_index']; $title_to_use = $comcode_page[0]['cc_page_title']; if ($title_to_use !== NULL) { $title_to_use = get_translated_text($title_to_use, NULL, NULL, true); if ($title_to_use === NULL) { $title_to_use = $codename; } } $html = $db_set; } else { $comcode_page = $GLOBALS['SITE_DB']->query_select('comcode_pages', array('*'), array('the_page' => $codename, 'the_zone' => $zone), '', 1); if (array_key_exists(0, $comcode_page)) { $comcode_page_row = $comcode_page[0]; } require_code('site2'); $new_comcode_page_row['p_add_date'] = filectime($file_base . '/' . $string); list($html, $title_to_use, $comcode_page_row) = _load_comcode_page_not_cached($string, $zone, $codename, $file_base, $comcode_page_row, $new_comcode_page_row, $being_included); } persistant_cache_set(array('COMCODE_PAGE', $codename, $zone, $theme, user_lang()), array($html, $title_to_use, $comcode_page_row)); } else { list($html, $title_to_use, $comcode_page_row) = $pcache; } } else { require_code('site2'); $new_comcode_page_row['p_add_date'] = filectime($file_base . '/' . $string); list($html, $comcode_page_row, $title_to_use) = _load_comcode_page_cache_off($string, $zone, $codename, $file_base, $new_comcode_page_row, $being_included); } $filtered_title_to_use = mixed(); if (!$is_panel && !$being_included) { if ($title_to_use !== NULL && $title_to_use != '') { get_page_title($title_to_use, false); // Little hack - this gets shift encoded, but shift encoding can't survive a tempcode cache. This will force it to reshift. It'll also make sure DISPLAYED_TITLE gets set. $filtered_title_to_use = @html_entity_decode(strip_tags($title_to_use), ENT_QUOTES, get_charset()); } seo_meta_load_for('comcode_page', $zone . ':' . $codename, $filtered_title_to_use); } $LAST_COMCODE_PARSED_TITLE = $title_to_use; if ($html->is_definitely_empty() && $being_included) { return $html; } if (has_actual_page_access(get_member(), 'cms_comcode_pages', NULL, NULL, $comcode_page_row['p_submitter'] == get_member() && !is_guest() ? 'edit_own_highrange_content' : 'edit_highrange_content')) { $redirect = get_self_url(true, false, array('redirect' => NULL, 'redirected' => NULL)); if (($codename == 'panel_left' || $codename == 'panel_right') && has_js() && has_actual_page_access(get_member(), 'admin_zones')) { $edit_url = build_url(array('page' => 'admin_zones', 'type' => '_editor', 'id' => get_zone_name(), 'redirect' => $redirect, 'wide' => 1), get_module_zone('admin_zones')); } else { $edit_url = build_url(array('page' => 'cms_comcode_pages', 'type' => '_ed', 'page_link' => $zone . ':' . $codename, 'redirect' => $redirect), get_module_zone('cms_comcode_pages')); } $add_child_url = get_option('is_on_comcode_page_children') == '1' ? build_url(array('page' => 'cms_comcode_pages', 'type' => '_ed', 'parent_page' => $codename, 'page_link' => $zone . ':'), get_module_zone('cms_comcode_pages')) : new ocp_tempcode(); } else { $edit_url = new ocp_tempcode(); $add_child_url = new ocp_tempcode(); } $warning_details = new ocp_tempcode(); if ($comcode_page_row['p_validated'] !== NULL && $comcode_page_row['p_validated'] == 0) { require_code('site2'); $warning_details = get_page_warning_details($zone, $codename, $edit_url); } if (!$is_panel && $title_to_use !== NULL && !$being_included) { global $PT_PAIR_CACHE_CP; $PT_PAIR_CACHE_CP[$codename]['cc_page_title'] = $title_to_use === NULL ? do_lang_tempcode('NA_EM') : make_string_tempcode($title_to_use); $PT_PAIR_CACHE_CP[$codename]['p_parent_page'] = $comcode_page_row['p_parent_page']; $comcode_breadcrumbs = comcode_breadcrumbs($codename, $zone, get_param('root', ''), $comcode_page_row['p_parent_page'] == '' || !has_specific_permission(get_member(), 'open_virtual_roots')); breadcrumb_add_segment($comcode_breadcrumbs); $GLOBALS['META_DATA'] += array('created' => date('Y-m-d', $comcode_page_row['p_add_date']), 'creator' => is_guest($comcode_page_row['p_submitter']) ? '' : $GLOBALS['FORUM_DRIVER']->get_username($comcode_page_row['p_submitter']), 'publisher' => '', 'modified' => $comcode_page_row['p_edit_date'] === NULL ? '' : date('Y-m-d', $comcode_page_row['p_edit_date']), 'type' => 'Comcode page', 'title' => $title_to_use, 'identifier' => $zone . ':' . $codename, 'description' => ''); } if ($html->is_definitely_empty() && $is_panel) { return $html; } global $SCREEN_TEMPLATE_CALLED; $st = $SCREEN_TEMPLATE_CALLED; $ret = do_template('COMCODE_PAGE_SCREEN', array('_GUID' => '0fc4fe4f27e54aaaa2b7e4848c02bacb', 'IS_PANEL' => $is_panel, 'BEING_INCLUDED' => $being_included, 'SUBMITTER' => strval($comcode_page_row['p_submitter']), 'TAGS' => get_loaded_tags('comcode_pages'), 'WARNING_DETAILS' => $warning_details, 'EDIT_DATE_RAW' => $comcode_page_row['p_edit_date'] === NULL ? '' : strval($comcode_page_row['p_edit_date']), 'SHOW_AS_EDIT' => $comcode_page_row['p_show_as_edit'] == 1, 'CONTENT' => $html, 'EDIT_URL' => $edit_url, 'ADD_CHILD_URL' => $add_child_url, 'NAME' => $codename)); if ($is_panel || $being_included) { $SCREEN_TEMPLATE_CALLED = $st; } return $ret; }
/** * This function is an offshoot of get_translated_text, it instead returns parsed comcode that is linked to the specified language id. * * @param integer The id * @param ?object The database connection to use (NULL: standard site connection) * @param ?LANGUAGE_NAME The language (NULL: uses the current language) * @param boolean Whether to force it to the specified language * @param boolean Whether to force as_admin, even if the lang string isn't stored against an admin (designed for comcode page cacheing) * @param boolean Whether to remove from the Tempcode cache when we're done, for performance reasons (normally don't bother with this, but some code knows it won't be needed again -- esp Comcode cache layer -- and saves RAM by removing it) * @return ?tempcode The parsed comcode (NULL: the text couldn't be looked up) */ function get_translated_tempcode($entry, $connection = NULL, $lang = NULL, $force = false, $as_admin = false, $clear_away_from_cache = false) { if ($entry == 0) { return paragraph(do_lang_tempcode('FAILED_ENTRY'), 'rtgtedgrgd'); } if ($connection === NULL) { $connection = $GLOBALS['SITE_DB']; } global $RECORD_LANG_STRINGS_CONTENT; if ($RECORD_LANG_STRINGS_CONTENT) { global $RECORDED_LANG_STRINGS_CONTENT; $RECORDED_LANG_STRINGS_CONTENT[$entry] = $connection->connection_write != $GLOBALS['SITE_DB']->connection_write; } if ($lang === NULL) { $lang = user_lang(); } if ($lang == 'xxx') { return make_string_tempcode('!!!'); } // Helpful for testing language compliancy. We don't expect to see non x's/!'s if we're running this language if (isset($connection->text_lookup_cache[$entry]) && $lang == user_lang()) { $ret = $connection->text_lookup_cache[$entry]; if ($ret !== '') { if (is_string($ret)) { $connection->text_lookup_cache[$entry] = new ocp_tempcode(); $connection->text_lookup_cache[$entry]->from_assembly($ret); $ret = $connection->text_lookup_cache[$entry]; } if ($clear_away_from_cache) { unset($connection->text_lookup_cache[$entry]); unset($connection->text_lookup_original_cache[$entry]); } return $ret; } } global $SEARCH__CONTENT_BITS; if ($SEARCH__CONTENT_BITS !== NULL) { $_result = $connection->query_select('translate', array('text_original', 'source_user'), array('id' => $entry, 'language' => $lang), '', 1); if (array_key_exists(0, $_result)) { global $LAX_COMCODE; $temp = $LAX_COMCODE; $LAX_COMCODE = true; $result = $_result[0]; $ret = comcode_to_tempcode($result['text_original'], $result['source_user'], $as_admin, 60, NULL, $connection, false, false, false, false, false, $SEARCH__CONTENT_BITS); $LAX_COMCODE = $temp; return $ret; } } $_result = $connection->query_select('translate', array('text_parsed', 'text_original'), array('id' => $entry, 'language' => $lang), '', 1); $result = isset($_result[0]) ? $_result[0]['text_parsed'] : NULL; if (isset($_result[0])) { if ($lang == user_lang()) { $connection->text_lookup_original_cache[$entry] = $_result[0]['text_original']; } } if ($result === NULL || $result == '' || is_browser_decacheing()) { require_code('lang3'); return parse_translated_text($entry, $connection, $lang, $force, $as_admin); } $parsed = new ocp_tempcode(); if (!$parsed->from_assembly($result, true)) { require_code('lang3'); return parse_translated_text($entry, $connection, $lang, $force, $as_admin); } if ($lang == user_lang()) { $connection->text_lookup_cache[$entry] = $parsed; } return $parsed; }
/** * Force a CSS file to be cached. * * @param string The CSS file required * @param ?ID_TEXT The name of the theme (NULL: current theme) * @param ?boolean Whether to minify (NULL: read from environment) * @return string The path to the CSS file in the cache (blank: no file) */ function css_enforce($c, $theme = NULL, $minify = NULL) { $text_only = get_param_integer('keep_textonly', 0) == 1; if ($text_only) { $c .= '_textonly'; } if ($minify === NULL) { $minify = get_param_integer('keep_no_minify', 0) == 0; } global $SITE_INFO; // Make sure the CSS file exists if ($theme === NULL) { $theme = @method_exists($GLOBALS['FORUM_DRIVER'], 'get_theme') ? $GLOBALS['FORUM_DRIVER']->get_theme() : 'default'; } $active_theme = $theme; $dir = get_custom_file_base() . '/themes/' . $theme . '/templates_cached/' . filter_naughty(user_lang()); if (!isset($SITE_INFO['no_disk_sanity_checks']) || $SITE_INFO['no_disk_sanity_checks'] == '0') { if (!is_dir($dir)) { if (@mkdir($dir, 0777) === false) { warn_exit(do_lang_tempcode('WRITE_ERROR_DIRECTORY_REPAIR', escape_html($dir))); } fix_permissions($dir, 0777); sync_file($dir); } } $css_cache_path = $dir . '/' . filter_naughty_harsh($c); if (!$minify) { $css_cache_path .= '_non_minified'; } if (get_option('enable_https', true) == '1' && function_exists('is_page_https') && function_exists('get_zone_name') && (tacit_https() || is_page_https(get_zone_name(), get_page_name()))) { $css_cache_path .= '_ssl'; } if (is_mobile()) { $css_cache_path .= '_mobile'; } $css_cache_path .= '.css'; global $CACHE_TEMPLATES; $support_smart_decaching = !isset($SITE_INFO['disable_smart_decaching']) || $SITE_INFO['disable_smart_decaching'] == '0'; $is_cached = ($CACHE_TEMPLATES || !running_script('index')) && @(filesize($css_cache_path) != 0) && !is_browser_decacheing() && !in_safe_mode(); if ($support_smart_decaching || !$is_cached || $text_only) { $found = find_template_place($c, '', $theme, '.css', 'css'); if ($found === NULL) { return ''; } $theme = $found[0]; $fullpath = get_custom_file_base() . '/themes/' . $theme . $found[1] . $c . '.css'; if (!is_file($fullpath)) { $fullpath = get_file_base() . '/themes/' . $theme . $found[1] . $c . '.css'; } if ($text_only && !is_file($fullpath)) { return ''; } } if (!$is_cached || $support_smart_decaching && (@(filemtime($css_cache_path) < filemtime($fullpath)) && @filemtime($fullpath) < time())) { require_code('css_and_js'); css_compile($active_theme, $theme, $c, $fullpath, $css_cache_path, $minify); } if (@filesize($css_cache_path) == 0) { return ''; } return $css_cache_path; }
/** * Convert a language string that is Comcode to tempcode, with potential cacheing in the db. * * @param ID_TEXT The language string ID * @return tempcode The parsed Comcode */ function _comcode_lang_string($lang_code) { global $COMCODE_LANG_STRING_CACHE; if (array_key_exists($lang_code, $COMCODE_LANG_STRING_CACHE)) { return $COMCODE_LANG_STRING_CACHE[$lang_code]; } $comcode_page = $GLOBALS['SITE_DB']->query_select('cached_comcode_pages p LEFT JOIN ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'translate t ON t.id=string_index AND ' . db_string_equal_to('t.language', user_lang()), array('string_index', 'text_parsed'), array('the_page' => $lang_code, 'the_zone' => '!'), '', 1); if (array_key_exists(0, $comcode_page) && !is_browser_decacheing()) { if (!is_null($comcode_page[0]['text_parsed']) && $comcode_page[0]['text_parsed'] != '') { $parsed = new ocp_tempcode(); if (!$parsed->from_assembly($comcode_page[0]['text_parsed'], true)) { $ret = get_translated_tempcode($comcode_page[0]['string_index']); unset($GLOBALS['RECORDED_LANG_STRINGS_CONTENT'][$comcode_page[0]['string_index']]); } } else { $ret = get_translated_tempcode($comcode_page[0]['string_index'], NULL, NULL, true); if (is_null($ret)) { $looked_up = do_lang($lang_code, NULL, NULL, NULL, NULL, false); $GLOBALS['SITE_DB']->query_insert('translate', array('id' => $comcode_page[0]['string_index'], 'source_user' => get_member(), 'broken' => 0, 'importance_level' => 1, 'text_original' => $looked_up, 'text_parsed' => '', 'language' => user_lang()), true, false, true); $ret = get_translated_tempcode($comcode_page[0]['string_index']); } unset($GLOBALS['RECORDED_LANG_STRINGS_CONTENT'][$comcode_page[0]['string_index']]); return $ret; } $COMCODE_LANG_STRING_CACHE[$lang_code] = $parsed; return $parsed; } elseif (array_key_exists(0, $comcode_page)) { $GLOBALS['SITE_DB']->query_delete('cached_comcode_pages', array('the_page' => $lang_code, 'the_zone' => '!')); delete_lang($comcode_page[0]['string_index']); } $nql_backup = $GLOBALS['NO_QUERY_LIMIT']; $GLOBALS['NO_QUERY_LIMIT'] = true; $looked_up = do_lang($lang_code, NULL, NULL, NULL, NULL, false); if (is_null($looked_up)) { return make_string_tempcode(escape_html('{!' . $lang_code . '}')); } $index = insert_lang_comcode($looked_up, 4, NULL, true, NULL, 60, false, true); $GLOBALS['SITE_DB']->query_insert('cached_comcode_pages', array('the_zone' => '!', 'the_page' => $lang_code, 'string_index' => $index, 'the_theme' => $GLOBALS['FORUM_DRIVER']->get_theme(), 'cc_page_title' => NULL), false, true); // Race conditions $parsed = get_translated_tempcode($index); $COMCODE_LANG_STRING_CACHE[$lang_code] = $parsed; $GLOBALS['NO_QUERY_LIMIT'] = $nql_backup; return $parsed; }