Page MenuHomeIn-Portal Phabricator

statistics_tag_processor.php
No OneTemporary

File Metadata

Created
Thu, Sep 4, 6:26 AM

statistics_tag_processor.php

<?php
/**
* @version $Id: statistics_tag_processor.php 14241 2011-03-16 20:24:35Z alex $
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class StatisticsTagProcessor extends kDBTagProcessor {
var $TagCache = Array(); // parsed tag (in sql queries only) values are cached
var $CurrentSQL = ''; // sql query being currently processed
var $PostFormatting = false; // apply formatting to sql query results
var $PostFormattingParams = Array(); // post formatting params if any
function CalculateValue($params)
{
$object =& $this->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
$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];
}
$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})(.*?)(?<!\\\)\\2/s', $tag_params, $rets, PREG_SET_ORDER);
$tag_params = Array();
foreach ($rets AS $key => $val){
$tag_params[$val[1]] = str_replace(Array('\\' . $val[2], '+'), Array($val[2], ' '), $val[3]);
}
switch ($tag_name) {
case 'm:config':
// m:config name="<variable_name>"
return $this->Application->ConfigValue($tag_params['name']);
break;
case 'm:post_format':
// m:post_format field="<field_name>" type="<formatting_type>" precision="2"
$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;
}
}
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()
{
$modules_helper =& $this->Application->recallObject('ModulesHelper');
/* @var $modules_helper kModulesHelper */
$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 .= '<tr>';
}
$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 .= '</tr>';
}
}
return $ret;
}
}

Event Timeline