From 9db559747527f620496de596da8a52684a430f01 Mon Sep 17 00:00:00 2001 From: Lufei Date: Fri, 2 Jun 2023 14:19:58 +0800 Subject: [PATCH] * Add cache for block. --- config/config.php | 6 ++ framework/base/control.class.php | 1 + framework/base/model.class.php | 16 +++++ framework/model.class.php | 1 - lib/cache/cache.class.php | 2 +- lib/cache/driver/FileDriver.php | 32 ++++++--- module/block/control.php | 112 ++++++++++++++++++++----------- 7 files changed, 118 insertions(+), 52 deletions(-) diff --git a/config/config.php b/config/config.php index 3fd4fb0e96..07552ee709 100644 --- a/config/config.php +++ b/config/config.php @@ -71,6 +71,12 @@ $config->slaveDB->driver = 'mysql'; $config->slaveDB->encoding = 'UTF8'; $config->slaveDB->strictMode = false; +/* 缓存设置。Cache settings. */ +$config->cache = new stdclass(); +$config->cache->enable = false; // 是否开启缓存。Enable cache or not. +$config->cache->lifetime = 5 * 60; // 缓存生存时间。The lifetime of cache. +$config->cache->driver = 'File'; // 缓存驱动。 The driver of cache. can be File|Yac|Apcu. + /* 可用域名后缀列表。Domain postfix lists. */ $config->domainPostfix = "|com|com.cn|com.hk|com.tw|com.vc|edu.cn|es|"; $config->domainPostfix .= "|eu|fm|gov.cn|gs|hk|im|in|info|jp|kr|la|me|"; diff --git a/framework/base/control.class.php b/framework/base/control.class.php index 9dd6011a00..55ff21c026 100644 --- a/framework/base/control.class.php +++ b/framework/base/control.class.php @@ -319,6 +319,7 @@ class baseControl $this->{$moduleName} = $model; $this->dao = $model->dao; + $this->cache = $model->cache; return $model; } diff --git a/framework/base/model.class.php b/framework/base/model.class.php index 936bde692b..53804c7149 100644 --- a/framework/base/model.class.php +++ b/framework/base/model.class.php @@ -150,6 +150,7 @@ class baseModel $this->loadDAO(); $this->setSuperVars(); + $this->loadCache(); /** * 读取当前模块的tao类。 @@ -323,6 +324,21 @@ class baseModel $this->dao = $dao; } + /** + * 加载缓存类。 + * Load cache class. + * + * @access public + * @return void + */ + public function loadCache() + { + if($this->config->cache->enable != true) return; + $this->app->loadClass('cache', $static = true); + $namespace = isset($this->session->user->account) ? $this->session->user->account : 'guest'; + $this->cache = cache::create($this->config->cache->driver, $namespace, $this->config->cache->lifetime); + } + /** * 删除记录。 * Delete one record. diff --git a/framework/model.class.php b/framework/model.class.php index b94ced3241..cebd1fa8dc 100644 --- a/framework/model.class.php +++ b/framework/model.class.php @@ -88,7 +88,6 @@ class model extends baseModel * @access public * @return string */ - public function buildMenu($moduleName, $methodName, $params, $data, $type = 'view', $icon = '', $target = '', $class = '', $onlyBody = false, $misc = '' , $title = '', $returnHtml = true) { if(strpos($moduleName, '.') !== false) list($appName, $moduleName) = explode('.', $moduleName); diff --git a/lib/cache/cache.class.php b/lib/cache/cache.class.php index 434312356c..153f9cccf1 100644 --- a/lib/cache/cache.class.php +++ b/lib/cache/cache.class.php @@ -49,7 +49,7 @@ class cache throw new InvalidArgumentException("Driver {$driver} is not supported."); } - if($driver != 'File' && !extension_loaded($driver)) throw new InvalidArgumentException("Driver ext-{$driver} is not loaded."); + if($driver != self::DRIVER_FILE && !extension_loaded($driver)) throw new InvalidArgumentException("Driver ext-{$driver} is not loaded."); global $app; $this->client = new $className($namespace, $defaultLifetime, $app->getCacheRoot()); diff --git a/lib/cache/driver/FileDriver.php b/lib/cache/driver/FileDriver.php index 215221bd3a..cae510f0a8 100644 --- a/lib/cache/driver/FileDriver.php +++ b/lib/cache/driver/FileDriver.php @@ -51,18 +51,22 @@ class FileDriver implements CacheInterface return $this->getPrefix() . DS . md5($key) . '.cache'; } - public function get($key, $default = null): mixed + public function get($key, $default = null) { $file = $this->getCacheKey($key); if(!file_exists($file)) return $default; $content = unserialize(file_get_contents($file)); - if($this->isExpired($content)) return $default; + if($this->isExpired($content)) + { + $this->delete($key); + return $default; + } return $content['data']; } - public function set($key, $value, $ttl = null): bool + public function set($key, $value, $ttl = null) { $file = $this->getCacheKey($key); $content = serialize($this->generatePayload($value, $ttl)); @@ -72,7 +76,7 @@ class FileDriver implements CacheInterface return (bool)$result; } - public function delete($key): bool + public function delete($key) { $file = $this->getCacheKey($key); if(file_exists($file)) @@ -89,7 +93,7 @@ class FileDriver implements CacheInterface return $this->clearPrefix(''); } - public function getMultiple($keys, $default = null): iterable + public function getMultiple($keys, $default = null) { if(!is_array($keys)) throw new InvalidArgumentException('The keys is invalid!'); @@ -99,7 +103,7 @@ class FileDriver implements CacheInterface return $result; } - public function setMultiple($values, $ttl = null): bool + public function setMultiple($values, $ttl = null) { if(!is_array($values)) throw new InvalidArgumentException('The values is invalid!'); @@ -109,7 +113,7 @@ class FileDriver implements CacheInterface return true; } - public function deleteMultiple($keys): bool + public function deleteMultiple($keys) { if(!is_array($keys)) throw new InvalidArgumentException('The keys is invalid!'); @@ -118,14 +122,22 @@ class FileDriver implements CacheInterface return true; } - public function has($key): bool + public function has($key) { $file = $this->getCacheKey($key); - return file_exists($file); + if(!file_exists($file)) return false; + + $content = unserialize(file_get_contents($file)); + if($this->isExpired($content)) + { + $this->delete($key); + return false; + } + return true; } - public function clearPrefix(string $prefix): bool + public function clearPrefix(string $prefix) { $files = glob($this->getPrefix() . DS . $prefix . '*'); foreach($files as $file) diff --git a/module/block/control.php b/module/block/control.php index 71e5693303..438ced2d17 100755 --- a/module/block/control.php +++ b/module/block/control.php @@ -380,7 +380,16 @@ class block extends control { $this->view->tutorialed = $this->loadModel('tutorial')->getTutorialed(); - $data = $this->block->getWelcomeBlockData(); + $cacheKey = 'welcomeBlockData'; + if($this->config->cache->enable and $this->cache->has($cacheKey)) + { + $data = $this->cache->get($cacheKey); + } + else + { + $data = $this->block->getWelcomeBlockData(); + if($this->config->cache->enable) $this->cache->set($cacheKey, $data); + } $this->view->tasks = $data['tasks']; $this->view->doneTasks = $data['doneTasks']; @@ -965,47 +974,57 @@ class block extends control return false; } - $today = helper::today(); - $monday = date('Ymd', strtotime($this->weekly->getThisMonday($today))); - $tasks = $this->dao->select("project, - sum(consumed) as totalConsumed, - sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft") - ->from(TABLE_TASK) - ->where('project')->in(array_keys($projects)) - ->andWhere('deleted')->eq(0) - ->andWhere('parent')->lt(1) - ->groupBy('project') - ->fetchAll('project'); - - $this->app->loadClass('pager', $static = true); - - foreach($projects as $projectID => $project) + $cacheKey = __FUNCTION__ . $status . $count . $excludedModel; + if($this->config->cache->enable and $this->cache->has($cacheKey)) { - if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) + $projects = $this->cache->get($cacheKey); + } + else + { + $today = helper::today(); + $monday = date('Ymd', strtotime($this->weekly->getThisMonday($today))); + $tasks = $this->dao->select("project, + sum(consumed) as totalConsumed, + sum(if(status != 'cancel' and status != 'closed', `left`, 0)) as totalLeft") + ->from(TABLE_TASK) + ->where('project')->in(array_keys($projects)) + ->andWhere('deleted')->eq(0) + ->andWhere('parent')->lt(1) + ->groupBy('project') + ->fetchAll('project'); + + $this->app->loadClass('pager', $static = true); + + foreach($projects as $projectID => $project) { - $pager = pager::init(0, 1, 1); - $project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100; - $project->executions = $this->execution->getStatData($projectID, 'all', 0, 0, false, '', 'id_desc', $pager); + if(in_array($project->model, array('scrum', 'kanban', 'agileplus'))) + { + $pager = pager::init(0, 1, 1); + $project->progress = $project->allStories == 0 ? 0 : round($project->doneStories / $project->allStories, 3) * 100; + $project->executions = $this->execution->getStatData($projectID, 'all', 0, 0, false, '', 'id_desc', $pager); + } + elseif(in_array($project->model, array('waterfall', 'waterfallplus'))) + { + $begin = $project->begin; + $weeks = $this->weekly->getWeekPairs($begin); + $current = zget($weeks, $monday, ''); + $current = substr($current, 0, -11) . substr($current, -6); + + $PVEV = $this->weekly->getPVEV($projectID, $today); + $project->pv = $PVEV['PV']; + $project->ev = $PVEV['EV']; + $project->ac = $this->weekly->getAC($projectID, $today); + $project->sv = $this->weekly->getSV($project->ev, $project->pv); + $project->cv = $this->weekly->getCV($project->ev, $project->ac); + + $progress = isset($tasks[$projectID]) ? (($tasks[$projectID]->totalConsumed + $tasks[$projectID]->totalLeft)) ? round($tasks[$projectID]->totalConsumed / ($tasks[$projectID]->totalConsumed + $tasks[$projectID]->totalLeft), 3) * 100 : 0 : 0; + + $project->current = $current; + $project->progress = $progress; + } } - elseif(in_array($project->model, array('waterfall', 'waterfallplus'))) - { - $begin = $project->begin; - $weeks = $this->weekly->getWeekPairs($begin); - $current = zget($weeks, $monday, ''); - $current = substr($current, 0, -11) . substr($current, -6); - $PVEV = $this->weekly->getPVEV($projectID, $today); - $project->pv = $PVEV['PV']; - $project->ev = $PVEV['EV']; - $project->ac = $this->weekly->getAC($projectID, $today); - $project->sv = $this->weekly->getSV($project->ev, $project->pv); - $project->cv = $this->weekly->getCV($project->ev, $project->ac); - - $progress = isset($tasks[$projectID]) ? (($tasks[$projectID]->totalConsumed + $tasks[$projectID]->totalLeft)) ? round($tasks[$projectID]->totalConsumed / ($tasks[$projectID]->totalConsumed + $tasks[$projectID]->totalLeft), 3) * 100 : 0 : 0; - - $project->current = $current; - $project->progress = $progress; - } + if($this->config->cache->enable) $this->cache->set($cacheKey, $projects); } $this->view->projects = $projects; @@ -1865,6 +1884,8 @@ class block extends control $objectCountList += array('feedback' => 'feedbackCount', 'ticket' => 'ticketCount'); } + $enableCache = $this->config->cache->enable; + $tasks = $this->loadModel('task')->getUserSuspendedTasks($this->app->user->account); foreach($objectCountList as $objectType => $objectCount) { @@ -2007,8 +2028,19 @@ class block extends control { /* load pager. */ $this->app->loadClass('pager', $static = true); - $pager = new pager(0, 3, 1); - $this->view->projects = $this->loadModel('project')->getInfoList('all', 'id_desc', $pager, 1); + $pager = new pager(0, 3, 1); + $cacheKey = __FUNCTION__; + if($this->config->cache->enable and $this->cache->has($cacheKey)) + { + $this->app->loadLang('project'); + $projects = $this->cache->get($cacheKey); + } + else + { + $projects = $this->loadModel('project')->getInfoList('all', 'id_desc', $pager, 1); + if($this->config->cache->enable) $this->cache->set($cacheKey, $projects); + } + $this->view->projects = $projects; } /**