getObject($params); $this->CurrentSQL = $object->GetDBField($params['field']); // 1. replace prefix to actual one $this->CurrentSQL = str_replace("<%prefix%>", TABLE_PREFIX, $this->CurrentSQL); // 2. replace all pseudo-tags found in sql with their values while ( ($tag = $this->FindTag()) != false ) { $this->CurrentSQL = str_replace('<%'.$tag.'%>', $this->ProcessStatisticTag($tag), $this->CurrentSQL); } // 3. query sql and process gathered data $values = $this->Conn->GetCol($this->CurrentSQL); if (!$values) return ''; if (!$this->PostFormatting) return array_shift($values); switch ($this->PostFormatting) { case 'number': // simple-specific postformatting /** @var LanguagesItem $lang */ $lang = $this->Application->recallObject('lang.current'); $value = $lang->formatNumber($value, $this->PostFormattingParams['precision']); break; case 'COUNT': // extended postformatting $value = count($values); break; case 'SUM': $value = 0; foreach ($values as $cur_value) { $value += $cur_value; } if ($this->PostFormattingParams['format_as'] == 'file') { $value = size($value); } break; // other type of information (not from db) case 'SysFileSize': $value = size( dir_size(FULL_PATH.'/') ); break; default: // simple-default postformatting $value = adodb_date($this->PostFormatting, array_shift($values)); break; } $this->PostFormatting = false; $this->PostFormattingParams = Array(); return $value; } function FindTag() { // finds tag in current sql & returns it if found, false otherwise $tagOpen = '<%'; $tagClose = '%>'; $tagOpenLen = strlen($tagOpen); $startPos = strpos($this->CurrentSQL, $tagOpen); if( $startPos !== false ) { $endPos = strpos($this->CurrentSQL, $tagClose, $startPos); return ($endPos > $startPos) ? substr($this->CurrentSQL, $startPos + $tagOpenLen, $endPos - $startPos - $tagOpenLen) : false; } return false; } function ProcessStatisticTag($tag) { $tag = trim($tag); if (isset($this->TagCache[$tag])) { return $this->TagCache[$tag]; } /** @var kDBItem $object */ $object = $this->getObject(); list($tag_name, $tag_params) = explode(' ', $tag, 2); // 1st - function, 2nd .. nth - params preg_match_all('/([\${}a-zA-Z0-9_.-]+)=(["\']{1,1})(.*?)(? $val){ $tag_params[$val[1]] = str_replace(Array('\\' . $val[2], '+'), Array($val[2], ' '), $val[3]); } switch ($tag_name) { case 'm:config': // m:config name="" return $this->Application->ConfigValue($tag_params['name']); break; case 'm:post_format': // m:post_format field="" type="" precision="2" /** @var LanguagesItem $lang */ $lang = $this->Application->recallObject('lang.current'); switch ($tag_params['type']) { case 'date': $this->PostFormatting = $lang->GetDBField('DateFormat'); break; case 'time': $this->PostFormatting = $lang->GetDBField('TimeFormat'); break; case 'currency': $this->PostFormatting = 'number'; $this->PostFormattingParams['precision'] = $tag_params['precision']; break; } return $tag_params['field']; break; case 'm:custom_action': // m:custom_action sql="empty" action="SysFileSize" $this->PostFormatting = $tag_params['action']; return ($tag_params['sql'] == 'empty') ? 'SELECT 1' : $tag_params['sql']; break; case 'modules:get_current': return $object->GetDBField('Module'); break; case 'm:sql_action': //m:sql_action sql="SHOW TABLES" action="COUNT" field="*" $this->PostFormatting = $tag_params['action']; $this->PostFormattingParams = $tag_params; return $tag_params['sql']; break; case 'link:hit_count': if ($tag_params['type'] == 'top') {// by now only top is supported $top_links_count = $this->Application->ConfigValue('Link_TopCount'); $sql = 'SELECT Hits FROM '.TABLE_PREFIX.'Link ORDER BY Hits DESC LIMIT 0, '.$top_links_count; return $this->getLastRecord($sql, 'Hits'); } break; case 'article:hit_count': if ($tag_params['type'] == 'top') {// by now only top is supported $top_articles_count = $this->Application->ConfigValue('News_VotesToHot'); $min_votes = $this->Application->ConfigValue('News_MinVotes'); $sql = 'SELECT CachedRating FROM '.TABLE_PREFIX.'News WHERE CachedVotesQty > '.$min_votes.' ORDER BY CachedRating DESC LIMIT 0, '.$top_articles_count; return $this->getLastRecord($sql, 'CachedRating'); } break; case 'topic:hit_count': if ($tag_params['type'] == 'top') {// by now only top is supported $top_posts_count = $this->Application->ConfigValue('Topic_PostsToPop'); $sql = 'SELECT Views FROM '.TABLE_PREFIX.'Topic ORDER BY Views DESC LIMIT 0, '.$top_posts_count; return $this->getLastRecord($sql, 'Views'); } break; } return ''; } function getLastRecord($sql, $field) { $records = $this->Conn->GetCol($sql); return count($records) ? array_pop($records) : 0; } /** * Allows to get pending item count for prefix * * @param Array $params * @return int */ function CountPending($params) { $prefix = $params['prefix']; $cache_key = 'statistics.pending[%' . $this->Application->incrementCacheSerial($prefix, null, false) . '%]'; $value = $this->Application->getCache($cache_key); if ($value === false) { $statistics_info = $this->Application->getUnitOption($prefix.'.pending', 'StatisticsInfo'); if (!$statistics_info) { return 0; } $table = $this->Application->getUnitOption($prefix, 'TableName'); $status_field = array_shift( $this->Application->getUnitOption($prefix, 'StatusField') ); $this->Conn->nextQueryCachable = true; $sql = 'SELECT COUNT(*) FROM '.$table.' WHERE '.$status_field.' = '.$statistics_info['status']; $value = $this->Conn->GetOne($sql); $this->Application->setCache($cache_key, $value); } return $value; } function GetTotalPending() { $prefixes = $this->getPendingPrefixes(); $sum = 0; foreach ($prefixes as $prefix) { $sum += $this->CountPending( Array('prefix' => $prefix) ); } return $sum; } /** * Get prefixes, that are allowed to have pending items (check module licenses too) * * @return Array */ function getPendingPrefixes() { /** @var kModulesHelper $modules_helper */ $modules_helper = $this->Application->recallObject('ModulesHelper'); $licensed_modules = array_map('strtolower', $modules_helper->_GetModules()); $sql = 'SELECT LOWER(Module), Prefix FROM '.TABLE_PREFIX.'ItemTypes it LEFT JOIN '.TABLE_PREFIX.'Modules m ON m.Name = it.Module WHERE (m.Loaded = 1) AND (LENGTH(it.ClassName) > 0)'; $prefixes = $this->Conn->GetCol($sql, 'Prefix'); $module_names = array_map('strtolower', array_unique(array_values($prefixes))); $module_names = array_intersect($module_names, $licensed_modules); $ret = Array (); foreach ($prefixes as $prefix => $module_name) { if (in_array($module_name, $module_names)) { $ret[] = $prefix; } } return $ret; } function PrintPendingStatistics($params) { $check_prefixes = $this->getPendingPrefixes(); if (!$check_prefixes) { return ''; } $ret = ''; $columns = $params['columns']; $block_params = $this->prepareTagParams( Array('name' => $this->SelectParam($params, 'render_as,block') ) ); $prefixes = Array(); foreach ($check_prefixes as $prefix) { $statistics_info = $this->Application->getUnitOption($prefix.'.pending', 'StatisticsInfo'); if ($statistics_info) { $prefixes[] = $prefix; } } $row_number = 0; foreach ($prefixes as $i => $prefix) { $block_params['prefix'] = $prefix; $statistics_info = $this->Application->getUnitOption($prefix.'.pending', 'StatisticsInfo'); if ($i % $columns == 0) { $column_number = 1; $ret .= ''; } $block_params['column_number'] = $column_number; $block_params['is_first'] = $i < $columns ? 1 : 0; $template = $statistics_info['url']['t']; unset($statistics_info['url']['t']); $url = $this->Application->HREF($template, '', $statistics_info['url']); if ($statistics_info['js_url'] != '#url#') { $statistics_info['js_url'] = 'javascript:'.$statistics_info['js_url']; } $block_params['url'] = str_replace('#url#', $url, $statistics_info['js_url']); $block_params['icon'] = $statistics_info['icon']; $block_params['label'] = $statistics_info['label']; $ret .= $this->Application->ParseBlock($block_params); $column_number++; if (($i+1) % $columns == 0) { $ret .= ''; } } return $ret; } }