Продолжим начатое, но чуть менее затратно.
Суть проста: зачем мы в магазине будем заставлять нам нести продавца все печеньки, если нам не нравятся диетические. В переводе значит, что мы прямо в запросе к БД будем проверять доступность модуля группе юзера, тем самым уменьшая нагрузку и экономя трафик с БД.
Как видно на демо, для главной страницы оптимизированной версии при дефолтной установке делается на 6 запросов к БД меньше, чем стоковой версии. Чтобы это увидеть поменяйте в блоке справа шаблон: "По умолчанию" и "_default_" — это неоптимизированная версия, "new_default" — оптимизированная. На время генерации можете не смотреть — мускул кэширует запросы сам.
Приступим к выполнению ключевого различия с этим.
1. Выполним запросы к БД:2. Файл /admin/applets/modules.php
Найти:Заменить:Найти:Заменить:3. Теперь открываем /core/classes/page.class.php и делаем также немаловажное различие:
после:вставляем:Ну и вновь перед последней закрывающейся скобкой вставляем:4. Ну и наконец в своём шаблоне (файле template.php) меняем countModules на countThisModules и printModules на printThisModules.
В следующий раз мы изменим printThisModules для другого метода кэширования, но можете даже не надеяться на появление этого в дистрибутиве, ибо у разработчиков совершенно иной взгляд на саму задачу кэширования)
Как именно будет кэшироваться? А очень просто: будут создаваться файлы кэша с простым html или же массивом данных. Это будет на усмотрение модуля, да, кешировать себя будет модуль сам, в зависимости от его приватности и каких либо изменений для каждого пользователя. Например модуль форума: в зависимости от доступа, он может отображать разные темы разным группам (по крайней мере в моей доработке =D), а также у каждого конкретного пользователя разные прочтённые темы, поэтому мы не можем просто взять и закэшировать его. У модуля форума будет по одному файлу на каждую группу, в каждом будет массив, который модуль будет перебирать и отмечать прочтённость топика данным конкретным юзером, а потом отдавать смарти. Хм, что же у нас не для разных групп… Ах, да — Лента. У неё будет один файл для всех групп, в котором просто готовый html.
Я не решил как чистить кеш, либо плагином по эвентам, либо классом логирования, благо всё что можно сделать во фронте, отображается в Ленте.
Ещё важный момент с датами: они просто будут окружаться спаном с timestamp, по которому в закэшированом html легко поменять "5 минут назад", на "вчера во столько то" и ещё с помощью яваскрипта можно будет оживить эти самые "n минут назад" на сайте).
UPDATE: патч.
Суть проста: зачем мы в магазине будем заставлять нам нести продавца все печеньки, если нам не нравятся диетические. В переводе значит, что мы прямо в запросе к БД будем проверять доступность модуля группе юзера, тем самым уменьшая нагрузку и экономя трафик с БД.
Как видно на демо, для главной страницы оптимизированной версии при дефолтной установке делается на 6 запросов к БД меньше, чем стоковой версии. Чтобы это увидеть поменяйте в блоке справа шаблон: "По умолчанию" и "_default_" — это неоптимизированная версия, "new_default" — оптимизированная. На время генерации можете не смотреть — мускул кэширует запросы сам.
Приступим к выполнению ключевого различия с этим.
1. Выполним запросы к БД:
UPDATE cms_modules SET access_list = REPLACE (access_list, '- ', '- allow'); ALTER TABLE `cms_modules` ADD FULLTEXT(`access_list`);
Найти:
389 и 470 $access_list = $inCore->request('allow_group', 'array_int');
$access_list = $inCore->request('allow_group', 'array');
942 echo '<option value="$group['id'].'"'; if ($do=='edit' && $mod['access_list']){ if (inArray($access_list, $group['id'])){
942 echo '<option value="allow'.$group['id'].'"'; if ($do=='edit' && $mod['access_list']){ if (inArray($access_list, 'allow'.$group['id'])){
после:
public $captcha_count = 1;
private static $modules;
public function countThisModules($position){ if (self::$modules === null)self::$modules = self::getThisModules(); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private function getThisModules(){ $inDB = cmsDatabase::getInstance(); //Получаем id пункта меню $menuid = cmsCore::getInstance()->menuId(); //Проверяем позиции $strict_sql = !cmsCore::getInstance()->isMenuIdStrict() ? 'AND (m.is_strict_bind = 0)' : ''; //Проверяем доступ $allow_sql = !cmsUser::getInstance()->is_admin ? "AND (MATCH (m.access_list) AGAINST ('+allow".cmsUser::getInstance()->group_id."' IN BOOLEAN MODE) OR m.access_list = '')" : ''; //Получаем все разрешённые данному юзеру модули для этой страницы $sql = "SELECT *, m.id as mid, m.template as tpl FROM cms_modules m, cms_modules_bind mb WHERE m.published = 1 AND m.id = mb.module_id AND (mb.menu_id = '$menuid' OR mb.menu_id = 0) $strict_sql $allow_sql ORDER BY m.ordering ASC"; $result = $inDB->query($sql); if(!$inDB->num_rows($result)){ return false; } while ($mod = $inDB->fetch_assoc($result)){ $mods[$mod['position']][] = $mod; }//while return $mods; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public function printThisModules($position){ $inCore = cmsCore::getInstance(); global $_LANG; // Проверяем позиции if($position=='top' && @$_REQUEST['view']=='search') { return true; } if(!self::countThisModules($position))return false; foreach(self::$modules[$position] as $mod){ $modulefile = PATH.'/modules/'.$mod['content'].'/module.php'; if (!$mod['user']) { cmsCore::loadLanguage('modules/'.$mod['content']); } if( !$mod['is_external'] ){ //PROCESS FILTERS $filters = $inCore->getFilters(); if ($filters){ foreach($filters as $id=>$_data){ require_once PATH.'/filters/'.$_data['link'].'/filter.php'; $_data['link']($mod['content']); } } $callback = true; $modulebody = $mod['content']; } if( $mod['is_external'] ){ //load module file require_once $modulefile; //run module and get its output to $modulebody if ($mod['cache'] && $inCore->isCached('module', $mod['mid'], $mod['cachetime'], $mod['cacheint'])){ $modulebody = $inCore->getCache('module', $mod['mid']); $callback = true; } else { $config = $inCore->yamlToArray($mod['config']); $inCore->cacheModuleConfig($mod['module_id'], $config); $callback = $mod['content']($mod['module_id']); if($mod['cache']) { $inCore->saveCache('module', $mod['mid'], $modulebody); } } } } if ( $callback ){ //if module returns TRUE $mod['body'] = $modulebody; $smarty = $inCore->initSmartyModule(); if (cmsConfig::getConfig('fastcfg') && cmsUser::getInstance()->is_admin){ $smarty->assign('cfglink', '/admin/index.php?view=modules&do=edit&id='.$mod['mid']); } $smarty->assign('mod', $mod); $smarty->display($module_tpl); } }//foreach } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
В следующий раз мы изменим printThisModules для другого метода кэширования, но можете даже не надеяться на появление этого в дистрибутиве, ибо у разработчиков совершенно иной взгляд на саму задачу кэширования)
Как именно будет кэшироваться? А очень просто: будут создаваться файлы кэша с простым html или же массивом данных. Это будет на усмотрение модуля, да, кешировать себя будет модуль сам, в зависимости от его приватности и каких либо изменений для каждого пользователя. Например модуль форума: в зависимости от доступа, он может отображать разные темы разным группам (по крайней мере в моей доработке =D), а также у каждого конкретного пользователя разные прочтённые темы, поэтому мы не можем просто взять и закэшировать его. У модуля форума будет по одному файлу на каждую группу, в каждом будет массив, который модуль будет перебирать и отмечать прочтённость топика данным конкретным юзером, а потом отдавать смарти. Хм, что же у нас не для разных групп… Ах, да — Лента. У неё будет один файл для всех групп, в котором просто готовый html.
Я не решил как чистить кеш, либо плагином по эвентам, либо классом логирования, благо всё что можно сделать во фронте, отображается в Ленте.
Ещё важный момент с датами: они просто будут окружаться спаном с timestamp, по которому в закэшированом html легко поменять "5 минут назад", на "вчера во столько то" и ещё с помощью яваскрипта можно будет оживить эти самые "n минут назад" на сайте).
UPDATE: патч.
Реклама #
Роман 11 лет назад #
Anonim 11 лет назад #
lokanaft 11 лет назад #
qwest 11 лет назад #
Очень шустро открываются странички.
lokanaft 11 лет назад #