php_olap
parent
56dc33acda
commit
311ce6b288
|
@ -0,0 +1 @@
|
|||
Deny from all
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
# Всякие константы
|
||||
# (c) VitaliF 2006-2010
|
||||
|
||||
define ('IN_CONFIG', true);
|
||||
|
||||
setlocale(LC_ALL, 'ru_RU.UTF-8');
|
||||
mb_internal_encoding('utf-8');
|
||||
|
||||
include_once 'loconfig.php';
|
||||
|
||||
$image_path = '/images/';
|
||||
$template_path = '/templates/';
|
||||
$cache_path = '/tplcache';
|
||||
|
||||
$cfgTables = array();
|
||||
$mysqlThrowError = true;
|
||||
$mysqlNoSiteConfig = true;
|
||||
|
||||
$LoginSession = 'RTV'.md5('http://' . $Domain);
|
||||
|
||||
require_once 'lib.php';
|
|
@ -0,0 +1,934 @@
|
|||
<?php
|
||||
|
||||
# Утилитные функции
|
||||
# (c) VitaliF 2006-2010
|
||||
|
||||
$AutoloadClasses['LinguaStemRu'] = dirname(__FILE__).'/stem_ru.php';
|
||||
|
||||
function __autoload($class_name)
|
||||
{
|
||||
global $AutoloadClasses;
|
||||
if ($f = $AutoloadClasses[$class_name])
|
||||
{
|
||||
require_once $f;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class PopulatedRow implements ArrayAccess
|
||||
{
|
||||
public $row;
|
||||
public function __construct($row)
|
||||
{
|
||||
$this->row = $row;
|
||||
}
|
||||
public function offsetExists($k)
|
||||
{
|
||||
return array_key_exists($k, $this->row) || self::$calckeys[$k];
|
||||
}
|
||||
public function offsetUnset($k)
|
||||
{
|
||||
unset($this->$k);
|
||||
}
|
||||
public function offsetSet($k, $v)
|
||||
{
|
||||
if (array_key_exists($k, $this->row))
|
||||
$this->row[$k] = $v;
|
||||
else
|
||||
$this->$k = $v;
|
||||
}
|
||||
public function offsetGet($k)
|
||||
{
|
||||
if (array_key_exists($k, $this->row))
|
||||
return $this->row[$k];
|
||||
if (!is_null($this->$k))
|
||||
return $this->$k;
|
||||
$this->populate($k);
|
||||
return $this->$k;
|
||||
}
|
||||
public function populate($k)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function get_include_contents($filename)
|
||||
{
|
||||
if (is_file($filename))
|
||||
{
|
||||
ob_start();
|
||||
include $filename;
|
||||
$contents = ob_get_contents();
|
||||
ob_end_clean();
|
||||
return $contents;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function str_starts_with ($str, $sub)
|
||||
{
|
||||
if (strcmp (substr ($str, 0, strlen ($sub)), $sub) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function str_ends_with ($str, $sub)
|
||||
{
|
||||
if (strcmp (substr ($str, strlen ($str) - strlen ($sub)), $sub) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalize_domain ($st)
|
||||
{
|
||||
$dom = '';
|
||||
if (!empty($st))
|
||||
{
|
||||
if (($p = strpos ($st, '://')) !== false)
|
||||
$dom = substr ($st, $p+3);
|
||||
$dom = strtolower ($dom);
|
||||
if (preg_match ('#^www[0-9]*\.#is', $dom, $m))
|
||||
$dom = substr ($dom, strlen ($m[0]));
|
||||
if (($p = strpos ($st, '/')) !== false)
|
||||
$dom = substr ($st, 0, $p);
|
||||
}
|
||||
return $dom;
|
||||
}
|
||||
|
||||
function normalize_link ($l, $pre)
|
||||
{
|
||||
if (!empty ($l) && !empty ($pre))
|
||||
{
|
||||
if (str_starts_with($l, './'))
|
||||
$l = substr($l, 2);
|
||||
if (!strpos($l, '://'))
|
||||
{
|
||||
if ($l{0} != '/')
|
||||
{
|
||||
if ($pre{strlen($pre)-1} != '/')
|
||||
$pre .= '/';
|
||||
$l = $pre . $l;
|
||||
}
|
||||
else if (($sch = strpos($pre, '://')) !== false)
|
||||
$l = substr($pre, 0, strpos($pre, '/', $sch+3)) . $l;
|
||||
}
|
||||
return $l;
|
||||
}
|
||||
return $l;
|
||||
}
|
||||
|
||||
function strlimit($str, $maxlen)
|
||||
{
|
||||
if (!$maxlen || $maxlen < 1 || strlen($str) <= $maxlen)
|
||||
return $str;
|
||||
$str = substr($str, 0, $maxlen);
|
||||
$p = strrpos($str, ' ');
|
||||
if (!$p || ($pt = strrpos($str, "\t")) > $ps)
|
||||
$p = $pt;
|
||||
if ($p)
|
||||
$str = substr($str, 0, $p);
|
||||
return $str . '...';
|
||||
}
|
||||
|
||||
function html_pbr($str)
|
||||
{
|
||||
return str_replace ("\n", "<br>", htmlspecialchars($str));
|
||||
}
|
||||
|
||||
function html_strip_pbr ($str)
|
||||
{
|
||||
global $allowed_html;
|
||||
if (!($a = $allowed_html))
|
||||
$a = '<div> <span> <a> <b> <i> <u> <p> <h1> <h2> <h3> <h4> <h5> <h6> <strike> <strong> <small> <big> <blink> <center> <ol> <pre> <sub> <sup> <font> <br> <table> <tr> <td> <th> <tbody> <tfoot> <thead> <tt> <ul> <li> <em> <img> <marquee>';
|
||||
return nl2br (strip_tags ($str, $a));
|
||||
}
|
||||
|
||||
function html_strip ($str)
|
||||
{
|
||||
global $allowed_html;
|
||||
if (!($a = $allowed_html))
|
||||
$a = '<div> <span> <a> <b> <i> <u> <p> <h1> <h2> <h3> <h4> <h5> <h6> <strike> <strong> <small> <big> <blink> <center> <ol> <pre> <sub> <sup> <font> <br> <table> <tr> <td> <th> <tbody> <tfoot> <thead> <tt> <ul> <li> <em> <img> <marquee>';
|
||||
return strip_tags ($str, $a);
|
||||
}
|
||||
|
||||
function unhtmlentity ($s)
|
||||
{
|
||||
$s = html_entity_decode ($s);
|
||||
preg_match_all ('/&#([0-9]*);/', $s, $ce, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||
$c = count($ce);
|
||||
for ($i = $c-1; $i >= 0; $i--)
|
||||
$s = substr ($s, 0, $ce[$i][0][1]) . chr($ce[$i][1][0]) . substr ($s, $ce[$i][0][1]+strlen($ce[$i][0][0]));
|
||||
return $s;
|
||||
}
|
||||
|
||||
function process_array ($arr, $kfunc, $vfunc)
|
||||
{
|
||||
$na = array ();
|
||||
foreach ($arr as $k => $v)
|
||||
{
|
||||
if (is_callable($kfunc))
|
||||
$k = $kfunc ($k);
|
||||
if (is_callable($vfunc))
|
||||
$v = $vfunc ($v);
|
||||
$na [$k] = $v;
|
||||
}
|
||||
return $na;
|
||||
}
|
||||
|
||||
/**
|
||||
* Функция разворачивает массив во вложенный хеш
|
||||
* Например [[0,1],[0,2],[1,1]] -> [0:[1:[[0,1]],2:[[0,2]]],1:[1:[[1,1]]]]
|
||||
*/
|
||||
function array_hashtree($a, $ka = NULL, $value = NULL)
|
||||
{
|
||||
$r = array();
|
||||
if (!is_array($ka))
|
||||
$ka = array($ka);
|
||||
foreach ($a as $ca)
|
||||
{
|
||||
$c = &$r;
|
||||
if (!is_null($ka))
|
||||
{
|
||||
foreach ($ka as $k)
|
||||
{
|
||||
$k = $ca[$k];
|
||||
if (!array_key_exists($k, $c))
|
||||
$c[$k] = array();
|
||||
$c = &$c[$k];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($ca as $k)
|
||||
{
|
||||
if (!array_key_exists($k, $c))
|
||||
$c[$k] = array();
|
||||
$c = &$c[$k];
|
||||
}
|
||||
}
|
||||
if (is_null($value))
|
||||
$c[] = $ca;
|
||||
else
|
||||
$c = $value;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Составление HTML кода картинки или flash-файла (возможно со ссылкой и alt)
|
||||
* Если $link начинается с popup:// - тогда запишется javascript-код для popup-а ссылки
|
||||
* Если $link начинается с popupwh:// - тогда дальше идёт WIDTH:HEIGHT:
|
||||
*/
|
||||
function banner ($path, $alt = false, $link = false, $width = false, $height = false, $target = false)
|
||||
{
|
||||
if (!$path)
|
||||
return '';
|
||||
$code = '';
|
||||
$wh = '';
|
||||
if ($width !== false && $width > 0)
|
||||
$wh .= ' width="' . $width . '"';
|
||||
if ($height !== false && $height > 0)
|
||||
$wh .= ' height="' . $height . '"';
|
||||
if (str_ends_with ($path, ".swf")) // flash
|
||||
{
|
||||
$code .= "<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0\"$wh>
|
||||
<param name=\"movie\" value=\"$path\">
|
||||
<param name=\"play\" value=\"true\">
|
||||
<param name=\"loop\" value=\"true\">
|
||||
<param name=\"quality\" value=\"high\">
|
||||
<param name=\"WMode\" value=\"Window\">
|
||||
<embed$wh src=\"$path\" play=\"true\" loop=\"true\" quality=\"high\" WMode=\"Window\" pluginspage=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\"></embed>
|
||||
</object>";
|
||||
}
|
||||
else // картинка
|
||||
{
|
||||
if ($link !== false && str_starts_with ($link, 'popup://'))
|
||||
{
|
||||
$link = substr ($link, 8);
|
||||
$link = "javascript: void window.open('$link', 'newWin', 'width=640,height=480,menubar=no,location=no,resizable=yes,scrollbars=yes').focus();";
|
||||
}
|
||||
else if ($link !== false && str_starts_with ($link, 'popupwh://'))
|
||||
{
|
||||
$link = substr ($link, 10);
|
||||
list ($popupw, $popuph, $link) = explode (':', $link, 3);
|
||||
$link = "javascript: void window.open('$link', 'newWin', 'width=$popupw,height=$popuph,menubar=no,location=no,resizable=yes,scrollbars=yes').focus();";
|
||||
}
|
||||
if ($link !== false)
|
||||
$code .= '<a href="'.$link.'"'.($target !== false ? ' target="'.$target.'"' : '').'>';
|
||||
if ($alt !== false)
|
||||
$alttag = ' alt="'.htmlspecialchars($alt).'" title="'.htmlspecialchars($alt).'"';
|
||||
else $alttag = '';
|
||||
$code .= "<img src=\"$path\" border=\"0\"$alttag$wh />";
|
||||
if ($link !== false)
|
||||
$code .= '</a>';
|
||||
}
|
||||
return $code;
|
||||
}
|
||||
|
||||
/* Уложить ширину и высоту изображения пропорционально в рамки maxw/maxh */
|
||||
function fit_width_height($cw, $ch, $maxw, $maxh)
|
||||
{
|
||||
if ($maxw <= 0 && $maxh <= 0 || $cw <= 0 || $ch <= 0)
|
||||
return array($cw, $ch);
|
||||
if ($maxw > 0 && ($maxh <= 0 || $maxh/$ch >= $maxw/$cw))
|
||||
{
|
||||
$nw = $maxw;
|
||||
$nh = $ch * $maxw / $cw;
|
||||
}
|
||||
else if ($maxh > 0 && ($maxw <= 0 || $maxh/$ch < $maxw/$cw))
|
||||
{
|
||||
$nw = $cw * $maxh / $ch;
|
||||
$nh = $maxh;
|
||||
}
|
||||
return array($nw, $nh);
|
||||
}
|
||||
|
||||
function loadimagebyext($from)
|
||||
{
|
||||
if (strrpos($from, '.') !== false)
|
||||
{
|
||||
$ext = strtolower(substr($from, strrpos($from, '.')+1));
|
||||
if (function_exists("imagejpeg") && ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'jfif' || $ext == 'jpe'))
|
||||
$img = @imagecreatefromjpeg($from);
|
||||
else if (function_exists("imagepng") && ($ext == 'png'))
|
||||
$img = @imagecreatefrompng($from);
|
||||
else if (function_exists("imagegif") && ($ext == 'gif'))
|
||||
$img = @imagecreatefromgif($from);
|
||||
}
|
||||
return $img;
|
||||
}
|
||||
|
||||
function saveimagebyext($img, $to)
|
||||
{
|
||||
global $default_jpeg_quality;
|
||||
$qual = $default_jpeg_quality;
|
||||
if (!$qual)
|
||||
$qual = 85;
|
||||
if (strrpos($to, '.') !== false)
|
||||
{
|
||||
$ext = strtolower(substr($to, strrpos($to, '.')+1));
|
||||
if ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'jfif' || $ext == 'jpe')
|
||||
@imagejpeg($img, $to, $qual);
|
||||
else if ($ext == 'png')
|
||||
@imagepng($img, $to);
|
||||
else if ($ext == 'gif')
|
||||
@imagegif($img, $to);
|
||||
else
|
||||
return false;
|
||||
return $to;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Масштабирование изображения, находящегося в файле $filename
|
||||
* Поддерживаются JPG, GIF, и PNG, в зависимости от возможностей PHP
|
||||
* В $maxw и $maxh возвратит результаты.
|
||||
*/
|
||||
function scaleimage ($from, $to, &$maxw, &$maxh, $ret_after_size = false)
|
||||
{
|
||||
if (is_string($from))
|
||||
$img = loadimagebyext($from);
|
||||
else
|
||||
$img = $from;
|
||||
if (!$img)
|
||||
return false;
|
||||
$cw = imagesx($img);
|
||||
$ch = imagesy($img);
|
||||
$maxw = intval($maxw);
|
||||
$maxh = intval($maxh);
|
||||
if (($maxw <= 0 || $cw <= $maxw) && ($maxh <= 0 || $ch <= $maxh))
|
||||
{
|
||||
$maxw = $cw;
|
||||
$maxh = $ch;
|
||||
copy($from, $to);
|
||||
@imagedestroy($img);
|
||||
return true;
|
||||
}
|
||||
list($nw, $nh) = fit_width_height($cw, $ch, $maxw, $maxh);
|
||||
$thumb = imagecreatetruecolor($nw, $nh);
|
||||
$f = function_exists('imagecopyresampled') ? 'imagecopyresampled' : 'imagecopyresized';
|
||||
call_user_func($f, $thumb, $img, 0, 0, 0, 0, $nw, $nh, $cw, $ch);
|
||||
imagedestroy($img);
|
||||
$r = saveimagebyext($thumb, $to);
|
||||
imagedestroy($thumb);
|
||||
if ($ret_after_size)
|
||||
{
|
||||
$maxw = $nw;
|
||||
$maxh = $nh;
|
||||
}
|
||||
else
|
||||
{
|
||||
$maxw = $cw;
|
||||
$maxh = $ch;
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/* обрезание до нужного соотношения сторон $aspect = X/Y
|
||||
и потом - масштабирование до ширины $forcewidth, если она задана */
|
||||
function centercropimage($from, $to, $aspect, $forcewidth = 0)
|
||||
{
|
||||
$img = loadimagebyext($from);
|
||||
if (!$img)
|
||||
return false;
|
||||
$cw = imagesx($img);
|
||||
$ch = imagesy($img);
|
||||
$ca = $cw/$ch;
|
||||
if ($ca > $aspect)
|
||||
{
|
||||
$nw = $aspect*$ch;
|
||||
$nh = $ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
$nw = $cw;
|
||||
$nh = $cw/$aspect;
|
||||
}
|
||||
$posx = intval(($cw-$nw)/2);
|
||||
$posy = intval(($ch-$nh)/2);
|
||||
$cw = $nw;
|
||||
$ch = $nh;
|
||||
if ($forcewidth > 0)
|
||||
{
|
||||
$nh = $nh*$forcewidth/$nw;
|
||||
$nw = $forcewidth;
|
||||
}
|
||||
$thumb = imagecreatetruecolor($nw, $nh);
|
||||
$f = function_exists('imagecopyresampled') ? 'imagecopyresampled' : 'imagecopyresized';
|
||||
call_user_func($f, $thumb, $img, 0, 0, $posx, $posy, $nw, $nh, $cw, $ch);
|
||||
imagedestroy($img);
|
||||
$r = saveimagebyext($thumb, $to);
|
||||
imagedestroy($thumb);
|
||||
return $r;
|
||||
}
|
||||
|
||||
function get_image_size($from, &$w, &$h)
|
||||
{
|
||||
if (strrpos ($from, '.') !== false)
|
||||
{
|
||||
$ext = strtolower (substr ($from, strrpos ($from, '.')+1));
|
||||
if (function_exists ("imagejpeg") && ($ext == 'jpg' || $ext == 'jpeg' || $ext == 'jfif' || $ext == 'jpe'))
|
||||
$img = @imagecreatefromjpeg ($from);
|
||||
else if (function_exists ("imagepng") && ($ext == 'png'))
|
||||
$img = @imagecreatefrompng ($from);
|
||||
else if (function_exists ("imagegif") && ($ext == 'gif'))
|
||||
$img = @imagecreatefromgif ($from);
|
||||
if ($img)
|
||||
{
|
||||
$w = imagesx ($img);
|
||||
$h = imagesy ($img);
|
||||
imagedestroy ($img);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function load_image ($filevarname, $newfilename, &$imgvar, &$thumbvar, &$imgw, &$imgh, $maxdim_config = '')
|
||||
{
|
||||
global $local_path, $image_path, $file_creation_mode;
|
||||
$ret = false;
|
||||
|
||||
$path = $image_path . $newfilename;
|
||||
if (($pos = strrpos ($path, '/')) !== false)
|
||||
$path = substr ($path, 0, $pos+1);
|
||||
else $path = '/';
|
||||
|
||||
if (isset ($_FILES [$filevarname]['tmp_name']) &&
|
||||
$_FILES [$filevarname]['name'] != '')
|
||||
{
|
||||
$ext = strtolower (substr ($_FILES [$filevarname]['name'], strrpos ($_FILES [$filevarname]['name'], '.')+1));
|
||||
if ($ext == 'jpg' || $ext == 'jpeg' ||
|
||||
$ext == 'jpe' || $ext == 'jfif' ||
|
||||
$ext == 'png' || $ext == 'gif')
|
||||
{
|
||||
$fn_i = $image_path . $newfilename . '.' . $ext;
|
||||
$fn_t = $image_path . $newfilename . '_t.' . $ext;
|
||||
@unlink ($local_path . $fn_i); // !!! - предыдущее файло сотрётся
|
||||
@unlink ($local_path . $fn_t); // !!!
|
||||
if ((@move_uploaded_file ($_FILES [$filevarname]['tmp_name'], $local_path . $fn_i)))
|
||||
{
|
||||
$imgw = 0+config_var ($maxdim_config.'img_maxw');
|
||||
$imgh = 0+config_var ($maxdim_config.'img_maxh');
|
||||
if ($imgw <= 0)
|
||||
$imgw = false;
|
||||
if ($imgh <= 0)
|
||||
$imgh = false;
|
||||
if (is_numeric($file_creation_mode))
|
||||
chmod($local_path . $fn_i, $file_creation_mode);
|
||||
if (scaleimage ($local_path . $fn_i, $local_path . $fn_t, $imgw, $imgh))
|
||||
{
|
||||
$imgvar = $fn_i;
|
||||
$thumbvar = $fn_t;
|
||||
$ret = true;
|
||||
if (is_numeric($file_creation_mode))
|
||||
chmod($local_path . $fn_t, $file_creation_mode);
|
||||
}
|
||||
}
|
||||
else
|
||||
@unlink ($_FILES [$filevarname]['tmp_name']);
|
||||
}
|
||||
else
|
||||
@unlink ($_FILES [$filevarname]['tmp_name']);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function load_file ($filevarname, $newfilename)
|
||||
{
|
||||
global $local_path, $file_creation_mode;
|
||||
$ret = false;
|
||||
|
||||
$path = $newfilename;
|
||||
if (($pos = strrpos ($path, '/')) !== false)
|
||||
$path = substr ($path, 0, $pos+1);
|
||||
else $path = '/';
|
||||
|
||||
if (isset ($_FILES [$filevarname]['tmp_name']))
|
||||
{
|
||||
$ext = strtolower (substr ($_FILES [$filevarname]['name'], strrpos ($_FILES [$filevarname]['name'], '.')+1));
|
||||
$fn = $newfilename . '.' . $ext;
|
||||
@unlink ($local_path . $fn);
|
||||
if ((@move_uploaded_file ($_FILES [$filevarname]['tmp_name'], $local_path . $fn)))
|
||||
{
|
||||
$ret = $fn;
|
||||
if (is_numeric($file_creation_mode))
|
||||
chmod($local_path . $fn, $file_creation_mode);
|
||||
}
|
||||
else
|
||||
@unlink ($_FILES [$filevarname]['tmp_name']);
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function file_size ($filename)
|
||||
{
|
||||
global $local_path;
|
||||
$r = false;
|
||||
if ($filename{0} == '/' &&
|
||||
file_exists($local_path . $filename))
|
||||
$r = filesize ($local_path . $filename);
|
||||
else if (str_starts_with ($filename, 'http://') ||
|
||||
str_starts_with ($filename, 'ftp://'))
|
||||
{
|
||||
$a = @get_headers ($filename, 1);
|
||||
if (isset ($a ['Content-Length']))
|
||||
$r = $a ['Content-Length'];
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
function file_size_string ($bytes)
|
||||
{
|
||||
$r = $bytes;
|
||||
if (is_numeric ($r))
|
||||
{
|
||||
if ($r >= 0 && $r < 1024)
|
||||
$r = $r . ' байт';
|
||||
else if ($r >= 1024 && $r < 1024*1024)
|
||||
$r = sprintf ('%.2f Кб', $r/1024);
|
||||
else if ($r >= 1024*1024 && $r < 1024*1024*1024)
|
||||
$r = sprintf ('%.2f Мб', $r/1024/1024);
|
||||
else if ($r >= 1024*1024*1024)
|
||||
$r = sprintf ('%.2f Гб', $r/1024/1024/1024);
|
||||
else if ($r < 0)
|
||||
$r = sprintf ('%.2f Гб', 2-($r/1024/1024/1024));
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получить данные от URL $url. Если $userpwd задана - тогда будет использована
|
||||
* HTTP аутентификация с логином и паролем, указанными в $userpwd как login:password.
|
||||
* Если данные являются gzip-сжатыми - они будут автоматически распакованы.
|
||||
*/
|
||||
function http_get_contents ($url, $userpwd = false)
|
||||
{
|
||||
global $local_path, $cache_path;
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt ($ch, CURLOPT_URL, $url);
|
||||
curl_setopt ($ch, CURLOPT_HEADER, 0);
|
||||
curl_setopt ($ch, CURLOPT_USERAGENT, 'CommercialRealty/1.0');
|
||||
|
||||
mt_srand ((float)microtime() * 1000000);
|
||||
$eh = $local_path . $cache_path . '/php-' . md5(mt_rand(0,mt_getrandmax())) . '.gz';
|
||||
$fd = fopen ($eh, 'wb');
|
||||
curl_setopt ($ch, CURLOPT_FILE, $fd);
|
||||
|
||||
if (!empty ($userpwd))
|
||||
curl_setopt ($ch, CURLOPT_USERPWD, $userpwd);
|
||||
|
||||
@curl_exec ($ch);
|
||||
curl_close ($ch);
|
||||
fclose ($fd);
|
||||
|
||||
ob_start ();
|
||||
readgzfile ($eh);
|
||||
$data = ob_get_clean ();
|
||||
unlink ($eh);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/* Преобразовать имена некоторых строк в ID некоторых строк */
|
||||
function get_tags($tags, $add_unknown = true, $table = 'tags', $id_field = 'id', $name_field = 'name')
|
||||
{
|
||||
$tagids = array_hashtree(mysql_select($table, "$id_field, LOWER($name_field) $name_field", array($name_field => $tags)), $name_field);
|
||||
$unk = array();
|
||||
foreach ($tags as $t)
|
||||
if (!$tagids[mb_strtolower($t, 'utf-8')])
|
||||
$unk[] = array($name_field => $t);
|
||||
if ($unk && $add_unknown)
|
||||
{
|
||||
mysql_update($table, $unk);
|
||||
$tagids = array_hashtree(mysql_select($table, "$id_field, LOWER($name_field) $name_field", array($name_field => $tags)), $name_field);
|
||||
}
|
||||
foreach ($tags as &$t)
|
||||
if ($tt = $tagids[mb_strtolower($t, 'utf-8')])
|
||||
$t = $tt[0];
|
||||
return $tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Функция возвращает ID значения $v поля $stringfield (по умолчанию поля name), при дополнительных
|
||||
* требованиях $adds = array (поле => значение, ...) и, если такого значения нету, добавляет его в БД.
|
||||
*
|
||||
* Функция работает так:
|
||||
* - если $v пусто (empty($v)==true) - функция возвращает 0 (ибо нефиг);
|
||||
* - ищет, есть ли заданное значение там, где удовлетворены все требования, если есть - всё ок, возвращает его ID;
|
||||
* - по одному с конца ослабляет требования, и если находит соответствующую строку - редактирует её таким образом,
|
||||
* чтобы она соответствовала всем заданным требованиям, и возвращает её ID;
|
||||
* - если такая строка не найдена - добавляет её и возвращает её ID.
|
||||
* - если произошла какая-либо ошибка, она возвращает 0.
|
||||
* - если в найденной записи поле stop != 0 => функция возвращает 0.
|
||||
* полезно, если мы хотим "обучать" функцию не совершать ошибки повторно.
|
||||
*/
|
||||
function stringtable_get_id ($v, $table, $adds, $stringfield = 'name')
|
||||
{
|
||||
$rid = 0;
|
||||
if (!empty ($v))
|
||||
{
|
||||
$v = mysql_ecranize ($v);
|
||||
$addset = array ();
|
||||
if (is_array ($adds))
|
||||
foreach ($adds as $pk => $pf)
|
||||
$addset [] = "`$pk`=" . mysql_ecranize($pf);
|
||||
$search = array_merge (array ("`$stringfield`=$v"), $addset);
|
||||
$change = array ();
|
||||
while (count ($search) > 0)
|
||||
{
|
||||
if (($rid = 0+amquery1x1 ("SELECT `id` FROM `$table` WHERE " . implode (' AND ', $search) . ' LIMIT 1')) > 0)
|
||||
{
|
||||
if (!empty ($change))
|
||||
amysql_query ("UPDATE `$table` SET " . implode (', ', $change) . " WHERE `id`=$rid");
|
||||
break;
|
||||
}
|
||||
$change [] = array_pop ($search);
|
||||
}
|
||||
if (!$rid && amysql_query ("INSERT INTO `$table` SET " . implode (', ', $change)))
|
||||
{
|
||||
$rid = mysql_insert_id ();
|
||||
if (!$rid)
|
||||
$rid = 0+amquery1x1 ("SELECT id FROM `$table` WHERE " . implode (' AND ', $change) . ' LIMIT 1');
|
||||
}
|
||||
if ($rid && acmget ($table, $rid, 'stop') > 0)
|
||||
$rid = 0;
|
||||
}
|
||||
return $rid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Начало сессии :)
|
||||
*/
|
||||
function session_begin($lifetime = -1)
|
||||
{
|
||||
global $Domain, $LoginSession;
|
||||
session_name($LoginSession);
|
||||
list($dom, $path) = explode('/', $Domain, 2);
|
||||
$path = "/$path";
|
||||
session_set_cookie_params($lifetime, $path, '.' . $dom);
|
||||
@session_start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Определение нужного количества итераций блока $block на основе:
|
||||
* sql-запроса $sql ($row[0] это ID и $row[1] это NAME) и
|
||||
* массива $arr (массив сначала).
|
||||
* Функция предназначена для присваивания блоков <select>...</select>
|
||||
* и присвоит "выделено" той опции, которая задана ID-ом $sel_id
|
||||
*/
|
||||
function option_block ($sql, $arr, $sel_id = NULL)
|
||||
{
|
||||
$vars = array();
|
||||
if (is_array ($arr))
|
||||
foreach ($arr as $id => $name)
|
||||
$vars[] = array (
|
||||
'ID' => $id,
|
||||
'NAME' => $name,
|
||||
'SEL' => !is_null($sel_id) && $id == $sel_id ? 'selected' : '',
|
||||
);
|
||||
if (is_string($sql) && ($rows = mysql_get_rows($sql)))
|
||||
{
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
$vars[] = array (
|
||||
'ID' => $row[0],
|
||||
'NAME' => $row[1],
|
||||
'SEL' => !is_null($sel_id) && $row[0] == $sel_id ? 'selected' : '',
|
||||
);
|
||||
}
|
||||
}
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* Данные постраничной навигации внутри $allcount элементов по
|
||||
* $perpage на странице, при том условии что текущий первый отображённый - это $start.
|
||||
* Ссылка на страницу будет getURL($component, $args+array(page => НОМЕР_СТРАНИЦЫ)).
|
||||
* Если задано $eps, то отобразится не более 2*$eps соседних страниц.
|
||||
*/
|
||||
function page_nav3 ($total, $perpage, $start, $component, $args = array(), $eps = NULL, $metanext = 'METAS', $pagearg = 'page')
|
||||
{
|
||||
if ($perpage <= 0 && $total > 0)
|
||||
$perpage = $total;
|
||||
if ($perpage <= 0)
|
||||
$perpage = 1;
|
||||
$curpage = floor($start / $perpage);
|
||||
$pagecount = ceil($total / $perpage);
|
||||
if ($curpage >= $pagecount)
|
||||
$curpage = $pagecount-1;
|
||||
if ($curpage < 0)
|
||||
$curpage = 0;
|
||||
|
||||
$vars = array (
|
||||
'total' => $total,
|
||||
'perpage' => $perpage,
|
||||
'list_start' => $start+1,
|
||||
'page_count' => $pagecount,
|
||||
'list_end' => min($total, $start+$perpage),
|
||||
'page' => array(),
|
||||
'current_page' => $curpage+1,
|
||||
);
|
||||
if ($pagecount < 2)
|
||||
return $vars;
|
||||
|
||||
if ($curpage > 0)
|
||||
{
|
||||
$args[$pagearg] = $curpage-1;
|
||||
$vars['page'][] = array (
|
||||
'name' => '<',
|
||||
'href' => getURL($component, $args),
|
||||
'nc' => true,
|
||||
);
|
||||
}
|
||||
if (is_null($eps))
|
||||
$eps = config_var('page_nav_eps', 10);
|
||||
if ($eps && $eps > 0)
|
||||
{
|
||||
$ppend = min ($pagecount, $curpage + $eps + 1);
|
||||
for ($i = max (0, $curpage - $eps); $i < $ppend; $i++)
|
||||
{
|
||||
$args[$pagearg] = $i;
|
||||
$vars['page'][] = array (
|
||||
'name' => $i+1,
|
||||
'href' => getURL($component, $args),
|
||||
'nc' => $i != $curpage,
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ($i = 0; $i < $pagecount; $i++)
|
||||
{
|
||||
$args[$pagearg] = $i;
|
||||
$vars['page'][] = array (
|
||||
'name' => $i+1,
|
||||
'href' => getURL($component, $args),
|
||||
'nc' => $i != $curpage,
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($curpage < $pagecount-1)
|
||||
{
|
||||
$args[$pagearg] = $curpage+1;
|
||||
if ($metanext)
|
||||
{
|
||||
global $template;
|
||||
$template->tpldata[$metanext] .= '<link rel="next" title="Следующая страница" href="'.getURL($component, $args).'"/>';
|
||||
}
|
||||
$vars['page'][] = array (
|
||||
'name' => '>',
|
||||
'href' => getURL($component, $args),
|
||||
'nc' => true,
|
||||
);
|
||||
}
|
||||
return $vars;
|
||||
}
|
||||
|
||||
function php2js($a)
|
||||
{
|
||||
if (is_null($a)) return 'null';
|
||||
if ($a === false) return 'false';
|
||||
if ($a === true) return 'true';
|
||||
if (is_scalar($a)) {
|
||||
$a = addslashes($a);
|
||||
$a = str_replace("\n", '\n', $a);
|
||||
$a = str_replace("\r", '\r', $a);
|
||||
$a = preg_replace('{(</)(script)}i', "$1'+'$2", $a);
|
||||
return "'$a'";
|
||||
}
|
||||
$isList = true;
|
||||
for ($i=0, reset($a); $i<count($a); $i++, next($a))
|
||||
if (key($a) !== $i) { $isList = false; break; }
|
||||
$result = array();
|
||||
if ($isList) {
|
||||
foreach ($a as $v) $result[] = php2js($v);
|
||||
return '[ ' . join(', ', $result) . ' ]';
|
||||
} else {
|
||||
foreach ($a as $k=>$v)
|
||||
$result[] = php2js($k) . ': ' . php2js($v);
|
||||
return '{ ' . join(', ', $result) . ' }';
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists("quoted_printable_encode"))
|
||||
{
|
||||
define('QP_LINE_LENGTH', 75);
|
||||
define('QP_LINE_SEPARATOR', "\r\n");
|
||||
|
||||
function quoted_printable_encode($string, $encodedWord = false)
|
||||
{
|
||||
if(!preg_match('//u', $string)) {
|
||||
throw new Exception('Input string is not valid UTF-8');
|
||||
}
|
||||
|
||||
static $wordStart = '=?UTF-8?Q?';
|
||||
static $wordEnd = '?=';
|
||||
static $endl = QP_LINE_SEPARATOR;
|
||||
|
||||
$lineLength = $encodedWord
|
||||
? QP_LINE_LENGTH - strlen($wordStart) - strlen($wordEnd)
|
||||
: QP_LINE_LENGTH;
|
||||
|
||||
$string = $encodedWord
|
||||
? preg_replace('~[\r\n]+~', ' ', $string) // we need encoded word to be single line
|
||||
: preg_replace('~\r\n?~', "\n", $string); // normalize line endings
|
||||
$string = preg_replace('~[\x00-\x08\x0B-\x1F]+~', '', $string); // remove control characters
|
||||
|
||||
$output = $encodedWord ? $wordStart : '';
|
||||
$charsLeft = $lineLength;
|
||||
|
||||
$chr = isset($string{0}) ? $string{0} : null;
|
||||
$ord = ord($chr);
|
||||
|
||||
for ($i = 0; isset($chr); $i++) {
|
||||
$nextChr = isset($string{$i + 1}) ? $string{$i + 1} : null;
|
||||
$nextOrd = ord($nextChr);
|
||||
|
||||
if (
|
||||
$ord > 127 or // high byte value
|
||||
$ord === 95 or // underscore "_"
|
||||
$ord === 63 && $encodedWord or // "?" in encoded word
|
||||
$ord === 61 or // equal sign "="
|
||||
// space or tab in encoded word or at line end
|
||||
$ord === 32 || $ord === 9 and $encodedWord || !isset($nextOrd) || $nextOrd === 10
|
||||
) {
|
||||
$chr = sprintf('=%02X', $ord);
|
||||
}
|
||||
|
||||
if ($ord === 10) { // line feed
|
||||
$output .= $endl;
|
||||
$charsLeft = $lineLength;
|
||||
} elseif (
|
||||
strlen($chr) < $charsLeft or
|
||||
strlen($chr) === $charsLeft and $nextOrd === 10 || $encodedWord
|
||||
) { // add character
|
||||
$output .= $chr;
|
||||
$charsLeft-=strlen($chr);
|
||||
} elseif (isset($nextOrd)) { // another line needed
|
||||
$output .= $encodedWord
|
||||
? $wordEnd . $endl . "\t" . $wordStart . $chr
|
||||
: '=' . $endl . $chr;
|
||||
$charsLeft = $lineLength - strlen($chr);
|
||||
}
|
||||
|
||||
$chr = $nextChr;
|
||||
$ord = $nextOrd;
|
||||
}
|
||||
|
||||
return $output . ($encodedWord ? $wordEnd : '');
|
||||
}
|
||||
}
|
||||
|
||||
function is_intval($a)
|
||||
{
|
||||
return (is_string($a) || is_int($a)) && !strcmp(intval($a), $a);
|
||||
}
|
||||
|
||||
function litsplit($re, $s)
|
||||
{
|
||||
$r = array();
|
||||
$s = trim($s);
|
||||
$lit = "\'(?:[^\'\\\\]+|\\.|\'\')+\'|\"(?:[^\"\\\\]+|\\.|\"\")+\"";
|
||||
$offset = 0;
|
||||
$re = "/((?:$lit|.+?)*?)($re)/is";
|
||||
while (preg_match($re, $s, $m, PREG_OFFSET_CAPTURE, $offset))
|
||||
{
|
||||
$r[] = $m[1][0];
|
||||
$offset = $m[0][1] + strlen($m[0][0]);
|
||||
}
|
||||
$s = substr($s, $offset);
|
||||
if (strlen($s))
|
||||
$r[] = $s;
|
||||
return $r;
|
||||
}
|
||||
|
||||
function probe_video($fn)
|
||||
{
|
||||
global $VideoProbe;
|
||||
if (!$VideoProbe || !$VideoProbe['cmd'] || !$VideoProbe['size'] || !$VideoProbe['duration'])
|
||||
die(__FUNCTION__.": \$VideoProbe=array('cmd'=>'shell command','size'=>'size regexp','duration'=>'duration regexp') isn't configured yet");
|
||||
$cmd = $VideoProbe['cmd'];
|
||||
$cmd = str_replace('$input', $fn, $cmd);
|
||||
$out = shell_exec($cmd);
|
||||
$db = array();
|
||||
if (preg_match($VideoProbe['size'], $out, $m))
|
||||
{
|
||||
$db['width'] = $m[1];
|
||||
$db['height'] = $m[2];
|
||||
}
|
||||
if (preg_match($VideoProbe['duration'], $out, $m))
|
||||
{
|
||||
$dur = $m[1];
|
||||
$colon = explode(':', $dur);
|
||||
if (count($colon) > 1)
|
||||
{
|
||||
$dur = 0;
|
||||
for ($mul = 1, $i = 0; $i < count($colon); $i++, $mul *= 60)
|
||||
$dur += $colon[count($colon)-1-$i] * $mul;
|
||||
}
|
||||
$db['duration'] = $dur;
|
||||
}
|
||||
return $db;
|
||||
}
|
||||
|
||||
function extract_video_frame($from, $time, $w, $h, $to)
|
||||
{
|
||||
global $VideoConverter;
|
||||
if (!$VideoConverter)
|
||||
die(__FUNCTION.": \$VideoConverter = 'shell command' isn't configured yet");
|
||||
$cmd = $VideoConverter;
|
||||
$repl = array(
|
||||
'$input' => $from,
|
||||
'$position' => $time,
|
||||
'$output' => $to,
|
||||
);
|
||||
$cmd = str_replace(array_keys($repl), array_values($repl), $cmd);
|
||||
exec($cmd, $output, $exitcode);
|
||||
if ($exitcode != 0)
|
||||
return false;
|
||||
scaleimage($to, $to, $w, $h);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,493 @@
|
|||
<?php
|
||||
|
||||
# Утилитные функции работы с MySQL
|
||||
# (c) VitaliF 2006-2010
|
||||
|
||||
require_once 'config.php';
|
||||
|
||||
define('MS_HASH', 0);
|
||||
define('MS_LIST', 1);
|
||||
define('MS_ROW', 2);
|
||||
define('MS_ONE', 2);
|
||||
define('MS_COL', 4);
|
||||
define('MS_VALUE', 6);
|
||||
define('MS_RESULT', 8);
|
||||
|
||||
$mysql_db_stack = array();
|
||||
$mds_count = 0;
|
||||
|
||||
function mysql_start($allow_nodb = false)
|
||||
{
|
||||
global $mysql_primary_link, $dbhost, $dbuser, $dbpwd, $db;
|
||||
if ($mysql_primary_link) // уже соединено
|
||||
return true;
|
||||
// Соединяемся с MySQL
|
||||
$mysql_primary_link = mysql_pconnect ($dbhost, $dbuser, $dbpwd);
|
||||
if (!$mysql_primary_link)
|
||||
die ('Could not connect to the database: ' . mysql_errno() . ": " . mysql_error());
|
||||
if (!mysql_usedb($db) && !$allow_nodb)
|
||||
return false;
|
||||
amysql_query("SET NAMES utf8");
|
||||
return true;
|
||||
}
|
||||
|
||||
function mysql_usedb($dbn)
|
||||
{
|
||||
global $mysql_db_stack, $mysql_primary_link;
|
||||
$r = true;
|
||||
if (!count($mysql_db_stack) || $mysql_db_stack[count($mysql_db_stack)-1] != $dbn)
|
||||
$r = mysql_select_db ($dbn, $mysql_primary_link);
|
||||
$mysql_db_stack[] = $dbn;
|
||||
return $r;
|
||||
}
|
||||
|
||||
function mysql_unusedb()
|
||||
{
|
||||
global $mysql_db_stack, $mysql_primary_link;
|
||||
if (($n = count($mysql_db_stack)) < 1)
|
||||
return false;
|
||||
$pop = array_pop($mysql_db_stack);
|
||||
if ($n > 1 && $pop != $mysql_db_stack[$n-2])
|
||||
return mysql_select_db($mysql_db_stack[$n-2], $mysql_primary_link);
|
||||
return false;
|
||||
}
|
||||
|
||||
function mysql_started()
|
||||
{
|
||||
global $mysql_primary_link;
|
||||
return is_resource($mysql_primary_link);
|
||||
}
|
||||
|
||||
function amysql_query($q)
|
||||
{
|
||||
global $amy_query_count, $mysql_primary_link, $mysqlQueryLogFile, $mysqlThrowError;
|
||||
if (!mysql_started())
|
||||
mysql_start(false);
|
||||
if (!isset($amy_query_count))
|
||||
$amy_query_count = 0;
|
||||
$amy_query_count++;
|
||||
if ($mysqlQueryLogFile && ($fp = fopen($mysqlQueryLogFile, "ab")))
|
||||
$start = microtime(true);
|
||||
$result = mysql_query($q, $mysql_primary_link);
|
||||
if (!$result && $mysqlThrowError)
|
||||
{
|
||||
debug_print_backtrace();
|
||||
die(mysql_errno().': '.mysql_error());
|
||||
}
|
||||
if ($fp)
|
||||
{
|
||||
$t = microtime(true)-$start;
|
||||
fwrite($fp, date("[Y-m-d H:i:s] ").intval($t/1000).".".($t%1000)." sec $q".(mysql_errno() ? ': ERROR! '.mysql_errno().': '.mysql_error() : '')."\n");
|
||||
fclose($fp);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function amysql_queries($qs, $ignore_errors = true)
|
||||
{
|
||||
$r = true;
|
||||
$qs = explode(';', $qs);
|
||||
foreach ($qs as $q)
|
||||
{
|
||||
$q = trim($q);
|
||||
if ($q != '' && !amysql_query($q))
|
||||
{
|
||||
$r = false;
|
||||
if (!$ignore_errors)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
function amquery1x1($s)
|
||||
{
|
||||
if (($r = amysql_query($s)) && ($r = mysql_fetch_row($r)))
|
||||
return $r[0];
|
||||
return false;
|
||||
}
|
||||
|
||||
function mysql_ecranize($s)
|
||||
{
|
||||
global $mysql_primary_link;
|
||||
if (!$mysql_primary_link)
|
||||
mysql_start();
|
||||
if (is_null($s))
|
||||
return "NULL";
|
||||
return "'" . mysql_real_escape_string($s) . "'";
|
||||
}
|
||||
|
||||
function mysql_time($dat, $tim, $format)
|
||||
{
|
||||
return @date($format, mktime (substr ($tim, 0, 2), substr ($tim, 3, 2), substr ($tim, 6, 2), substr($dat,5,2), substr($dat,8,2), substr($dat,0,4)));
|
||||
}
|
||||
|
||||
// Дополнить кэш таблицы $table с помощью запроса $q
|
||||
function cmcache($table, $q)
|
||||
{
|
||||
global $mysql_php_cache;
|
||||
$cnt = 0;
|
||||
$r = amysql_query($q);
|
||||
if ($r)
|
||||
{
|
||||
while ($row = mysql_fetch_assoc ($r))
|
||||
{
|
||||
$mysql_php_cache [$table][$row['id']] = $row;
|
||||
$cnt++;
|
||||
}
|
||||
}
|
||||
return $cnt;
|
||||
}
|
||||
|
||||
// Функция кэширующего чтения поля field из записи номер id таблицы table: "table/id/field"
|
||||
// Кэш можно заполнять предыдущей функцией, хотя эта и сама может кэшировать записи по одной
|
||||
function acmget($table, $id, $field)
|
||||
{
|
||||
global $mysql_php_cache, $cfgTables;
|
||||
if ($cfgTables[$table])
|
||||
$table = $cfgTables[$table];
|
||||
if (!isset ($mysql_php_cache[$table][$id][$field]) &&
|
||||
cmcache ($table, "SELECT * FROM `$table` WHERE `id`=$id LIMIT 1") < 1)
|
||||
return false;
|
||||
return $mysql_php_cache[$table][$id][$field];
|
||||
}
|
||||
|
||||
function cmchainmatch($table, $parent_field, $start, $field, $value)
|
||||
{
|
||||
while (($new = acmget($table, $start, $field)) != $value && $start > 0)
|
||||
$start = $new;
|
||||
if (acmget($table, $start, $field) == $value)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function mysql_where_builder($where)
|
||||
{
|
||||
$wh = array();
|
||||
foreach ($where as $k => $v)
|
||||
{
|
||||
if (is_numeric($k))
|
||||
$wh[] = $v;
|
||||
else if (is_array($v))
|
||||
{
|
||||
if (!$v)
|
||||
{
|
||||
debug_print_backtrace();
|
||||
die("Error: empty array for '$k IN (...)', don't know what to do");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (is_array($v[0]))
|
||||
foreach ($v as &$l)
|
||||
$l = "(" . implode(",", array_map('mysql_ecranize', $l)) . ")";
|
||||
else
|
||||
$v = array_map('mysql_ecranize', $v);
|
||||
$wh[] = "$k IN (" . implode(",", $v) . ")";
|
||||
}
|
||||
}
|
||||
elseif (!is_null($v))
|
||||
$wh[] = "$k=".mysql_ecranize($v);
|
||||
else
|
||||
$wh[] = "$k IS NULL";
|
||||
}
|
||||
if (!$wh)
|
||||
$where = '1';
|
||||
else
|
||||
$where = '(' . join(') AND (', $wh) . ')';
|
||||
return $where;
|
||||
}
|
||||
|
||||
function mysql_select_builder($tables, $fields, $where, $options = NULL)
|
||||
{
|
||||
if (!$options)
|
||||
$options = array();
|
||||
else
|
||||
{
|
||||
foreach ($options as $k => $v)
|
||||
if (is_intval($k))
|
||||
$options[$v] = true;
|
||||
}
|
||||
if (is_array($fields))
|
||||
$fields = join(',', $fields);
|
||||
if (is_array($where))
|
||||
$where = mysql_where_builder($where);
|
||||
$tables = mysql_tables_builder($tables);
|
||||
$sql = 'SELECT ';
|
||||
if ($options['CALC_FOUND_ROWS'] || $options['SQL_CALC_FOUND_ROWS'])
|
||||
$sql .= 'SQL_CALC_FOUND_ROWS ';
|
||||
$sql .= "$fields FROM $tables WHERE $where";
|
||||
if ($g = $options['GROUP BY'])
|
||||
{
|
||||
if (is_array($g))
|
||||
{
|
||||
$g1 = array();
|
||||
foreach ($g as $k => $v)
|
||||
{
|
||||
if (is_numeric($k))
|
||||
$g1[] = $v;
|
||||
else
|
||||
$g1[] = "$k $v";
|
||||
}
|
||||
$g = join(',', $g1);
|
||||
}
|
||||
$sql .= " GROUP BY $g";
|
||||
}
|
||||
if ($g = $options['ORDER BY'])
|
||||
{
|
||||
if (is_array($g))
|
||||
{
|
||||
$g1 = array();
|
||||
foreach ($g as $k => $v)
|
||||
{
|
||||
if (is_numeric($k))
|
||||
$g1[] = $v;
|
||||
else
|
||||
$g1[] = "$k $v";
|
||||
}
|
||||
$g = join(',', $g1);
|
||||
}
|
||||
$sql .= " ORDER BY $g";
|
||||
}
|
||||
if ($g = $options['LIMIT'])
|
||||
{
|
||||
if (is_array($g))
|
||||
$g = join(',', $g);
|
||||
if ($g)
|
||||
$sql .= " LIMIT $g";
|
||||
}
|
||||
if ($options['FOR UPDATE'])
|
||||
$sql .= ' FOR UPDATE';
|
||||
elseif ($options['LOCK IN SHARE MODE'])
|
||||
$sql .= ' LOCK IN SHARE MODE';
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function mysql_tables_builder($tables)
|
||||
{
|
||||
global $cfgTables;
|
||||
if (is_array($tables))
|
||||
{
|
||||
$t = array();
|
||||
foreach ($tables as $k => $v)
|
||||
{
|
||||
if (!is_numeric($k))
|
||||
$v = ($cfgTables[$v] ? '`'.$cfgTables[$v].'`' : $v) . ' ' . $k;
|
||||
else
|
||||
$v = ($cfgTables[$v] ? '`'.$cfgTables[$v].'` '.$v : $v);
|
||||
$t[] = $v;
|
||||
}
|
||||
$tables = join(',', $t);
|
||||
}
|
||||
else
|
||||
$tables = preg_replace_callback('/((?:,|JOIN)\s*`)([^`]+)/s', 'mysql_tables_builder_pregcb1', $tables);
|
||||
return $tables;
|
||||
}
|
||||
|
||||
function mysql_tables_builder_pregcb1($m)
|
||||
{
|
||||
global $cfgTables;
|
||||
$t = $cfgTables[$m[2]];
|
||||
if (!$t)
|
||||
$t = $m[2];
|
||||
return $m[1].$t;
|
||||
}
|
||||
|
||||
function mysql_select($tables, $fields = '*', $where = 1, $options = NULL, $format = 0)
|
||||
{
|
||||
if (!strcmp(intval($fields), "$fields"))
|
||||
{
|
||||
$sql = $tables;
|
||||
$format = $fields;
|
||||
}
|
||||
else
|
||||
$sql = mysql_select_builder($tables, $fields, $where, $options);
|
||||
if ($format & MS_RESULT)
|
||||
return amysql_query($sql);
|
||||
if ($format & MS_LIST)
|
||||
$r = mysql_get_rows($sql);
|
||||
else
|
||||
$r = mysql_get_assocs($sql);
|
||||
if (!$r)
|
||||
$r = array();
|
||||
if ($format & MS_ROW)
|
||||
{
|
||||
if ($format & MS_COL)
|
||||
{
|
||||
if (!count($r))
|
||||
return NULL;
|
||||
$r = $r[0];
|
||||
$k = array_keys($r);
|
||||
$r = $r[$k[0]];
|
||||
}
|
||||
else
|
||||
$r = $r[0];
|
||||
}
|
||||
elseif ($format & MS_COL)
|
||||
{
|
||||
foreach ($r as $i => $v)
|
||||
{
|
||||
if (!$k)
|
||||
{
|
||||
$k = array_keys($v);
|
||||
$k = $k[0];
|
||||
}
|
||||
$r[$i] = $v[$k];
|
||||
}
|
||||
}
|
||||
return $r;
|
||||
}
|
||||
|
||||
function mysql_found_rows()
|
||||
{
|
||||
return mysql_select('SELECT FOUND_ROWS()', MS_VALUE);
|
||||
}
|
||||
|
||||
function mysql_delete($tables, $where, $options = NULL)
|
||||
{
|
||||
global $mysql_primary_link;
|
||||
$tables = mysql_tables_builder($tables);
|
||||
if (is_array($where))
|
||||
$where = mysql_where_builder($where);
|
||||
$sql = "DELETE FROM $tables WHERE $where";
|
||||
if (is_array($options))
|
||||
{
|
||||
if ($g = $options['LIMIT'])
|
||||
{
|
||||
if (is_array($g))
|
||||
$g = join(',', $g);
|
||||
if ($g)
|
||||
$sql .= " LIMIT $g";
|
||||
}
|
||||
}
|
||||
amysql_query($sql);
|
||||
return mysql_affected_rows($mysql_primary_link);
|
||||
}
|
||||
|
||||
function mysql_insert_builder($table, $rows, $onduplicatekey = false)
|
||||
{
|
||||
global $cfgTables;
|
||||
if ($cfgTables[$table])
|
||||
$table = $cfgTables[$table];
|
||||
$key = array_keys($rows[0]);
|
||||
foreach ($rows as &$r)
|
||||
{
|
||||
$rs = array();
|
||||
foreach ($key as &$k)
|
||||
$rs[] = mysql_ecranize($r[$k]);
|
||||
$r = "(".implode(",", $rs).")";
|
||||
}
|
||||
foreach ($key as &$k)
|
||||
if (strpos($k, '`') === false)
|
||||
$k = "`$k`";
|
||||
$sql = "INSERT INTO $table (".implode(",",$key).") VALUES ".implode(",",$rows);
|
||||
if ($onduplicatekey)
|
||||
{
|
||||
foreach ($key as &$k)
|
||||
$k = "$k=VALUES($k)";
|
||||
$sql .= " ON DUPLICATE KEY UPDATE ".implode(",",$key);
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
|
||||
function mysql_insert_row($table, $row)
|
||||
{
|
||||
global $mysql_primary_link;
|
||||
$sql = mysql_insert_builder($table, array($row));
|
||||
if (amysql_query($sql))
|
||||
return mysql_insert_id($mysql_primary_link);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
function mysql_update($table, $rows, $where = NULL, $options = NULL)
|
||||
{
|
||||
global $mysql_primary_link;
|
||||
if (!$rows)
|
||||
return false;
|
||||
if (is_null($where))
|
||||
{
|
||||
if (!is_array($rows))
|
||||
return false;
|
||||
if (!is_array($rows[0]))
|
||||
$rows = array($rows);
|
||||
$sql = mysql_insert_builder($table, $rows, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$sql = array();
|
||||
if (!is_array($rows))
|
||||
$rows = array($rows);
|
||||
foreach ($rows as $k => $v)
|
||||
{
|
||||
if (!is_intval($k))
|
||||
$sql[] = $k.'='.mysql_ecranize($v);
|
||||
else
|
||||
$sql[] = $v;
|
||||
}
|
||||
if (is_array($where))
|
||||
$where = mysql_where_builder($where);
|
||||
$sql = 'UPDATE ' . mysql_tables_builder($table) . ' SET ' . implode(', ', $sql) . ' WHERE ' . $where;
|
||||
if (is_array($options))
|
||||
{
|
||||
if ($g = $options['LIMIT'])
|
||||
{
|
||||
if (is_array($g))
|
||||
$g = join(',', $g);
|
||||
if ($g)
|
||||
$sql .= " LIMIT $g";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (amysql_query($sql))
|
||||
return mysql_affected_rows($mysql_primary_link);
|
||||
return false;
|
||||
}
|
||||
|
||||
function mysql_get_rows($sql)
|
||||
{
|
||||
$r = array();
|
||||
if (is_resource($res = $sql) || ($res = amysql_query ($sql)))
|
||||
while ($row = mysql_fetch_row ($res))
|
||||
$r[] = $row;
|
||||
return $r;
|
||||
}
|
||||
|
||||
function mysql_get_assocs($sql)
|
||||
{
|
||||
$r = array();
|
||||
if (is_resource($res = $sql) || ($res = amysql_query ($sql)))
|
||||
while ($row = mysql_fetch_assoc ($res))
|
||||
$r[] = $row;
|
||||
return $r;
|
||||
}
|
||||
|
||||
function load_config()
|
||||
{
|
||||
global $engine_configuration, $mysqlNoSiteConfig;
|
||||
if ($mysqlNoSiteConfig)
|
||||
return;
|
||||
$engine_configuration = array();
|
||||
if ($rows = mysql_select('config', array('name', 'value'), 1, array(), MS_LIST))
|
||||
foreach ($rows as $row)
|
||||
$engine_configuration[$row[0]] = $row[1];
|
||||
}
|
||||
|
||||
function config_var($name, $default = NULL)
|
||||
{
|
||||
global $engine_configuration;
|
||||
if (!$engine_configuration)
|
||||
load_config();
|
||||
$v = @$engine_configuration[$name];
|
||||
if (!is_null($default) && !strlen($v) || is_intval($default) && $v <= 0)
|
||||
$v = $default;
|
||||
elseif (is_intval($default))
|
||||
$v = intval($v);
|
||||
return $v;
|
||||
}
|
||||
|
||||
function mysql_finish()
|
||||
{
|
||||
global $mysql_primary_link;
|
||||
if (mysql_started())
|
||||
mysql_close($mysql_primary_link);
|
||||
$mysql_primary_link = NULL;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
# Создание глобального объекта шаблона и определение наиболее общих его переменных
|
||||
# (c) VitaliF 2006-2010
|
||||
|
||||
require_once 'config.php';
|
||||
require_once 'template.php';
|
||||
require_once 'mysql.php';
|
||||
|
||||
if (!defined('LIGHTWEIGHT'))
|
||||
{
|
||||
header("Cache-Control: no-cache");
|
||||
header("Pragma: no-cache");
|
||||
header("Expires: Thu, 01 Jan 1970 12:00:00 GMT");
|
||||
}
|
||||
|
||||
$tpl = config_var('template');
|
||||
if ($tpl == '')
|
||||
$tpl = 'default';
|
||||
$template = new Template (array(
|
||||
'root' => $local_path . $template_path . $tpl,
|
||||
'cache_dir' => $local_path . $cache_path,
|
||||
'print_error' => 1,
|
||||
));
|
||||
$template->vars(array(
|
||||
'DOMAIN' => "http://$Domain",
|
||||
));
|
|
@ -0,0 +1,288 @@
|
|||
<?php
|
||||
|
||||
# Простая OLAPообразная статистика
|
||||
# admin_olap.tpl, admin_olap_csv.tpl
|
||||
# (c) Vitaliy Filippov 2010
|
||||
|
||||
$is_adm = true;
|
||||
require_once 'lib/templating.php';
|
||||
|
||||
require_once 'olap_config.php';
|
||||
|
||||
OLAP::execute($_REQUEST);
|
||||
exit;
|
||||
|
||||
class OLAP
|
||||
{
|
||||
static $sources;
|
||||
static $current_srcid, $current_src;
|
||||
static $functions = array(
|
||||
'year' => array('name' => 'Год', 'time' => true),
|
||||
'month' => array('name' => 'Месяц', 'time' => true),
|
||||
'day' => array('name' => 'Дата', 'time' => true),
|
||||
'weekday' => array('name' => 'День недели', 'time' => true),
|
||||
'week' => array('name' => '№ недели', 'time' => true),
|
||||
);
|
||||
static $aggregates = array(
|
||||
'distinct' => array('name' => 'Значения', 'cell_only' => true),
|
||||
'count' => array('name' => 'Количество'),
|
||||
'sum' => array('name' => 'Сумма'),
|
||||
'avg' => array('name' => 'Среднее'),
|
||||
'min' => array('name' => 'Минимум'),
|
||||
'max' => array('name' => 'Максимум'),
|
||||
);
|
||||
static $specf = array('v_field', 'v_func', 'h_field', 'h_func', 'cell_field', 'cell_aggr', 'cell_func', 'v_sort_dir', 'v_sort_field', 'v_sort_aggr', 'v_sort_func', 'h_sort_dir', 'h_sort_field', 'h_sort_aggr', 'h_sort_func');
|
||||
|
||||
static function execute($request)
|
||||
{
|
||||
global $template;
|
||||
set_time_limit(300);
|
||||
$time_start = microtime(true);
|
||||
$template->compiletime_functions['fformat'] = "OLAP::tpl_field_format";
|
||||
self::$current_srcid = $request['datasource'];
|
||||
self::$current_src = self::$sources[self::$current_srcid];
|
||||
$template->vars('sources', array_values(self::$sources));
|
||||
if (!self::$current_src)
|
||||
{
|
||||
$template->vars('select', true);
|
||||
print $template->parse('admin_olap.tpl');
|
||||
exit;
|
||||
}
|
||||
foreach (self::$current_src['fielddescs'] as $k => &$v)
|
||||
{
|
||||
$v['id'] = $k;
|
||||
if ($v['options'])
|
||||
foreach ($v['options'] as &$o)
|
||||
$v['options_hash'][$o['id']] = $o['name'];
|
||||
}
|
||||
foreach (self::$functions as $k => &$v)
|
||||
$v['id'] = $k;
|
||||
foreach (self::$aggregates as $k => &$v)
|
||||
$v['id'] = $k;
|
||||
unset($v);
|
||||
|
||||
$wh = array();
|
||||
$where = array();
|
||||
foreach ($request as $k => $t)
|
||||
{
|
||||
if (substr($k, 0, 5) == 'type-')
|
||||
{
|
||||
$i = substr($k, 5);
|
||||
$f = $request["field-$i"];
|
||||
$v = $request["value-$i"];
|
||||
$fd = self::$current_src['fielddescs'][$f];
|
||||
if (!strlen($v))
|
||||
continue;
|
||||
$wh["type-$i"] = $t;
|
||||
$wh["field-$i"] = $f;
|
||||
$wh["value-$i"] = $v;
|
||||
if ($fd['is_time'])
|
||||
$v = Template::timestamp($v, self::$current_src['fielddefs'][$f]['format']);
|
||||
$dn = $fd['dbname'];
|
||||
if (!$dn)
|
||||
$dn = $f;
|
||||
if ($t == 'eq')
|
||||
$where[$dn] = $v;
|
||||
elseif ($t == 'ge')
|
||||
$where[] = "$dn >= ".mysql_ecranize($v);
|
||||
elseif ($t == 'le')
|
||||
$where[] = "$dn <= ".mysql_ecranize($v);
|
||||
}
|
||||
}
|
||||
|
||||
$template->vars(array(
|
||||
'wh' => $wh,
|
||||
'srcid' => self::$current_srcid,
|
||||
'src' => self::$current_src,
|
||||
'fielddescs' => array_values(self::$current_src['fielddescs']),
|
||||
'functions' => array_values(self::$functions),
|
||||
'aggregates' => array_values(self::$aggregates),
|
||||
));
|
||||
|
||||
if (!$request['build'])
|
||||
{
|
||||
$vars = array();
|
||||
foreach (self::$specf as $f)
|
||||
$vars[$f] = $$f;
|
||||
$template->vars($vars);
|
||||
print $template->parse('admin_olap.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = mysql_select(self::$current_src['tables'], self::$current_src['fields'], array_merge(self::$current_src['where'], $where), self::$current_src['options'], MS_RESULT);
|
||||
|
||||
foreach(self::$specf as $x)
|
||||
$$x = $request[$x];
|
||||
|
||||
$group = array();
|
||||
$hkeys = array();
|
||||
$v_v = '';
|
||||
$v_h = '';
|
||||
$fetch = self::$current_src['fetch_row'] ? 'mysql_fetch_row' : 'mysql_fetch_assoc';
|
||||
|
||||
$code = 'while($r = '.$fetch.'($result)) {';
|
||||
if ($v_field !== '')
|
||||
{
|
||||
$code .= '$v_v = ';
|
||||
if ($v_func !== '')
|
||||
$code .= 'self::transform_'.$v_func.'(&$r, $v_field);';
|
||||
else
|
||||
$code .= '$r[$v_field];';
|
||||
}
|
||||
if ($h_field !== '')
|
||||
{
|
||||
$code .= '$v_h = ';
|
||||
if ($h_func !== '')
|
||||
$code .= 'self::transform_'.$h_func.'(&$r, $h_field);';
|
||||
else
|
||||
$code .= '$r[$h_field];';
|
||||
}
|
||||
$code .= '$v_c = ';
|
||||
if ($cell_func !== '')
|
||||
$code .= 'self::transform_'.$cell_func.'(&$r, $cell_field);';
|
||||
else
|
||||
$code .= '$r[$cell_field];';
|
||||
$code .= '$hkeys[$v_h] = 1;';
|
||||
$code .= 'self::aggr_update_'.$cell_aggr.'(&$group[$v_v][$v_h], &$v_c);';
|
||||
if ($v_field !== '' && $v_sort_aggr !== '' && $v_sort_field !== '')
|
||||
{
|
||||
$code .= '$v_vs = ';
|
||||
if ($v_sort_func !== '')
|
||||
$code .= 'self::transform_'.$v_sort_func.'(&$r, $v_sort_field);';
|
||||
else
|
||||
$code .= '$r[$v_sort_field];';
|
||||
$code .= 'self::aggr_update_'.$v_sort_aggr.'(&$vsort[$v_v], &$v_vs);';
|
||||
}
|
||||
if ($h_field !== '' && $h_sort_aggr !== '' && $h_sort_field !== '')
|
||||
{
|
||||
$code .= '$v_hs = ';
|
||||
if ($h_sort_func !== '')
|
||||
$code .= 'self::transform_'.$h_sort_func.'(&$r, $h_sort_field);';
|
||||
else
|
||||
$code .= '$r[$h_sort_field];';
|
||||
$code .= 'self::aggr_update_'.$h_sort_aggr.'(&$vsort[$v_h], &$v_hs);';
|
||||
}
|
||||
$code .= '}';
|
||||
|
||||
eval($code);
|
||||
|
||||
if (is_callable("OLAP::aggr_finish_$cell_aggr"))
|
||||
foreach ($group as $i => &$r)
|
||||
foreach ($r as $j => &$c)
|
||||
call_user_func_array("OLAP::aggr_finish_$cell_aggr", array(&$c));
|
||||
|
||||
if ($v_field !== '' && $v_sort_aggr !== '' && $v_sort_field !== '' && is_callable("OLAP::aggr_finish_$v_sort_aggr"))
|
||||
foreach ($vsort as $v => &$c)
|
||||
call_user_func_array("OLAP::aggr_finish_$v_sort_aggr", array(&$c));
|
||||
|
||||
if ($h_field !== '' && $h_sort_aggr !== '' && $h_sort_field !== '' && is_callable("OLAP::aggr_finish_$h_sort_aggr"))
|
||||
foreach ($hsort as $v => &$c)
|
||||
call_user_func_array("OLAP::aggr_finish_$h_sort_aggr", array(&$c));
|
||||
|
||||
$hkeys = array_keys($hkeys);
|
||||
self::do_sort($hkeys, $hsort, $h_sort_dir);
|
||||
|
||||
$vkeys = array_keys($group);
|
||||
self::do_sort($vkeys, $vsort, $v_sort_dir);
|
||||
|
||||
$vars = array(
|
||||
'build' => 1,
|
||||
'hkeys' => $hkeys,
|
||||
'vkeys' => $vkeys,
|
||||
'hsort' => $hsort,
|
||||
'vsort' => $vsort,
|
||||
'data' => $group,
|
||||
'rpt_link' => "?".http_build_query($_GET+$_POST),
|
||||
'csv_link' => "?csv=1&".http_build_query($_GET+$_POST),
|
||||
'memory' => file_size_string(memory_get_usage()),
|
||||
'time_elapsed' => sprintf("%.3f", microtime(true)-$time_start),
|
||||
);
|
||||
|
||||
foreach (self::$specf as $f)
|
||||
$vars[$f] = $$f;
|
||||
|
||||
$template->vars($vars);
|
||||
if ($request['csv'])
|
||||
{
|
||||
self::$is_html_format = false;
|
||||
header("Content-Type: text/csv; charset=windows-1251");
|
||||
header("Content-Disposition: inline; filename=OLAP-".date('YmdHis').".csv");
|
||||
$out = $template->parse('admin_olap_csv.tpl');
|
||||
print iconv("utf-8", "windows-1251", $out);
|
||||
}
|
||||
else
|
||||
print $template->parse('admin_olap.tpl');
|
||||
}
|
||||
|
||||
static function do_sort(&$values, &$sortvalues, &$sort_dir)
|
||||
{
|
||||
$fn = 'sort';
|
||||
$sort_dir = strtolower($sort_dir);
|
||||
if ($sort_dir == 'desc')
|
||||
$fn = 'rsort';
|
||||
if ($sortvalues)
|
||||
{
|
||||
$ufn = $sort_dir == 'desc' ? "OLAP::custom_reverse_cmp" : "OLAP::custom_sort_cmp";
|
||||
self::$sort = &$sortvalues;
|
||||
usort($values, $ufn);
|
||||
}
|
||||
else
|
||||
$fn($values);
|
||||
}
|
||||
|
||||
static $sort;
|
||||
static function custom_sort_cmp($a, $b)
|
||||
{
|
||||
return self::$sort[$a] < self::$sort[$b] ? -1 : (self::$sort[$a] > self::$sort[$b] ? 1 : 0);
|
||||
}
|
||||
static function custom_reverse_cmp($a, $b)
|
||||
{
|
||||
return self::$sort[$a] > self::$sort[$b] ? -1 : (self::$sort[$a] < self::$sort[$b] ? 1 : 0);
|
||||
}
|
||||
|
||||
static $is_html_format = true;
|
||||
static function field_format($field, $func, $aggr, $value)
|
||||
{
|
||||
$o = &self::$current_src['fielddescs'][$field]['options_hash'];
|
||||
if ($aggr == 'distinct')
|
||||
{
|
||||
$r = '';
|
||||
foreach($value as $k => $n)
|
||||
$r .= self::field_format($field, $func, false, $k).': '.$n.(self::$is_html_format ? "<br />" : "")."\n";
|
||||
return $r;
|
||||
}
|
||||
elseif ($o && $o[$value])
|
||||
return $o[$value];
|
||||
$fn = self::$is_html_format ? 'htmlspecialchars' : 'addslashes';
|
||||
return $fn($value);
|
||||
}
|
||||
|
||||
static function tpl_field_format($field, $func, $aggr, $value)
|
||||
{
|
||||
return "OLAP::field_format($field, $func, $aggr, $value)";
|
||||
}
|
||||
|
||||
static function o_tsformat($f, &$row, $field)
|
||||
{
|
||||
$tf = "_t$field";
|
||||
if (!$row[$tf])
|
||||
$row[$tf] = Template::timestamp($row[$field]);
|
||||
return date($f, $row[$tf]);
|
||||
}
|
||||
|
||||
/* Агрегатные функции и преобразования */
|
||||
|
||||
static function transform_year(&$row, $field) { return self::o_tsformat('Y', $row, $field); }
|
||||
static function transform_month(&$row, $field) { return self::o_tsformat('Y-m', $row, $field); }
|
||||
static function transform_day(&$row, $field) { return self::o_tsformat('Y-m-d', $row, $field); }
|
||||
static function transform_weekday(&$row, $field) { return self::o_tsformat('N', $row, $field); }
|
||||
static function transform_week(&$row, $field) { return self::o_tsformat('W', $row, $field); }
|
||||
|
||||
static function aggr_update_count(&$n, &$v) { $n++; }
|
||||
static function aggr_update_sum(&$sum, &$v) { $sum += $v; }
|
||||
static function aggr_update_avg(&$avg, &$v) { $avg['n']++; $avg['s'] += $v; }
|
||||
static function aggr_finish_avg(&$avg) { $avg = $avg['s']/$avg['n']; }
|
||||
static function aggr_update_min(&$min, &$v) { if ($min > $v) $min = $v; }
|
||||
static function aggr_update_max(&$max, &$v) { if ($max < $v) $max = $v; }
|
||||
static function aggr_update_distinct(&$d, &$v) { $d[$v]++; }
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
OLAP::$sources = array(
|
||||
'v2tags' => array(
|
||||
'id' => 'v2tags',
|
||||
'name' => 'VitaphotoV2, статистика по тегам',
|
||||
'tables' => array('t' => 'stats_tag_all'),
|
||||
'fields' => 't.ts, t.tag',
|
||||
'where' => array(),
|
||||
'fetch_row' => true,
|
||||
'fielddescs' => array(
|
||||
#'ts'
|
||||
0 => array(
|
||||
'name' => 'Время',
|
||||
'le_ge' => true,
|
||||
'is_time' => true,
|
||||
'format' => TS_UNIX,
|
||||
'dbname' => 'ts',
|
||||
),
|
||||
#'tag'
|
||||
1 => array(
|
||||
'name' => 'Тег',
|
||||
'dbname' => 'tag',
|
||||
'options' => array_merge(array('id' => 0, 'name' => '*'), mysql_select('tags', 'id, name', array('type' => 0))),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
|
@ -0,0 +1,10 @@
|
|||
<!--# script language="JavaScript">
|
||||
AjexFileManager.init({
|
||||
path: '/admin/afm/',
|
||||
editor: CKEDITOR
|
||||
});
|
||||
</script>-->
|
||||
</div>
|
||||
<p id="admpoweredby" style="color: #d0d0d0; margin: 20px 0 0 20px">Powered by VitaliF, 2010</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>{title/s}</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
{METAS}
|
||||
<style>
|
||||
<!--
|
||||
html, body, form, table, input, select, textarea { margin: 0; font-family: sans-serif; font-size: 13px; }
|
||||
html, form, table, input, select { padding: 0; }
|
||||
img { border: 0; }
|
||||
body { padding: 8px; }
|
||||
select, textarea { border: 1px solid black; }
|
||||
input:not([type="radio"]):not([type="checkbox"]) { border: 1px solid black; }
|
||||
h1 { text-indent: 20px; font-family: Trebuchet MS; font-size: 20px; font-weight: bold; }
|
||||
p { margin: 4px 0; }
|
||||
.rbborder { border-width: 0 1px 1px 0; border-color: gray; border-style: solid; }
|
||||
.themes { padding: 8px; text-align: left; }
|
||||
.themes ul { list-style-type: none; padding: 0; margin: 4px 0; display: block; }
|
||||
.themes li { padding: 0; display: inline; margin-right: 8px; }
|
||||
.simpletable, .simpletable td { border: 1px solid black; }
|
||||
.simpletable { border-collapse: collapse; }
|
||||
.simpletable th { padding: 3px 8px; }
|
||||
.simpletable td { padding: 3px; }
|
||||
#middle ul.list div.right { float: left; }
|
||||
-->
|
||||
</style>
|
||||
<script language="JavaScript" type="text/javascript" src="{DOMAIN}/tpldata/lightbox.js"></script>
|
||||
<!-- IF NOT nock -->
|
||||
<script type="text/javascript" language="JavaScript" src="{DOMAIN}/ckeditor/ckeditor.js"></script>
|
||||
<!--#<script type="text/javascript" language="JavaScript" src="{DOMAIN}/admin/afm/ajex.js"></script> -->
|
||||
<!-- END -->
|
||||
<link rel="stylesheet" type="text/css" href="{DOMAIN}/tpldata/lightbox.css" />
|
||||
</head>
|
||||
<body {body_args}>
|
||||
<div id="admcontent">
|
||||
<!-- IF NOT notitle --><h1><!-- IF detailtitle -->{detailtitle}<!-- ELSE -->{title}<!-- END --></h1><!-- END -->
|
|
@ -0,0 +1,166 @@
|
|||
<!-- SET title -->Статистика<!-- END -->
|
||||
<!-- INCLUDE admin_header.tpl -->
|
||||
<!-- IF NOT srcid -->
|
||||
<p>Добро пожаловать в простую OLAPообразную статистику. Выберите источник данных:</p>
|
||||
<form action="?" method="GET">
|
||||
<select style="width:100px" name="datasource">
|
||||
<!-- FOR s = sources -->
|
||||
<option value="{s s.id}">{s s.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<input type="submit" value=" Продолжить " />
|
||||
</form>
|
||||
<!-- ELSE -->
|
||||
<p>Выбранный источник данных: <b>{s src.name}</b>. <a href="?">Выбрать другой источник данных</a>.</p>
|
||||
<p>Настройте желаемый отчёт:</p>
|
||||
<form action="?" method="GET">
|
||||
<input type="hidden" name="datasource" value="{s src.id}" />
|
||||
<input type="hidden" name="build" value="1" />
|
||||
<table>
|
||||
<tr><td style="text-align: center; vertical-align: middle"><input type="submit" value=" Построить отчёт " /></td><td style="background-color: #e0e0e0; padding: 8px">
|
||||
По горизонтали:<br />
|
||||
<select style="width:100px" name="h_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="h_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select><br />
|
||||
Сортировка:<br />
|
||||
<select style="width:100px" name="h_sort_dir">
|
||||
<option value="asc">по возрастанию</option>
|
||||
<option value="desc"<!-- IF eq(h_sort_dir, 'desc') --> selected<!-- END -->>по убыванию</option>
|
||||
</select>
|
||||
<select style="width:100px" name="h_sort_aggr">
|
||||
<option value="">по значениям поля</option>
|
||||
<!-- FOR f = aggregates -->
|
||||
<!-- IF NOT f.cell_only -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_sort_aggr, f.id) --> selected<!-- END -->>{s f.name} другого поля:</option>
|
||||
<!-- END -->
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="h_sort_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_sort_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="h_sort_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(h_sort_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
</td></tr>
|
||||
<tr><td style="background-color: #e0e0e0; padding: 8px">
|
||||
По вертикали:<br />
|
||||
<select style="width:100px" name="v_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="v_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select><br />
|
||||
Сортировка:<br />
|
||||
<select style="width:100px" name="v_sort_dir">
|
||||
<option value="asc">по возрастанию</option>
|
||||
<option value="desc"<!-- IF eq(v_sort_dir, 'desc') --> selected<!-- END -->>по убыванию</option>
|
||||
</select>
|
||||
<select style="width:100px" name="v_sort_aggr">
|
||||
<option value="">по значениям поля</option>
|
||||
<!-- FOR f = aggregates -->
|
||||
<!-- IF NOT f.cell_only -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_sort_aggr, f.id) --> selected<!-- END -->>{s f.name} другого поля:</option>
|
||||
<!-- END -->
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="v_sort_field">
|
||||
<option value="">---</option>
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_sort_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="v_sort_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(v_sort_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
</td><td style="background-color: #ffe0e0; padding: 8px">
|
||||
В таблице:<br />
|
||||
<select style="width:100px" name="cell_aggr">
|
||||
<!-- FOR f = aggregates -->
|
||||
<option value="{s f.id}"<!-- IF eq(cell_aggr, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="cell_field">
|
||||
<!-- FOR f = fielddescs -->
|
||||
<option value="{s f.id}"<!-- IF eq(cell_field, f.id) --> selected<!-- END -->>{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<select style="width:100px" name="cell_func">
|
||||
<option value="">без преобразования</option>
|
||||
<!-- FOR f = functions -->
|
||||
<option value="{s f.id}"<!-- IF eq(cell_func, f.id) --> selected<!-- END -->><!-- IF f.time -->(время) <!-- END -->{s f.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
</td></tr>
|
||||
</table>
|
||||
Условия выборки данных:
|
||||
<table>
|
||||
<!-- SET i = "0" -->
|
||||
<!-- FOR f = fielddescs -->
|
||||
<tr><th style="text-align: left; vertical-align: top">{s f.name}</th>
|
||||
<td style="text-align: left; vertical-align: top">
|
||||
= <input type="hidden" name="field-{i}" value="{s f.id}" /><input type="hidden" name="type-{i}" value="eq" />
|
||||
<!-- IF f.options -->
|
||||
<select style="width: 100px" name="value-{i}">
|
||||
<option value="">любой</option>
|
||||
<!-- FOR o = f.options -->
|
||||
<option value="{s o.id}">{s o.name}</option>
|
||||
<!-- END -->
|
||||
</select>
|
||||
<!-- ELSE -->
|
||||
<input style="width: 100px" type="text" name="value-{i}" value="{s get(wh,concat('value-',i))}" />
|
||||
<!-- END -->
|
||||
<!-- SET i = add(i,1) -->
|
||||
<!-- IF f.le_ge -->
|
||||
или ≥ <input type="hidden" name="field-{i}" value="{s f.id}" /><input type="hidden" name="type-{i}" value="ge" /><input style="width: 100px" type="text" name="value-{i}" value="{s get(wh,concat('value-',i))}" /><!-- SET i = add(i,1) -->
|
||||
и ≤ <input type="hidden" name="field-{i}" value="{s f.id}" /><input type="hidden" name="type-{i}" value="le" /><input style="width: 100px" type="text" name="value-{i}" value="{s get(wh,concat('value-',i))}" /><!-- SET i = add(i,1) -->
|
||||
<!-- END -->
|
||||
<!-- IF f.is_time --> (YYYY-MM-DD HH:MM:SS)<!-- END -->
|
||||
<!-- IF eq(concat('',f.id),'in_trust') --> (0-9)<!-- END -->
|
||||
</td></tr>
|
||||
<!-- END -->
|
||||
</table>
|
||||
</form>
|
||||
<!-- IF build -->
|
||||
<h1>Отчёт</h1>
|
||||
<p><a href="{s rpt_link}">Ссылка на данный отчёт</a> | <a href="{s csv_link}">В формате CSV</a></p>
|
||||
<!-- IF NOT data -->
|
||||
<p>Нет данных для показа.</p>
|
||||
<!-- ELSE -->
|
||||
<table class="simpletable">
|
||||
<tr><th></th><!-- FOR k = hkeys --><th>{fformat(h_field,h_func,'',k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
|
||||
<!-- FOR v = vkeys -->
|
||||
<tr><th>{fformat(v_field,v_func,'',v)}</th><!-- FOR k = hkeys --><td>{fformat(cell_field,cell_func,cell_aggr,get(get(data,v),k))}</td><!-- END --><!-- IF vsort --><th>{get(vsort,v)}</th><!-- END --></tr>
|
||||
<!-- END -->
|
||||
<!-- IF hsort -->
|
||||
<tr><th></th><!-- FOR k = hkeys --><th>{get(hsort,k)}</th><!-- END --><!-- IF vsort --><th></th><!-- END --></tr>
|
||||
<!-- END -->
|
||||
</table>
|
||||
<p>Отчёт занял {time_elapsed} сек. Использовано {memory} памяти для работы.</p>
|
||||
<!-- END -->
|
||||
<!-- END -->
|
||||
<!-- END -->
|
||||
<!-- INCLUDE admin_footer.tpl -->
|
|
@ -0,0 +1,4 @@
|
|||
<!-- FOR k = hkeys -->;"{fformat(h_field,h_func,'',k)}"<!-- END -->
|
||||
<!-- FOR v = vkeys -->
|
||||
"{fformat(v_field,v_func,'',v)}"<!-- FOR k = hkeys -->;"{fformat(cell_field,cell_func,cell_aggr,get(get(data,v),k))}"<!-- END -->
|
||||
<!-- END -->
|
Loading…
Reference in New Issue