mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-06-26 03:30:48 +03:00
Plugins вынесены в корень сайта, управление файла перенесено в админпанель.
This commit is contained in:
parent
65bc1d85d9
commit
2a469a9275
122
classes/actions/ActionAdmin.class.php
Normal file
122
classes/actions/ActionAdmin.class.php
Normal file
|
@ -0,0 +1,122 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Класс обработки УРЛа вида /comments/
|
||||
*
|
||||
*/
|
||||
class ActionAdmin extends Action {
|
||||
|
||||
/**
|
||||
* Главное меню
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $sMenuHeadItemSelect='admin';
|
||||
|
||||
public function Init() {
|
||||
if(!$this->User_IsAuthorization() or !$oUserCurrent=$this->User_GetUserCurrent() or !$oUserCurrent->isAdministrator()) {
|
||||
return parent::EventNotFound();
|
||||
}
|
||||
|
||||
$this->oUserCurrent=$oUserCurrent;
|
||||
}
|
||||
|
||||
protected function RegisterEvent() {
|
||||
$this->AddEvent('plugins','EventPlugins');
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
|
||||
**********************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
protected function EventPlugins() {
|
||||
$this->sMenuHeadItemSelect='plugins';
|
||||
/**
|
||||
* Обработка удаления плагинов
|
||||
*/
|
||||
if (isPost('submit_plugins_del')) {
|
||||
$this->Security_ValidateSendForm();
|
||||
|
||||
$aPluginsDelete=getRequest('plugins_del');
|
||||
if (is_array($aPluginsDelete)) {
|
||||
$this->Plugin_Delete(array_keys($aPluginsDelete));
|
||||
}
|
||||
}
|
||||
|
||||
if($sPlugin=getRequest('plugin',null,'get') and $sAction=getRequest('action',null,'get')) {
|
||||
return $this->SubmitManagePlugin($sPlugin,$sAction);
|
||||
}
|
||||
/**
|
||||
* Передан ли номер страницы
|
||||
*/
|
||||
$iPage= preg_match("/^\d+$/i",$this->GetEventMatch(2)) ? $this->GetEventMatch(2) : 1;
|
||||
/**
|
||||
* Получаем список блогов
|
||||
*/
|
||||
$aPlugins=$this->Plugin_GetList();
|
||||
/**
|
||||
* Загружаем переменные в шаблон
|
||||
*/
|
||||
$this->Viewer_Assign("aPlugins",$aPlugins);
|
||||
$this->Viewer_AddHtmlTitle($this->Lang_Get('plugins_administartion_title'));
|
||||
/**
|
||||
* Устанавливаем шаблон вывода
|
||||
*/
|
||||
$this->SetTemplateAction('plugins');
|
||||
}
|
||||
|
||||
/**
|
||||
* Активация\деактивация плагина
|
||||
*
|
||||
* @param string $sPlugin
|
||||
* @param string $sAction
|
||||
*/
|
||||
protected function SubmitManagePlugin($sPlugin,$sAction) {
|
||||
if(!in_array($sAction,array('activate','deactivate'))) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('plugins_unknown_action'),$this->Lang_Get('error'),true);
|
||||
Router::Location(Router::GetPath('plugins'));
|
||||
}
|
||||
/**
|
||||
* Активируем\деактивируем плагин
|
||||
*/
|
||||
if($bResult=$this->Plugin_Toggle($sPlugin,$sAction)) {
|
||||
$this->Message_AddNotice($this->Lang_Get('plugins_action_ok'),$this->Lang_Get('attention'),true);
|
||||
} else {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('system_error'),$this->Lang_Get('error'),true);
|
||||
}
|
||||
/**
|
||||
* Возвращаем на страницу управления плагинами
|
||||
*/
|
||||
Router::Location(Router::GetPath('admin').'plugins/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Выполняется при завершении работы экшена
|
||||
*
|
||||
*/
|
||||
public function EventShutdown() {
|
||||
/**
|
||||
* Загружаем в шаблон необходимые переменные
|
||||
*/
|
||||
$this->Viewer_Assign('sMenuHeadItemSelect',$this->sMenuHeadItemSelect);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -1,5 +1,5 @@
|
|||
{include file='header.tpl' noShowSystemMessage=false}
|
||||
<script type="text/javascript" src="{cfg name='path.root.web'}/classes/plugins/profiler/templates/skin/default/js/profiler.js"></script>
|
||||
<script type="text/javascript" src="{cfg name='path.root.web'}/plugins/profiler/templates/skin/default/js/profiler.js"></script>
|
||||
|
||||
<div class="topic people top-blogs talk-table">
|
||||
<h1>{$aLang.profiler_reports_title}</h1>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{include file='header.tpl' noShowSystemMessage=false}
|
||||
<script type="text/javascript" src="{cfg name='path.root.web'}/classes/plugins/profiler/templates/skin/new/js/profiler.js"></script>
|
||||
<script type="text/javascript" src="{cfg name='path.root.web'}/plugins/profiler/templates/skin/new/js/profiler.js"></script>
|
||||
|
||||
<div class="topic people top-blogs talk-table">
|
||||
<h1>{$aLang.profiler_reports_title}</h1>
|
||||
|
|
|
@ -287,7 +287,7 @@ $config['router']['page']['link'] = 'ActionLink';
|
|||
$config['router']['page']['question'] = 'ActionQuestion';
|
||||
$config['router']['page']['blogs'] = 'ActionBlogs';
|
||||
$config['router']['page']['search'] = 'ActionSearch';
|
||||
$config['router']['page']['plugins'] = 'ActionPlugins';
|
||||
$config['router']['page']['admin'] = 'ActionAdmin';
|
||||
// Глобальные настройки роутинга
|
||||
$config['router']['config']['action_default'] = 'index';
|
||||
$config['router']['config']['action_not_found'] = 'error';
|
||||
|
|
|
@ -127,10 +127,10 @@ if(file_exists(Config::Get('path.root.server').'/config/config.stable.php')) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Загружает конфиги плагинов вида /classes/plugins/[plugin_name]/config/*.php
|
||||
* и include-файлы /classes/plugins/[plugin_name]/include/*.php
|
||||
* Загружает конфиги плагинов вида /plugins/[plugin_name]/config/*.php
|
||||
* и include-файлы /plugins/[plugin_name]/include/*.php
|
||||
*/
|
||||
$sPluginsDir = Config::Get('path.root.server').'/classes/plugins';
|
||||
$sPluginsDir = Config::Get('path.root.server').'/plugins';
|
||||
$sPluginsListFile = $sPluginsDir.'/plugins.dat';
|
||||
if($aPluginsList=@file($sPluginsListFile)) {
|
||||
foreach ($aPluginsList as $sPlugin) {
|
||||
|
|
|
@ -46,11 +46,11 @@ abstract class ActionPlugin extends Action {
|
|||
* Проверяем в списке шаблонов
|
||||
*/
|
||||
$aMatches[1]=strtolower($aMatches[1]);
|
||||
$sTemplateName=in_array(Config::Get('view.skin'),array_map('basename',glob(Config::Get('path.root.server').'/classes/plugins/'.$aMatches[1].'/templates/skin/*',GLOB_ONLYDIR)))
|
||||
$sTemplateName=in_array(Config::Get('view.skin'),array_map('basename',glob(Config::Get('path.root.server').'/plugins/'.$aMatches[1].'/templates/skin/*',GLOB_ONLYDIR)))
|
||||
? Config::Get('view.skin')
|
||||
: 'default';
|
||||
|
||||
$this->sTemplatePathAction=Config::Get('path.root.server')."/classes/plugins/{$aMatches[1]}/templates/skin/{$sTemplateName}";
|
||||
$this->sTemplatePathAction=Config::Get('path.root.server')."/plugins/{$aMatches[1]}/templates/skin/{$sTemplateName}";
|
||||
}
|
||||
|
||||
return $this->sTemplatePathAction;
|
||||
|
|
|
@ -174,7 +174,7 @@ class Engine extends Object {
|
|||
/**
|
||||
* Это модуль плагина
|
||||
*/
|
||||
$sModuleFile = Config::Get('path.root.server').'/classes/plugins/'.strtolower($aMatches[1]).'/classes/modules/'.strtolower($aMatches[2]).'/'.$aMatches[2].'.class.php';
|
||||
$sModuleFile = Config::Get('path.root.server').'/plugins/'.strtolower($aMatches[1]).'/classes/modules/'.strtolower($aMatches[2]).'/'.$aMatches[2].'.class.php';
|
||||
if($this->isFileExists($sModuleFile)) {
|
||||
require_once($sModuleFile);
|
||||
} else {
|
||||
|
@ -247,9 +247,9 @@ class Engine extends Object {
|
|||
*
|
||||
*/
|
||||
protected function InitPluginHooks() {
|
||||
if($aPluginList = @file(Config::Get('path.root.server').'/classes/plugins/plugins.dat')) {
|
||||
if($aPluginList = @file(Config::Get('path.root.server').'/plugins/plugins.dat')) {
|
||||
$aFiles=array();
|
||||
$sDirHooks=Config::Get('path.root.server').'/classes/plugins/';
|
||||
$sDirHooks=Config::Get('path.root.server').'/plugins/';
|
||||
|
||||
foreach ($aPluginList as $sPluginName) {
|
||||
$aFiles=glob($sDirHooks.$sPluginName.'/classes/hooks/Hook*.class.php');
|
||||
|
@ -272,9 +272,9 @@ class Engine extends Object {
|
|||
*
|
||||
*/
|
||||
protected function InitPlugins() {
|
||||
if($aPluginList = @file(Config::Get('path.root.server').'/classes/plugins/plugins.dat')) {
|
||||
if($aPluginList = @file(Config::Get('path.root.server').'/plugins/plugins.dat')) {
|
||||
foreach ($aPluginList as $sPluginName) {
|
||||
$sDirPlugins=Config::Get('path.root.server').'/classes/plugins/';
|
||||
$sDirPlugins=Config::Get('path.root.server').'/plugins/';
|
||||
$sFile="{$sDirPlugins}{$sPluginName}/Plugin{$sPluginName}.class.php";
|
||||
if(is_file($sFile)) {
|
||||
require_once($sFile);
|
||||
|
@ -431,11 +431,11 @@ class Engine extends Object {
|
|||
//$sFileClass=Config::get('path.root.server').'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.'.((self::$aEntityCustoms[$sName]=='custom')?'custom.':'').'php';
|
||||
} else {
|
||||
$sFileDefaultClass=isset($sPlugin)
|
||||
? Config::get('path.root.server').'/classes/plugins/'.strtolower($sPlugin).'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.php'
|
||||
? Config::get('path.root.server').'/plugins/'.strtolower($sPlugin).'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.php'
|
||||
: Config::get('path.root.server').'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.php';
|
||||
|
||||
$sFileCustomClass=isset($sPlugin)
|
||||
? Config::get('path.root.server').'/classes/plugins/'.strtolower($sPlugin).'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.custom.php'
|
||||
? Config::get('path.root.server').'/plugins/'.strtolower($sPlugin).'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.custom.php'
|
||||
: Config::get('path.root.server').'/classes/modules/'.strtolower($sModule).'/entity/'.$sEntity.'.entity.class.custom.php';
|
||||
|
||||
/**
|
||||
|
|
|
@ -167,7 +167,7 @@ class Router extends Object {
|
|||
$sPrefixCustom='_custom';
|
||||
}
|
||||
} else {
|
||||
require_once(Config::Get('path.root.server').'/classes/plugins/'.strtolower($aMatches[1]).'/classes/actions/Action'.ucfirst($aMatches[2]).'.class.php');
|
||||
require_once(Config::Get('path.root.server').'/plugins/'.strtolower($aMatches[1]).'/classes/actions/Action'.ucfirst($aMatches[2]).'.class.php');
|
||||
$sPrefixCustom='';
|
||||
}
|
||||
|
||||
|
|
|
@ -113,8 +113,8 @@ class LsLang extends Module {
|
|||
/**
|
||||
* Ищет языковые файлы актвиированных плагинов
|
||||
*/
|
||||
if($aPluginList = @file(Config::Get('path.root.server').'/classes/plugins/plugins.dat')) {
|
||||
$sDir=Config::Get('path.root.server').'/classes/plugins/';
|
||||
if($aPluginList = @file(Config::Get('path.root.server').'/plugins/plugins.dat')) {
|
||||
$sDir=Config::Get('path.root.server').'/plugins/';
|
||||
|
||||
foreach ($aPluginList as $sPluginName) {
|
||||
$aFiles=glob($sDir.$sPluginName.'/templates/language/'.$sLangName.'.php');
|
||||
|
|
|
@ -52,7 +52,7 @@ class LsPlugin extends Module {
|
|||
*
|
||||
*/
|
||||
public function Init() {
|
||||
$this->sPluginsDir=Config::Get('path.root.server').'/classes/plugins/';
|
||||
$this->sPluginsDir=Config::Get('path.root.server').'/plugins/';
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -171,7 +171,7 @@ class LsViewer extends Module {
|
|||
* Создаём объект Smarty и устанавливаем необходиму параметры
|
||||
*/
|
||||
$this->oSmarty = new Smarty();
|
||||
$this->oSmarty->template_dir=array(Config::Get('path.smarty.template'),Config::Get('path.root.server').'/classes/plugins/');
|
||||
$this->oSmarty->template_dir=array(Config::Get('path.smarty.template'),Config::Get('path.root.server').'/plugins/');
|
||||
/**
|
||||
* Для каждого скина устанавливаем свою директорию компиляции шаблонов
|
||||
*/
|
||||
|
|
|
@ -36,7 +36,7 @@ function smarty_insert_block($aParams,&$oSmarty) {
|
|||
require_once(Config::Get('path.root.server').'/engine/classes/ActionPlugin.class.php');
|
||||
|
||||
$sBlockTemplate = rtrim($aParams['params']['dir'],'/').'/block.'.$aParams['block'].'.tpl';
|
||||
$sBlockClass = Config::Get('path.root.server').'/classes/plugins/'.$aParams['params']['plugin'].'/blocks/Block'.$sBlock.'.class.php';
|
||||
$sBlockClass = Config::Get('path.root.server').'/plugins/'.$aParams['params']['plugin'].'/blocks/Block'.$sBlock.'.class.php';
|
||||
$sCmd='$oBlock=new Plugin'.ucfirst($aParams['params']['plugin']).'_Block'.$sBlock.'($aParamsBlock);';
|
||||
} else {
|
||||
$sBlockTemplate = 'block.'.$aParams['block'].'.tpl';
|
||||
|
|
0
plugins/plugins.dat
Normal file
0
plugins/plugins.dat
Normal file
28
plugins/profiler/PluginProfiler.class.php
Normal file
28
plugins/profiler/PluginProfiler.class.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
class PluginProfiler extends Plugin {
|
||||
/**
|
||||
* Активация плагина Профайлер.
|
||||
* Создание таблицы в базе данных при ее отсутствии.
|
||||
*/
|
||||
public function Activate() {
|
||||
$this->ExportSQL(dirname(__FILE__).'/sql.sql');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
267
plugins/profiler/classes/actions/ActionProfiler.class.php
Normal file
267
plugins/profiler/classes/actions/ActionProfiler.class.php
Normal file
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Обрабатывает вывод отчетов профилирования
|
||||
*
|
||||
*/
|
||||
class PluginProfiler_ActionProfiler extends ActionPlugin {
|
||||
/**
|
||||
* Текущий юзер
|
||||
*
|
||||
* @var UserEntity_User
|
||||
*/
|
||||
protected $oUserCurrent=null;
|
||||
|
||||
/**
|
||||
* Инициализация
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function Init() {
|
||||
/**
|
||||
* Проверяем авторизован ли юзер
|
||||
*/
|
||||
if (!$this->User_IsAuthorization()) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('not_access'));
|
||||
return Router::Action('error');
|
||||
}
|
||||
/**
|
||||
* Получаем текущего юзера
|
||||
*/
|
||||
$this->oUserCurrent=$this->User_GetUserCurrent();
|
||||
/**
|
||||
* Проверяем является ли юзер администратором
|
||||
*/
|
||||
if (!$this->oUserCurrent->isAdministrator()) {
|
||||
$this->Message_AddErrorSingle($this->Lang_Get('not_access'));
|
||||
return Router::Action('error');
|
||||
}
|
||||
|
||||
$this->SetDefaultEvent('report');
|
||||
}
|
||||
|
||||
protected function RegisterEvent() {
|
||||
$this->AddEvent('report','EventReport');
|
||||
$this->AddEvent('ajaxloadreport','EventAjaxLoadReport');
|
||||
$this->AddEvent('ajaxloadentriesbyfilter','EventAjaxLoadEntriesByFilter');
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
************************ РЕАЛИЗАЦИЯ ЭКШЕНА ***************************************
|
||||
**********************************************************************************
|
||||
*/
|
||||
|
||||
protected function EventReport() {
|
||||
/**
|
||||
* Обработка удаления отчетов профайлера
|
||||
*/
|
||||
if (isPost('submit_report_delete')) {
|
||||
$this->Security_ValidateSendForm();
|
||||
|
||||
$aReportsId=getRequest('report_del');
|
||||
if (is_array($aReportsId)) {
|
||||
if($this->PluginProfiler_Profiler_DeleteEntryByRequestId(array_keys($aReportsId))) {
|
||||
$this->Message_AddNotice($this->Lang_Get('profiler_report_delete_success'), $this->Lang_Get('attention'));
|
||||
} else {
|
||||
$this->Message_AddError($this->Lang_Get('profiler_report_delete_error'), $this->Lang_Get('error'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Если вызвана обработка upload`а логов в базу данных
|
||||
*/
|
||||
if(getRequest('submit_profiler_import') and getRequest('profiler_date_import')) {
|
||||
$iCount = @$this->PluginProfiler_Profiler_UploadLog(date('Y-m-d H:i:s',strtotime(getRequest('profiler_date_import'))));
|
||||
if(!is_null($iCount)) {
|
||||
$this->Message_AddNotice($this->Lang_Get('profiler_import_report_success',array('count'=>$iCount)), $this->Lang_Get('attention'));
|
||||
} else {
|
||||
$this->Message_AddError($this->Lang_Get('profiler_import_report_error'), $this->Lang_Get('error'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Составляем фильтр для просмотра отчетов
|
||||
*/
|
||||
$aFilter=$this->BuildFilter();
|
||||
|
||||
/**
|
||||
* Передан ли номер страницы
|
||||
*/
|
||||
$iPage=preg_match("/^page(\d+)$/i",$this->getParam(0),$aMatch) ? $aMatch[1] : 1;
|
||||
/**
|
||||
* Получаем список отчетов
|
||||
*/
|
||||
$aResult=$this->PluginProfiler_Profiler_GetReportsByFilter($aFilter,$iPage,Config::Get('plugin.profiler.per_page'));
|
||||
$aReports=$aResult['collection'];
|
||||
/**
|
||||
* Если был использован фильтр, выводим количество найденых по фильтру
|
||||
*/
|
||||
if(count($aFilter)) {
|
||||
$this->Message_AddNotice(
|
||||
($aResult['count'])
|
||||
? $this->Lang_Get('profiler_filter_result_count',array('count'=>$aResult['count']))
|
||||
: $this->Lang_Get('profiler_filter_result_empty')
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Формируем постраничность
|
||||
*/
|
||||
$aPaging=$this->Viewer_MakePaging(
|
||||
$aResult['count'],$iPage,Config::Get('plugin.profiler.per_page'),4,
|
||||
Router::GetPath('profiler').$this->sCurrentEvent,
|
||||
array_intersect_key(
|
||||
$_REQUEST,
|
||||
array_fill_keys(array('start','end','request_id','time','per_page'), '')
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Загружаем переменные в шаблон
|
||||
*/
|
||||
$this->Viewer_Assign('aPaging',$aPaging);
|
||||
$this->Viewer_Assign('aReports',$aReports);
|
||||
$this->Viewer_Assign('aDatabaseStat',($aData=$this->PluginProfiler_Profiler_GetDatabaseStat())?$aData:array('max_date'=>'','count'=>''));
|
||||
$this->Viewer_AddBlock('right',$this->getTemplatePathAction().'/actions/ActionProfiler/sidebar.tpl');
|
||||
$this->Viewer_AddHtmlTitle($this->Lang_Get('profiler_report_page_title'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Формирует из REQUEST массива фильтр для отбора отчетов
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function BuildFilter() {
|
||||
$aFilter = array();
|
||||
|
||||
if($start=getRequest('start')) {
|
||||
if(func_check($start,'text',6,10) && substr_count($start,'.')==2) {
|
||||
list($d,$m,$y)=explode('.',$start);
|
||||
if(@checkdate($m,$d,$y)) {
|
||||
$aFilter['date_min']="{$y}-{$m}-{$d}";
|
||||
} else {
|
||||
$this->Message_AddError(
|
||||
$this->Lang_Get('profiler_filter_error_date_format'),
|
||||
$this->Lang_Get('profiler_filter_error')
|
||||
);
|
||||
unset($_REQUEST['start']);
|
||||
}
|
||||
} else {
|
||||
$this->Message_AddError(
|
||||
$this->Lang_Get('profiler_filter_error_date_format'),
|
||||
$this->Lang_Get('profiler_filter_error')
|
||||
);
|
||||
unset($_REQUEST['start']);
|
||||
}
|
||||
}
|
||||
|
||||
if($end=getRequest('end')) {
|
||||
if(func_check($end,'text',6,10) && substr_count($end,'.')==2) {
|
||||
list($d,$m,$y)=explode('.',$end);
|
||||
if(@checkdate($m,$d,$y)) {
|
||||
$aFilter['date_max']="{$y}-{$m}-{$d} 23:59:59";
|
||||
} else {
|
||||
$this->Message_AddError(
|
||||
$this->Lang_Get('profiler_filter_error_date_format'),
|
||||
$this->Lang_Get('profiler_filter_error')
|
||||
);
|
||||
unset($_REQUEST['end']);
|
||||
}
|
||||
} else {
|
||||
$this->Message_AddError(
|
||||
$this->Lang_Get('profiler_filter_error_date_format'),
|
||||
$this->Lang_Get('profiler_filter_error')
|
||||
);
|
||||
unset($_REQUEST['end']);
|
||||
}
|
||||
}
|
||||
|
||||
if($iTimeFull=getRequest('time') and $iTimeFull>0) {
|
||||
$aFilter['time']=$iTimeFull;
|
||||
}
|
||||
|
||||
if($iPerPage=getRequest('per_page',0) and $iPerPage>0) {
|
||||
Config::Set('plugins.profiler.per_page',$iPerPage);
|
||||
}
|
||||
return $aFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Подгрузка данных одного профиля по ajax-запросу
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected function EventAjaxLoadReport() {
|
||||
$this->Viewer_SetResponseAjax();
|
||||
|
||||
$sReportId=str_replace('report_','',getRequest('reportId',null,'post'));
|
||||
$bTreeView=getRequest('bTreeView',false,'post');
|
||||
$sParentId=getRequest('parentId',null,'post');
|
||||
|
||||
$oViewerLocal=$this->Viewer_GetLocalViewer();
|
||||
$oViewerLocal->Assign('oReport',$this->PluginProfiler_Profiler_GetReportById($sReportId,$sParentId));
|
||||
if(!$sParentId) $oViewerLocal->Assign('sAction','tree');
|
||||
|
||||
$sTemplateName = ($bTreeView)
|
||||
? (($sParentId)
|
||||
? 'level'
|
||||
: 'tree')
|
||||
:'report';
|
||||
$this->Viewer_AssignAjax('sReportText',$oViewerLocal->Fetch($this->getTemplatePathAction()."/actions/ActionProfiler/ajax/{$sTemplateName}.tpl", 'profiler'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Подгрузка данных одного профиля по ajax-запросу
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected function EventAjaxLoadEntriesByFilter() {
|
||||
$this->Viewer_SetResponseAjax();
|
||||
|
||||
$sAction = $this->GetParam(0);
|
||||
$sReportId=str_replace('report_','',getRequest('reportId',null,'post'));
|
||||
|
||||
$oViewerLocal=$this->Viewer_GetLocalViewer();
|
||||
$oViewerLocal->Assign('sAction',$sAction);
|
||||
|
||||
$oReport = $this->PluginProfiler_Profiler_GetReportById($sReportId,($sAction=='tree')?0:null);
|
||||
|
||||
/**
|
||||
* Преобразуем report взависимости от выбранного фильтра
|
||||
*/
|
||||
switch ($sAction) {
|
||||
case 'query':
|
||||
$oReport->setAllEntries($oReport->getEntriesByName('query'));
|
||||
break;
|
||||
}
|
||||
$oViewerLocal->Assign('oReport',$oReport);
|
||||
|
||||
$sTemplateName=($sAction=='tree')?'tree':'report';
|
||||
$this->Viewer_AssignAjax('sReportText',$oViewerLocal->Fetch($this->getTemplatePathAction()."/actions/ActionProfiler/ajax/{$sTemplateName}.tpl", "profiler"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Завершение работы Action`a
|
||||
*
|
||||
*/
|
||||
public function EventShutdown() {
|
||||
|
||||
}
|
||||
}
|
||||
?>
|
252
plugins/profiler/classes/modules/profiler/Profiler.class.php
Normal file
252
plugins/profiler/classes/modules/profiler/Profiler.class.php
Normal file
|
@ -0,0 +1,252 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__));
|
||||
require_once('mapper/Profiler.mapper.class.php');
|
||||
|
||||
/**
|
||||
* Модуль статических страниц
|
||||
*
|
||||
*/
|
||||
class PluginProfiler_Profiler extends Module {
|
||||
/**
|
||||
* Меппер для сохранения логов в базу данных и формирования выборок по данным из базы
|
||||
*
|
||||
* @var Mapper_Profiler
|
||||
*/
|
||||
protected $oMapper;
|
||||
|
||||
/**
|
||||
* Хендлер открытого файла лога
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $hLog;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $sDataDelimiter = "\t";
|
||||
|
||||
/**
|
||||
* Инициализация модуля
|
||||
*/
|
||||
public function Init() {
|
||||
$this->oMapper=new PluginProfiler_Mapper_Profiler($this->Database_GetConnect());
|
||||
$this->hLog = @fopen(Config::Get('path.root.server').'/logs/'.Config::Get('sys.logs.profiler_file'),'r+');
|
||||
}
|
||||
|
||||
/**
|
||||
* Добавить новую запись в базу данных
|
||||
*
|
||||
* @param PluginProfiler_ProfilerEntity_Entry $oEntry
|
||||
* @return bool
|
||||
*/
|
||||
public function AddEntry(PluginProfiler_ProfilerEntity_Entry $oEntry) {
|
||||
return $this->oMapper->AddEntry($oEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Читает из лог-файла записи
|
||||
*
|
||||
* @param string $sPath
|
||||
* @return PluginProfiler_ProfilerEntity_Entry
|
||||
*/
|
||||
public function ReadEntry() {
|
||||
/**
|
||||
* Если хендлер не определен, или лог закончен, вовращаем null
|
||||
*/
|
||||
if(!$this->hLog or feof($this->hLog)) return null;
|
||||
/**
|
||||
* Читаем следующую строку и формируем объект Entry
|
||||
*/
|
||||
$sLine=fgets($this->hLog);
|
||||
if(!$sLine) return null;
|
||||
|
||||
$aTime = array();
|
||||
list(
|
||||
$aTime['request_date'],$aTime['request_id'],$aTime['time_full'],
|
||||
$aTime['time_start'],$aTime['time_stop'],$aTime['time_id'],
|
||||
$aTime['time_pid'],$aTime['time_name'],$aTime['time_comment']
|
||||
)=explode($this->sDataDelimiter,$sLine,9);
|
||||
|
||||
return Engine::GetEntity('PluginProfiler_Profiler_Entry',$aTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Выгружает записи из лога в базу данных
|
||||
*
|
||||
* @param string $sDateStart
|
||||
* @param string $sPath
|
||||
* @return bool|int
|
||||
*/
|
||||
public function UploadLog($sDateStart,$sPath=null) {
|
||||
if($sPath) $this->hLog = @fopen($sPath,'r+');
|
||||
if(!$this->hLog) return null;
|
||||
|
||||
rewind($this->hLog);
|
||||
|
||||
$iCount=0;
|
||||
while($oEntry=$this->ReadEntry()) {
|
||||
if(strtotime($oEntry->getDate())>strtotime($sDateStart)){
|
||||
$this->AddEntry($oEntry);
|
||||
$iCount++;
|
||||
}
|
||||
unset($oEntry);
|
||||
}
|
||||
return $iCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает дату последней записи профайлера в базе данных
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetDatabaseStat() {
|
||||
return $this->oMapper->GetDatabaseStat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Очищает файл лога
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function EraseLog() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает записи профайлера из базы данных, группированных по уровню "Report"
|
||||
* TODO: Реализовать кеширование данных
|
||||
*
|
||||
* @param array $aFilter
|
||||
* @param int $iPage
|
||||
* @param int $iPerPage
|
||||
* @return array
|
||||
*/
|
||||
public function GetReportsByFilter($aFilter,$iPage,$iPerPage) {
|
||||
$data=array(
|
||||
'collection'=>$this->oMapper->GetReportsByFilter($aFilter,$iCount,$iPage,$iPerPage),
|
||||
'count'=>$iCount
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает профайл-отчет по идентификатору
|
||||
* TODO: доработать система вывода записей в виде дерева
|
||||
*
|
||||
* @param int $sId
|
||||
* @return ProfileEntity_Report
|
||||
*/
|
||||
public function GetReportById($sId,$sPid=null) {
|
||||
$aReportRows=$this->oMapper->GetReportById($sId,$sPid);
|
||||
if(count($aReportRows)) {
|
||||
/**
|
||||
* Если запрошена часть записей, отдельно получаем статистику общей выборки
|
||||
*/
|
||||
$aStat = !is_null($sPid)
|
||||
? $this->GetReportStatById($sId)
|
||||
: array(
|
||||
'count' => 0,
|
||||
'query' => 0,
|
||||
'modules' => array(),
|
||||
'time_full' => 0
|
||||
);
|
||||
|
||||
$oReport = Engine::GetEntity('PluginProfiler_Profiler_Report');
|
||||
$aEntries = $this->BuildEntriesRecursive($aReportRows);
|
||||
foreach ($aEntries as $oEntry) {
|
||||
$oReport->addEntry($oEntry);
|
||||
if(is_null($sPid)) {
|
||||
/**
|
||||
* Заполняем статистику
|
||||
*/
|
||||
$aStat['count']++;
|
||||
$aStat['time_full']=max($aStat['time_full'],$oEntry->getTimeFull());
|
||||
if($oEntry->getName()=='query') $aStat['query']++;
|
||||
}
|
||||
}
|
||||
|
||||
$oReport->setStat($aStat);
|
||||
return $oReport;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Получает статистику данного отчета
|
||||
* (количество замеров, общее время, количество запросов к БД, используемые модули)
|
||||
*
|
||||
* @param string $sId
|
||||
* @return array
|
||||
*/
|
||||
public function GetReportStatById($sId) {
|
||||
$aStat = array(
|
||||
'count' => 0,
|
||||
'query' => 0,
|
||||
'modules' => array(),
|
||||
'time_full' => 0
|
||||
);
|
||||
|
||||
$aReportRows=$this->oMapper->GetReportStatById($sId);
|
||||
foreach ($aReportRows as $aEntry) {
|
||||
$aStat['count']++;
|
||||
$aStat['time_full']=max($aStat['time_full'],$aEntry['time_full']);
|
||||
/**
|
||||
* Является ли запросом
|
||||
*/
|
||||
if($aEntry['time_name']=='query') $aStat['query']++;
|
||||
}
|
||||
return $aStat;
|
||||
}
|
||||
|
||||
protected function BuildEntriesRecursive($aEntries,$bBegin=true) {
|
||||
static $aResultEntries;
|
||||
static $iLevel;
|
||||
if ($bBegin) {
|
||||
$aResultEntries=array();
|
||||
$iLevel=0;
|
||||
}
|
||||
foreach ($aEntries as $aEntry) {
|
||||
$aTemp=$aEntry;
|
||||
$aTemp['level']=$iLevel;
|
||||
unset($aTemp['childNodes']);
|
||||
$aResultEntries[]=Engine::GetEntity('PluginProfiler_Profiler_Entry',$aTemp);
|
||||
if (isset($aEntry['childNodes']) and count($aEntry['childNodes'])>0) {
|
||||
$iLevel++;
|
||||
$this->BuildEntriesRecursive($aEntry['childNodes'],false);
|
||||
}
|
||||
}
|
||||
$iLevel--;
|
||||
return $aResultEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление отчетов из базы данных
|
||||
* TODO: Добавить обработку кеша данных
|
||||
*
|
||||
* @param array|int $aIds
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteEntryByRequestId($aIds) {
|
||||
if(!is_array($aIds)) $aIds = array($aIds);
|
||||
return $this->oMapper->DeleteEntryByRequestId($aIds);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
class PluginProfiler_ProfilerEntity_Entry extends Entity
|
||||
{
|
||||
public function getRequestId() {
|
||||
return $this->_aData['request_id'];
|
||||
}
|
||||
public function getDate() {
|
||||
return $this->_aData['request_date'];
|
||||
}
|
||||
public function getTimeFull() {
|
||||
return str_replace(',','.',$this->_aData['time_full']);
|
||||
}
|
||||
|
||||
public function getTimeStart($mode=null) {
|
||||
switch ($mode) {
|
||||
case 'seconds':
|
||||
list($iSeconds,)=explode(' ',$this->_aData['time_start'],2);
|
||||
return $iSeconds;
|
||||
|
||||
case 'time':
|
||||
list(,$iTime)=explode(' ',$this->_aData['time_start'],2);
|
||||
return $iTime;
|
||||
|
||||
case null:
|
||||
default:
|
||||
return $this->_aData['time_start'];
|
||||
|
||||
}
|
||||
}
|
||||
public function getTimeStop($mode=null) {
|
||||
switch ($mode) {
|
||||
case 'seconds':
|
||||
list($iSeconds,)=explode(' ',$this->_aData['time_stop'],2);
|
||||
return $iSeconds;
|
||||
|
||||
case 'time':
|
||||
list(,$iTime)=explode(' ',$this->_aData['time_stop'],2);
|
||||
return $iTime;
|
||||
|
||||
case null:
|
||||
default:
|
||||
return $this->_aData['time_stop'];
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function getId() {
|
||||
return $this->_aData['time_id'];
|
||||
}
|
||||
public function getPid() {
|
||||
return is_null($this->_aData['time_pid']) ? 0 : $this->_aData['time_pid'];
|
||||
}
|
||||
public function getName() {
|
||||
return $this->_aData['time_name'];
|
||||
}
|
||||
public function getComment() {
|
||||
return $this->_aData['time_comment'];
|
||||
}
|
||||
|
||||
public function getLevel() {
|
||||
return $this->_aData['level'];
|
||||
}
|
||||
public function getChildCount() {
|
||||
return $this->_aData['child_count'];
|
||||
}
|
||||
public function getParentTimeFull() {
|
||||
return $this->_aData['parent_time_full'];
|
||||
}
|
||||
|
||||
public function setRequestId($data) {
|
||||
$this->_aData['request_id']=$data;
|
||||
}
|
||||
public function setDate($data) {
|
||||
$this->_aData['request_date']=$data;
|
||||
}
|
||||
public function setTimeFull($data) {
|
||||
$this->_aData['time_full']=$data;
|
||||
}
|
||||
public function setTimeStart($data) {
|
||||
$this->_aData['time_start']=$data;
|
||||
}
|
||||
public function setTimeStop($data) {
|
||||
$this->_aData['time_stop']=$data;
|
||||
}
|
||||
public function setId($data) {
|
||||
$this->_aData['time_id']=$data;
|
||||
}
|
||||
public function setPid($data) {
|
||||
$this->_aData['time_pid']=$data;
|
||||
}
|
||||
public function setName($data) {
|
||||
$this->_aData['time_name']=$data;
|
||||
}
|
||||
public function setComment($data) {
|
||||
$this->_aData['time_comment']=$data;
|
||||
}
|
||||
|
||||
public function setLevel($data) {
|
||||
$this->_aData['level']=$data;
|
||||
}
|
||||
public function setParentTimeFull($data) {
|
||||
$this->_aData['parent_time_full']=$data;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
class PluginProfiler_ProfilerEntity_Report extends Entity
|
||||
{
|
||||
public function getId() {
|
||||
return $this->_aData['report_id'];
|
||||
}
|
||||
public function getDate() {
|
||||
return $this->_aData['report_date'];
|
||||
}
|
||||
public function getAllEntries() {
|
||||
return isset($this->_aData['report_entries'])?$this->_aData['report_entries']:array();
|
||||
}
|
||||
public function getTime() {
|
||||
return isset($this->_aData['report_time_full'])?$this->_aData['report_time_full']:0;
|
||||
}
|
||||
|
||||
public function getEntriesByName($sName=null) {
|
||||
if(!$sName) return $this->getAllEntries();
|
||||
|
||||
$aResult=array();
|
||||
foreach ($this->getAllEntries() as $oEntry) {
|
||||
if($oEntry->getName()==$sName) $aResult[$oEntry->getId()]=$oEntry;
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
public function getCountEntriesByName($sName=null) {
|
||||
return count($this->getEntriesByName($sName));
|
||||
}
|
||||
|
||||
public function getEntriesByCommentFilter($sFilter) {
|
||||
$sFilter=str_replace('*','[\W]+',$sFilter);
|
||||
|
||||
$aResult=array();
|
||||
foreach ($this->_aData['report_entries'] as $oEntry) {
|
||||
if(preg_match("/{$sFilter}/Ui",$oEntry->getComment())) {
|
||||
$aResult[$oEntry->getId()]=$oEntry;
|
||||
}
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
public function getCountEntriesByCommentFilter($sFilter) {
|
||||
return count($this->getEntriesByCommentFilter($sFilter));
|
||||
}
|
||||
|
||||
public function getEntriesByPid($sPid) {
|
||||
$aResult=array();
|
||||
foreach ($this->_aData['report_entries'] as $oEntry) {
|
||||
if($oEntry->getPid()==$sPid) $aResult[]=$oEntry;
|
||||
}
|
||||
return $aResult;
|
||||
}
|
||||
public function getCountEntriesByPid($sPid) {
|
||||
return $this->getEntriesByPid($sPid);
|
||||
}
|
||||
|
||||
public function getEntryShare($sEntryId) {
|
||||
if(!isset($this->_aData['report_entries'][$sEntryId])) return null;
|
||||
if(!$this->_aData['report_entries'][$sEntryId]->getParentTimeFull()) return '-';
|
||||
|
||||
return round($this->_aData['report_entries'][$sEntryId]->getTimeFull()*100/$this->_aData['report_entries'][$sEntryId]->getParentTimeFull(), 2);
|
||||
}
|
||||
|
||||
public function getEntryFullShare($sEntryId) {
|
||||
if(!isset($this->_aData['report_entries'][$sEntryId])) return null;
|
||||
|
||||
return ($iTimeFull=$this->getStat('time_full'))
|
||||
? round($this->_aData['report_entries'][$sEntryId]->getTimeFull()*100/$iTimeFull, 2)
|
||||
: '?';
|
||||
}
|
||||
/**
|
||||
* Получает статистику отчета
|
||||
*
|
||||
* @param string [$sKey default=null
|
||||
* @return array|string|null
|
||||
*/
|
||||
public function getStat($sKey=null) {
|
||||
if(!$sKey) return $this->_aData['report_stat'];
|
||||
if(isset($this->_aData['report_stat'][$sKey])) return $this->_aData['report_stat'][$sKey];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setId($data) {
|
||||
$this->_aData['report_id']=$data;
|
||||
}
|
||||
public function setDate($data) {
|
||||
$this->_aData['report_date']=$data;
|
||||
}
|
||||
protected function setTime($data) {
|
||||
$this->_aData['report_time_full']=$data;
|
||||
}
|
||||
|
||||
public function addEntry(PluginProfiler_ProfilerEntity_Entry $data) {
|
||||
if(!isset($this->_aData['report_id'])) {
|
||||
$this->setId($data->getRequestId());
|
||||
$this->setDate($data->getDate());
|
||||
}
|
||||
|
||||
if($this->getId()!=$data->getRequestId()) return null;
|
||||
$this->_aData['report_entries'][$data->getId()]=$data;
|
||||
}
|
||||
/**
|
||||
* Устанавливаем все записи одним массивом
|
||||
*
|
||||
* @param array $data
|
||||
* @return null
|
||||
*/
|
||||
public function setAllEntries($data) {
|
||||
if(!is_array($data)) return null;
|
||||
$this->_aData['report_entries']=$data;
|
||||
}
|
||||
public function setStat($data,$sKey=null) {
|
||||
if(!$sKey) {
|
||||
$this->_aData['report_stat']=$data;
|
||||
return ;
|
||||
}
|
||||
$this->_aData[$sKey]=$data;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,146 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
class PluginProfiler_Mapper_Profiler extends Mapper {
|
||||
|
||||
public function AddEntry(PluginProfiler_ProfilerEntity_Entry $oEntry) {
|
||||
$sql = "INSERT IGNORE INTO ".Config::Get('db.table.profiler')."
|
||||
(request_date,
|
||||
request_id,
|
||||
time_full,
|
||||
time_start,
|
||||
time_stop,
|
||||
time_id,
|
||||
time_pid,
|
||||
time_name,
|
||||
time_comment)
|
||||
VALUES(?, ?, ?f, ?f+?f, ?f+?f, ?d, ?d, ?, ?)
|
||||
";
|
||||
return $this->oDb->query($sql,$oEntry->getDate(),$oEntry->getRequestId(),$oEntry->getTimeFull(),$oEntry->getTimeStart('time'),$oEntry->getTimeStart('seconds'),$oEntry->getTimeStop('time'),$oEntry->getTimeStop('seconds'),$oEntry->getId(),$oEntry->getPid(),$oEntry->getName(),$oEntry->getComment());
|
||||
}
|
||||
|
||||
public function GetDatabaseStat() {
|
||||
$sql = "
|
||||
SELECT
|
||||
MAX(request_date) as max_date,
|
||||
COUNT(*) as count
|
||||
FROM ".Config::Get('db.table.profiler') ."
|
||||
";
|
||||
|
||||
if($aData = $this->oDb->selectRow($sql)) {
|
||||
return $aData;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Возвращает список отчетов профайлера, сгруппированных по идентификатору вызова request_id
|
||||
*
|
||||
* @param array $aFilter
|
||||
* @param int $iCount
|
||||
* @param int $iCurrPage
|
||||
* @param int $iPerPage
|
||||
* @return array
|
||||
*/
|
||||
public function GetReportsByFilter($aFilter,&$iCount,$iCurrPage,$iPerPage) {
|
||||
$sql = "
|
||||
SELECT
|
||||
DISTINCT request_id,
|
||||
MAX(time_full) as time_full,
|
||||
COUNT(time_id) as count_time_id,
|
||||
MIN(request_date) as request_date
|
||||
FROM ".Config::Get('db.table.profiler')."
|
||||
WHERE
|
||||
1=1
|
||||
{ AND request_date >= ? }
|
||||
{ AND request_date <= ? }
|
||||
{ AND time_full > ? }
|
||||
GROUP BY request_id
|
||||
ORDER BY request_date desc
|
||||
LIMIT ?d, ?d
|
||||
";
|
||||
|
||||
if (
|
||||
$aRows=$this->oDb->selectPage(
|
||||
$iCount,
|
||||
$sql,
|
||||
isset($aFilter['date_min'])?$aFilter['date_min']:DBSIMPLE_SKIP,
|
||||
isset($aFilter['date_max'])?$aFilter['date_max']:DBSIMPLE_SKIP,
|
||||
isset($aFilter['time'])?$aFilter['time']:DBSIMPLE_SKIP,
|
||||
($iCurrPage-1)*$iPerPage,
|
||||
$iPerPage
|
||||
)
|
||||
) {
|
||||
return $aRows;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function GetReportById($sReportId,$sPid=null) {
|
||||
$sql = "
|
||||
SELECT
|
||||
p.*,
|
||||
p.time_id as ARRAY_KEY,
|
||||
p.time_pid as PARENT_KEY,
|
||||
COUNT(pc.time_id) as child_count,
|
||||
pp.time_full as parent_time_full
|
||||
FROM
|
||||
".Config::Get('db.table.profiler')." as p
|
||||
LEFT JOIN ".Config::Get('db.table.profiler')." as pc ON p.request_id=pc.request_id AND p.time_id = pc.time_pid
|
||||
LEFT JOIN ".Config::Get('db.table.profiler')." AS pp ON p.request_id=pp.request_id AND p.time_pid = pp.time_id
|
||||
WHERE
|
||||
p.request_id=?
|
||||
{ AND p.time_pid=?d }
|
||||
GROUP BY p.time_id
|
||||
";
|
||||
|
||||
if($aRows=$this->oDb->query($sql,$sReportId,is_null($sPid)?DBSIMPLE_SKIP:$sPid)) {
|
||||
return $aRows;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
public function GetReportStatById($sReportId) {
|
||||
$sql = "
|
||||
SELECT time_full, time_name, time_comment
|
||||
FROM ".Config::Get('db.table.profiler')."
|
||||
WHERE request_id=?
|
||||
";
|
||||
|
||||
if($aRows=$this->oDb->query($sql,$sReportId)) {
|
||||
return $aRows;
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Удаление записей из базы данных по уникальному ключу отчетов
|
||||
*
|
||||
* @param array|int $aIds
|
||||
* @return bool
|
||||
*/
|
||||
public function DeleteEntryByRequestId($aIds) {
|
||||
$sql = "
|
||||
DELETE FROM ".Config::Get('db.table.profiler')."
|
||||
WHERE request_id IN(?a)
|
||||
";
|
||||
|
||||
return $this->oDb->query($sql,$aIds);
|
||||
}
|
||||
}
|
||||
?>
|
23
plugins/profiler/config/config.php
Normal file
23
plugins/profiler/config/config.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
$config['per_page'] = 15; // Число profiler-отчетов на одну страницу
|
||||
|
||||
Config::Set('db.table.profiler', '___db.table.prefix___profiler');
|
||||
Config::Set('router.page.profiler', 'PluginProfiler_ActionProfiler');
|
||||
|
||||
return $config;
|
||||
?>
|
6
plugins/profiler/readme.txt
Normal file
6
plugins/profiler/readme.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
Name: Livestreet Profiler Plugin
|
||||
Author: LiveStreet Developers Team
|
||||
Homepage: http://livestreet.ru/
|
||||
Version: 1.0.0
|
||||
Requires: 0.4.0
|
||||
Description: Профилирование работы движка LiveStreet-движка.
|
12
plugins/profiler/sql.sql
Normal file
12
plugins/profiler/sql.sql
Normal file
|
@ -0,0 +1,12 @@
|
|||
CREATE TABLE IF NOT EXISTS `prefix_profiler` (
|
||||
`request_date` DATETIME NOT NULL ,
|
||||
`request_id` VARCHAR( 32 ) NOT NULL ,
|
||||
`time_full` DOUBLE( 9,6 ) NOT NULL ,
|
||||
`time_start` DOUBLE( 17,7 ) NOT NULL ,
|
||||
`time_stop` DOUBLE( 17,7 ) NOT NULL ,
|
||||
`time_id` INT NOT NULL ,
|
||||
`time_pid` INT NOT NULL ,
|
||||
`time_name` VARCHAR( 250 ) NOT NULL ,
|
||||
`time_comment` VARCHAR( 250 ) NOT NULL,
|
||||
PRIMARY KEY (`request_id` , `time_id`)
|
||||
);
|
65
plugins/profiler/templates/language/russian.php
Normal file
65
plugins/profiler/templates/language/russian.php
Normal file
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
/*-------------------------------------------------------
|
||||
*
|
||||
* LiveStreet Engine Social Networking
|
||||
* Copyright © 2008 Mzhelskiy Maxim
|
||||
*
|
||||
*--------------------------------------------------------
|
||||
*
|
||||
* Official site: www.livestreet.ru
|
||||
* Contact e-mail: rus.engine@gmail.com
|
||||
*
|
||||
* GNU General Public License, version 2:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
*
|
||||
---------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* Русский языковой файл плагина Profiler
|
||||
*/
|
||||
return array(
|
||||
'profiler_report_page_title' => 'Профилирование',
|
||||
|
||||
'profiler_reports_title' => 'Отчеты о профилировании',
|
||||
'profiler_table_date' => 'Дата начала работы',
|
||||
'profiler_table_time_full' => 'Время работы',
|
||||
'profiler_table_count_id' => 'Количество профилей',
|
||||
'profiler_report_delete' => 'Удалить',
|
||||
'profiler_report_delete_confirm' => 'Вы уверены, что хотите удалить выбранные отчеты?',
|
||||
|
||||
'profiler_dbstat_title' => 'Информацию о базе данных',
|
||||
'profiler_dbstat_count' => 'Всего записей',
|
||||
'profiler_dbstat_max_date' => 'Последняя дата',
|
||||
'profiler_import_label' => 'Импортировать начиная с',
|
||||
'profiler_import_notice' => 'В любом читаемом формате, напрмиер, Y-m-d H:i',
|
||||
'profiler_import_submit' => 'Импортировать в БД',
|
||||
|
||||
'profiler_report_delete_success' => 'Отчеты успешно удалены из базы данных',
|
||||
'profiler_report_delete_error' => 'При удалении отчетов произошла ошибка',
|
||||
'profiler_import_report_success' => 'Импортировано записей: %%count%%',
|
||||
'profiler_import_report_error' => 'При импорте отчетов в базу данных произошла ошибка',
|
||||
|
||||
'profiler_entries_show_all' => 'Показать все',
|
||||
'profiler_entries_show_tree' => 'Вывести дерево',
|
||||
'profiler_entries_show_query' => 'Запросы к БД',
|
||||
|
||||
'profiler_filter_title' => 'Фильтровать',
|
||||
'profiler_filter_highlight' => 'Подсветить',
|
||||
'profiler_filter_seconds' => 'секунд',
|
||||
'profiler_filter_erase' => 'Сбросить фильтр',
|
||||
'profiler_filter_erase_form' => 'Очистить форму',
|
||||
'profiler_filter_label_per_page' => 'Вывести на страницу',
|
||||
'profiler_filter_label_time' => 'Общее время больше',
|
||||
'profiler_filter_label_date' => 'Ограничения по дате',
|
||||
'profiler_filter_notice_per_page' => '',
|
||||
'profiler_filter_notice_time' => 'Минимальное количество секунд выполнения',
|
||||
'profiler_filter_notice_date' => 'Дата вводиться в формате 25.12.2009',
|
||||
'profiler_filter_submit' => 'Отфильтровать',
|
||||
'profiler_filter_error' => 'Ошибка фильрации',
|
||||
'profiler_filter_error_date_format' => 'Указан неверный формат даты',
|
||||
'profiler_filter_result_count' => 'Найдено отчетов: %%count%%',
|
||||
'profiler_filter_result_empty' => 'По вашим критериям отчетов не найдено'
|
||||
);
|
||||
|
||||
?>
|
|
@ -0,0 +1,14 @@
|
|||
<div class="profiler-table">
|
||||
<table class="profiler entries">
|
||||
{foreach from=$oReport->getAllEntries() item=oEntry}
|
||||
<tr class="entry_{$oReport->getId()}_all entry_{$oReport->getId()}_{$oEntry->getName()}{if $oEntry->getChildCount()!=0} has-child{/if}">
|
||||
<td>{if $oEntry->getChildCount()!=0}<img src="{cfg name='path.static.skin'}/images/open.gif" alt="+" title="{$aLang.comment_collapse}/{$aLang.comment_expand}" class="folding lsProfiler_tree" id="tree_{$oReport->getId()}_{$oEntry->getId()}" style="margin-right:3px;"/>{/if}</td>
|
||||
<td width="5%">{$oEntry->getId()}</td>
|
||||
<td width="12%">{$oEntry->getName()}</td>
|
||||
<td width="12%" class="time">{$oEntry->getTimeFull()}</td>
|
||||
<td width="18%">{$oReport->getEntryFullShare($oEntry->getId())}% ({$oReport->getEntryShare($oEntry->getId())}%)</td>
|
||||
<td>{$oEntry->getComment()}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
{if $oReport}
|
||||
<a href="#" class="profiler tree {if $sAction=='tree'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','tree',this); return false;">{$aLang.profiler_entries_show_tree}</a>
|
||||
<a href="#" class="profiler all {if $sAction=='all'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','all',this); return false;">{$aLang.profiler_entries_show_all} ({$oReport->getStat('count')})</a>
|
||||
<a href="#" class="profiler query {if $sAction=='query'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','query',this); return false;">{$aLang.profiler_entries_show_query} ({$oReport->getStat('query')})</a>
|
||||
|
||||
<div class="profiler-table">
|
||||
<table class="profiler entries">
|
||||
{foreach from=$oReport->getAllEntries() item=oEntry}
|
||||
<tr class="entry_{$oReport->getId()}_all entry_{$oReport->getId()}_{$oEntry->getName()}{if $oEntry->getChildCount()!=0} child{/if}">
|
||||
<td></td>
|
||||
<td width="5%">{$oEntry->getId()}</td>
|
||||
<td width="12%">{$oEntry->getName()}</td>
|
||||
<td width="12%" class="time">{$oEntry->getTimeFull()}</td>
|
||||
<td width="18%">{$oReport->getEntryFullShare($oEntry->getId())}% ({$oReport->getEntryShare($oEntry->getId())}%)</td>
|
||||
<td>{$oEntry->getComment()}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
</div>
|
||||
{else}
|
||||
{$aLang.error}
|
||||
{/if}
|
|
@ -0,0 +1,9 @@
|
|||
{if $oReport}
|
||||
<a href="#" class="profiler tree {if $sAction=='tree'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','tree',this); return false;">{$aLang.profiler_entries_show_tree}</a>
|
||||
<a href="#" class="profiler all {if $sAction=='all'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','all',this); return false;">{$aLang.profiler_entries_show_all} ({$oReport->getStat('count')})</a>
|
||||
<a href="#" class="profiler query {if $sAction=='query'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','query',this); return false;">{$aLang.profiler_entries_show_query} ({$oReport->getStat('query')})</a>
|
||||
|
||||
{include file='profiler/templates/skin/new/actions/ActionProfiler/ajax/level.tpl'}
|
||||
{else}
|
||||
{$aLang.error}
|
||||
{/if}
|
|
@ -0,0 +1,35 @@
|
|||
{include file='header.tpl' noShowSystemMessage=false}
|
||||
<script type="text/javascript" src="{cfg name='path.root.web'}/plugins/profiler/templates/skin/new/js/profiler.js"></script>
|
||||
|
||||
<div class="topic people top-blogs talk-table">
|
||||
<h1>{$aLang.profiler_reports_title}</h1>
|
||||
<form action="{router page='profiler'}" method="post" id="form_report_list">
|
||||
<input type="hidden" name="security_ls_key" value="{$LIVESTREET_SECURITY_KEY}" />
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="20px"><input type="checkbox" name="" onclick="checkAllReport(this);"></td>
|
||||
<td></td>
|
||||
<td>{$aLang.profiler_table_date}</td>
|
||||
<td align="center">{$aLang.profiler_table_time_full}</td>
|
||||
<td align="center">{$aLang.profiler_table_count_id}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{foreach from=$aReports item=oReport}
|
||||
<tr>
|
||||
<td><input type="checkbox" name="report_del[{$oReport.request_id}]" class="form_reports_checkbox"></td>
|
||||
<td><img src="{cfg name='path.static.skin'}/images/open.gif" alt="+" title="{$aLang.comment_collapse}/{$aLang.comment_expand}" class="folding" id="img_{$oReport.request_id}" /></td>
|
||||
<td>{date_format date=$oReport.request_date}</td>
|
||||
<td align="center" class="time">{$oReport.time_full}</td>
|
||||
<td align="center">{$oReport.count_time_id}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="submit" name="submit_report_delete" value="{$aLang.profiler_report_delete}" onclick="return ($$('.form_reports_checkbox').length==0)?false:confirm('{$aLang.profiler_report_delete_confirm}');">
|
||||
</form>
|
||||
</div>
|
||||
{include file='paging.tpl' aPaging=`$aPaging`}
|
||||
{include file='footer.tpl'}
|
|
@ -0,0 +1,99 @@
|
|||
<div class="profiler-highlight">{$aLang.profiler_filter_highlight}: <input type="text" name="profiler_filter_entries" id="profiler_filter_entries" onchange="lsProfiler.filterNode(this);" class="w50" /> {$aLang.profiler_filter_seconds}</div>
|
||||
<div class="block blogs">
|
||||
<div class="tl"><div class="tr"></div></div>
|
||||
<div class="cl"><div class="cr">
|
||||
|
||||
<h1>{$aLang.profiler_dbstat_title}</h1>
|
||||
|
||||
<form action="{router page='profiler'}" method="POST" name="profiler_import_form">
|
||||
<p>{$aLang.profiler_dbstat_count}: {$aDatabaseStat.count}<br />
|
||||
{$aLang.profiler_dbstat_max_date}: {$aDatabaseStat.max_date}</p>
|
||||
<p>
|
||||
<label for="profiler_date_import">{$aLang.profiler_import_label}:</label><br />
|
||||
<input type="text" id="profiler_date_import" name="profiler_date_import" value="{if $_aRequest.date_import}{$_aRequest.date_import}{else}{if $aDatabaseStat.max_date}{$aDatabaseStat.max_date}{else}{date_format date=$smarty.now format='Y-m-d \0\0\:\0\0\:\0\0'}{/if}{/if}" class="w100p" /><br />
|
||||
<span class="form_note">{$aLang.profiler_import_notice}</span>
|
||||
</p>
|
||||
<p class="buttons">
|
||||
<input type="submit" name="submit_profiler_import" value="{$aLang.profiler_import_submit}"/>
|
||||
</p>
|
||||
</form>
|
||||
<br/>
|
||||
</div></div>
|
||||
<div class="bl"><div class="br"></div></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="block blogs">
|
||||
<div class="tl"><div class="tr"></div></div>
|
||||
<div class="cl"><div class="cr">
|
||||
|
||||
<h1>{$aLang.profiler_filter_title}</h1>
|
||||
|
||||
{literal}
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
document.addEvent('domready', function() {
|
||||
new vlaDatePicker(
|
||||
$('profiler_filter_start'),
|
||||
{
|
||||
separator: '.',
|
||||
leadingZero: true,
|
||||
twoDigitYear: false,
|
||||
alignX: 'center',
|
||||
alignY: 'top',
|
||||
offset: { y: 3 },
|
||||
filePath: DIR_WEB_ROOT+'/engine/lib/external/MooTools_1.2/plugs/vlaCal-v2.1/inc/',
|
||||
prefillDate: false,
|
||||
startMonday: true
|
||||
}
|
||||
);
|
||||
new vlaDatePicker(
|
||||
$('profiler_filter_end'),
|
||||
{
|
||||
separator: '.',
|
||||
leadingZero: true,
|
||||
twoDigitYear: false,
|
||||
alignX: 'center',
|
||||
alignY: 'top',
|
||||
offset: { y: 3 },
|
||||
filePath: DIR_WEB_ROOT+'/engine/lib/external/MooTools_1.2/plugs/vlaCal-v2.1/inc/',
|
||||
prefillDate: false,
|
||||
startMonday: true
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function eraseFilterForm() {
|
||||
$$("#profiler_filter_per_page, #profiler_filter_time, #profiler_filter_start, #profiler_filter_end").each(
|
||||
function(item,index){
|
||||
return item.set('value','');
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
{/literal}
|
||||
<form action="{router page='profiler'}" method="GET" name="profiler_filter_form">
|
||||
<p><label for="profiler_filter_start">{$aLang.profiler_filter_label_date}:</label><br />
|
||||
<input type="text" id="profiler_filter_start" name="start" value="{$_aRequest.start}" class="w100p" style="width: 44%" readonly="readonly" /> —
|
||||
<input type="text" id="profiler_filter_end" name="end" value="{$_aRequest.end}" class="w100p" style="width: 44%" readonly="readonly" /><br />
|
||||
<span class="form_note">{$aLang.profiler_filter_notice_date}</span>
|
||||
</p>
|
||||
|
||||
<p><label for="profiler_filter_time">{$aLang.profiler_filter_label_time}:</label>
|
||||
<input type="text" id="profiler_filter_time" name="time" value="{$_aRequest.time}" class="w100" /><br />
|
||||
<span class="form_note">{$aLang.profiler_filter_notice_time}</span>
|
||||
</p>
|
||||
|
||||
<p><label for="profiler_filter_per_page">{$aLang.profiler_filter_label_per_page}:</label>
|
||||
<input type="text" id="profiler_filter_per_page" name="per_page" value="{if $_aRequest.per_page}{$_aRequest.per_page}{else}{cfg name='module.profiler.per_page'}{/if}" class="w50" /><br />
|
||||
<span class="form_note">{$aLang.profiler_filter_notice_per_page}</span>
|
||||
</p>
|
||||
|
||||
<p class="buttons">
|
||||
<input type="submit" name="submit_profiler_filter" value="{$aLang.profiler_filter_submit}"/>
|
||||
</p>
|
||||
</form>
|
||||
<div class="right"><a href="#" onclick="return eraseFilterForm();">{$aLang.profiler_filter_erase_form}</a> | <a href="{router page='profiler'}">{$aLang.profiler_filter_erase}</a></div>
|
||||
</div></div>
|
||||
<div class="bl"><div class="br"></div></div>
|
||||
</div>
|
207
plugins/profiler/templates/skin/default/js/profiler.js
Normal file
207
plugins/profiler/templates/skin/default/js/profiler.js
Normal file
|
@ -0,0 +1,207 @@
|
|||
var lsProfilerClass = new Class({
|
||||
|
||||
Implements: Options,
|
||||
|
||||
options: {
|
||||
img : {
|
||||
path: DIR_STATIC_SKIN+'/images/',
|
||||
openName: 'open.gif',
|
||||
closeName: 'close.gif'
|
||||
},
|
||||
classes: {
|
||||
visible: 'lsProfiler_visible',
|
||||
hidden: 'lsProfiler_hidden',
|
||||
openImg: 'lsProfiler_open',
|
||||
closeImg: 'lsProfiler_close',
|
||||
treeNode: 'lsProfiler_tree',
|
||||
filterNode: 'lsProfiler_filter'
|
||||
},
|
||||
prefix: {
|
||||
img: 'img_',
|
||||
td: 'report_',
|
||||
entry: 'entry_',
|
||||
tree: 'tree_',
|
||||
treeNode: 'tree_node_'
|
||||
},
|
||||
path: {
|
||||
loadReport: aRouter['profiler']+'ajaxloadreport/',
|
||||
loadEntries: aRouter['profiler']+'ajaxloadentriesbyfilter/'
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(options){
|
||||
this.setOptions(options);
|
||||
this.make();
|
||||
},
|
||||
|
||||
make: function(expandClass){
|
||||
var thisObj = this;
|
||||
var aImgFolding=(!expandClass)?$$('img.folding'):$$('img.folding.'+expandClass);
|
||||
aImgFolding.each(function(img, i){thisObj.makeImg(img);});
|
||||
},
|
||||
|
||||
makeImg: function(img) {
|
||||
var thisObj = this;
|
||||
img.setStyles({
|
||||
'cursor' : 'pointer',
|
||||
'display' : 'inline'
|
||||
});
|
||||
img.removeClass(this.options.classes.closeImg);
|
||||
img.addClass(this.options.classes.openImg);
|
||||
img.removeEvents('click');
|
||||
img.addEvent('click',function(){
|
||||
thisObj.toggleNode(img);
|
||||
});
|
||||
},
|
||||
|
||||
toggleNode: function(img) {
|
||||
if (img.hasClass(this.options.classes.closeImg)) {
|
||||
this.collapseNode(img);
|
||||
} else {
|
||||
this.expandNode(img);
|
||||
}
|
||||
},
|
||||
|
||||
expandNode: function(img) {
|
||||
var thisObj = this;
|
||||
|
||||
img.setProperties({'src': this.options.img.path + this.options.img.closeName});
|
||||
img.removeClass(this.options.classes.openImg);
|
||||
img.addClass(this.options.classes.closeImg);
|
||||
|
||||
if(img.hasClass(thisObj.options.classes.treeNode)) {
|
||||
// Это элемент дерева - обрабатываем его соответствующим образом
|
||||
ids = img.get('id').replace(this.options.prefix.tree,'').split('_');
|
||||
|
||||
reportId=ids[0];
|
||||
var trReportId=this.options.prefix.treeNode+ids[0]+'_'+ids[1];
|
||||
var trReport=$(trReportId);
|
||||
var parentId=ids[1];
|
||||
} else {
|
||||
reportId=img.get('id').replace(this.options.prefix.img,this.options.prefix.td);
|
||||
var trReport = $(reportId);
|
||||
var parentId = 0;
|
||||
var trReportId = 0;
|
||||
}
|
||||
|
||||
if(trReport){
|
||||
trReport.show();
|
||||
} else {
|
||||
thisObj.loadReport(img.getParent('tr'),reportId,parentId,trReportId);
|
||||
}
|
||||
},
|
||||
|
||||
loadReport: function(obj,reportId,parentId,namedId) {
|
||||
var thisObj=this;
|
||||
var trCurrent = obj;
|
||||
|
||||
JsHttpRequest.query(
|
||||
'POST '+thisObj.options.path.loadReport,
|
||||
{
|
||||
reportId: reportId,
|
||||
bTreeView: true,
|
||||
parentId: parentId,
|
||||
security_ls_key: LIVESTREET_SECURITY_KEY
|
||||
},
|
||||
function(result, errors) {
|
||||
if (!result) {
|
||||
msgErrorBox.alert('Error','Please try again later');
|
||||
}
|
||||
if (result.bStateError) {
|
||||
msgErrorBox.alert(result.sMsgTitle,result.sMsg);
|
||||
} else {
|
||||
var trReport=new Element('tr', {'id':(!namedId)?reportId:namedId});
|
||||
trReport.adopt(new Element('td',{
|
||||
'colspan': 6,
|
||||
'html' : result.sReportText
|
||||
}));
|
||||
trReport.inject(trCurrent,'after');
|
||||
trReport.getElements('img').each(function(img, i){thisObj.makeImg(img);});
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
collapseNode: function(img) {
|
||||
var thisObj = this;
|
||||
|
||||
img.setProperties({'src': this.options.img.path + this.options.img.openName});
|
||||
img.removeClass(this.options.classes.closeImg);
|
||||
img.addClass(this.options.classes.openImg);
|
||||
|
||||
if(img.hasClass(thisObj.options.classes.treeNode)) {
|
||||
// Это элемент дерева - обрабатываем его соответствующим образом
|
||||
trReport=img.getParent('tr').getNext('tr');
|
||||
} else {
|
||||
reportId=img.get('id').replace(this.options.prefix.img,this.options.prefix.td);
|
||||
var trReport = $(reportId);
|
||||
}
|
||||
|
||||
trReport.hide();
|
||||
},
|
||||
|
||||
toggleEntriesByClass: function(reportId,name,link) {
|
||||
var thisObj=this;
|
||||
$$('a.profiler').removeClass('active');
|
||||
$$('a.profiler.'+name).addClass('active');
|
||||
|
||||
//var trCurrent = link.getParent('tr').getPrevious('tr');
|
||||
|
||||
JsHttpRequest.query(
|
||||
'POST '+thisObj.options.path.loadEntries+name+'/',
|
||||
{
|
||||
reportId: reportId,
|
||||
security_ls_key: LIVESTREET_SECURITY_KEY
|
||||
},
|
||||
function(result, errors) {
|
||||
if (!result) {
|
||||
msgErrorBox.alert('Error','Please try again later');
|
||||
}
|
||||
if (result.bStateError) {
|
||||
msgErrorBox.alert(result.sMsgTitle,result.sMsg);
|
||||
} else {
|
||||
var trReport = $(thisObj.options.prefix.td+reportId).empty();
|
||||
trReport.adopt(new Element('td',{
|
||||
'colspan': 5,
|
||||
'html' : result.sReportText
|
||||
}));
|
||||
trReport.getElements('img').each(function(img, i){thisObj.makeImg(img);});
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
filterNode: function(obj) {
|
||||
var thisObj = this;
|
||||
var iTime=obj.get('value');
|
||||
if(iTime!='' && parseFloat(iTime)){ thisObj.highlightFilterNode(iTime); }
|
||||
},
|
||||
|
||||
highlightFilterNode: function(iTime) {
|
||||
var thisObj = this;
|
||||
|
||||
$$('.time').each(function(el,i){
|
||||
el.getParent('tr').removeClass(thisObj.options.classes.filterNode);
|
||||
if(el.get('text')>iTime) {
|
||||
el.getParent('tr').addClass(thisObj.options.classes.filterNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var lsProfiler;
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
lsProfiler = new lsProfilerClass({
|
||||
img: {
|
||||
path: DIR_STATIC_SKIN+'/images/'
|
||||
},
|
||||
classes: {
|
||||
openImg: 'folding-open',
|
||||
closeImg: 'folding',
|
||||
filterNode: 'filter'
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
<div class="profiler-table">
|
||||
<table class="profiler entries">
|
||||
{foreach from=$oReport->getAllEntries() item=oEntry}
|
||||
<tr class="entry_{$oReport->getId()}_all entry_{$oReport->getId()}_{$oEntry->getName()}{if $oEntry->getChildCount()!=0} has-child{/if}">
|
||||
<td>{if $oEntry->getChildCount()!=0}<img src="{cfg name='path.static.skin'}/images/open.gif" alt="+" title="{$aLang.comment_collapse}/{$aLang.comment_expand}" class="folding lsProfiler_tree" id="tree_{$oReport->getId()}_{$oEntry->getId()}" style="margin-right:3px;"/>{/if}</td>
|
||||
<td width="5%">{$oEntry->getId()}</td>
|
||||
<td width="12%">{$oEntry->getName()}</td>
|
||||
<td width="12%" class="time">{$oEntry->getTimeFull()}</td>
|
||||
<td width="18%">{$oReport->getEntryFullShare($oEntry->getId())}% ({$oReport->getEntryShare($oEntry->getId())}%)</td>
|
||||
<td>{$oEntry->getComment()}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,22 @@
|
|||
{if $oReport}
|
||||
<a href="#" class="profiler tree {if $sAction=='tree'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','tree',this); return false;">{$aLang.profiler_entries_show_tree}</a>
|
||||
<a href="#" class="profiler all {if $sAction=='all'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','all',this); return false;">{$aLang.profiler_entries_show_all} ({$oReport->getStat('count')})</a>
|
||||
<a href="#" class="profiler query {if $sAction=='query'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','query',this); return false;">{$aLang.profiler_entries_show_query} ({$oReport->getStat('query')})</a>
|
||||
|
||||
<div class="profiler-table">
|
||||
<table class="profiler entries">
|
||||
{foreach from=$oReport->getAllEntries() item=oEntry}
|
||||
<tr class="entry_{$oReport->getId()}_all entry_{$oReport->getId()}_{$oEntry->getName()}{if $oEntry->getChildCount()!=0} child{/if}">
|
||||
<td></td>
|
||||
<td width="5%">{$oEntry->getId()}</td>
|
||||
<td width="12%">{$oEntry->getName()}</td>
|
||||
<td width="12%" class="time">{$oEntry->getTimeFull()}</td>
|
||||
<td width="18%">{$oReport->getEntryFullShare($oEntry->getId())}% ({$oReport->getEntryShare($oEntry->getId())}%)</td>
|
||||
<td>{$oEntry->getComment()}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
</div>
|
||||
{else}
|
||||
{$aLang.error}
|
||||
{/if}
|
|
@ -0,0 +1,9 @@
|
|||
{if $oReport}
|
||||
<a href="#" class="profiler tree {if $sAction=='tree'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','tree',this); return false;">{$aLang.profiler_entries_show_tree}</a>
|
||||
<a href="#" class="profiler all {if $sAction=='all'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','all',this); return false;">{$aLang.profiler_entries_show_all} ({$oReport->getStat('count')})</a>
|
||||
<a href="#" class="profiler query {if $sAction=='query'}active{/if}" onclick="lsProfiler.toggleEntriesByClass('{$oReport->getId()}','query',this); return false;">{$aLang.profiler_entries_show_query} ({$oReport->getStat('query')})</a>
|
||||
|
||||
{include file='profiler/templates/skin/new/actions/ActionProfiler/ajax/level.tpl'}
|
||||
{else}
|
||||
{$aLang.error}
|
||||
{/if}
|
|
@ -0,0 +1,35 @@
|
|||
{include file='header.tpl' noShowSystemMessage=false}
|
||||
<script type="text/javascript" src="{cfg name='path.root.web'}/plugins/profiler/templates/skin/new/js/profiler.js"></script>
|
||||
|
||||
<div class="topic people top-blogs talk-table">
|
||||
<h1>{$aLang.profiler_reports_title}</h1>
|
||||
<form action="{router page='profiler'}" method="post" id="form_report_list">
|
||||
<input type="hidden" name="security_ls_key" value="{$LIVESTREET_SECURITY_KEY}" />
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="20px"><input type="checkbox" name="" onclick="checkAllReport(this);"></td>
|
||||
<td></td>
|
||||
<td>{$aLang.profiler_table_date}</td>
|
||||
<td align="center">{$aLang.profiler_table_time_full}</td>
|
||||
<td align="center">{$aLang.profiler_table_count_id}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{foreach from=$aReports item=oReport}
|
||||
<tr>
|
||||
<td><input type="checkbox" name="report_del[{$oReport.request_id}]" class="form_reports_checkbox"></td>
|
||||
<td><img src="{cfg name='path.static.skin'}/images/open.gif" alt="+" title="{$aLang.comment_collapse}/{$aLang.comment_expand}" class="folding" id="img_{$oReport.request_id}" /></td>
|
||||
<td>{date_format date=$oReport.request_date}</td>
|
||||
<td align="center" class="time">{$oReport.time_full}</td>
|
||||
<td align="center">{$oReport.count_time_id}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="submit" name="submit_report_delete" value="{$aLang.profiler_report_delete}" onclick="return ($$('.form_reports_checkbox').length==0)?false:confirm('{$aLang.profiler_report_delete_confirm}');">
|
||||
</form>
|
||||
</div>
|
||||
{include file='paging.tpl' aPaging=`$aPaging`}
|
||||
{include file='footer.tpl'}
|
|
@ -0,0 +1,99 @@
|
|||
<div class="profiler-highlight">{$aLang.profiler_filter_highlight}: <input type="text" name="profiler_filter_entries" id="profiler_filter_entries" onchange="lsProfiler.filterNode(this);" class="w50" /> {$aLang.profiler_filter_seconds}</div>
|
||||
<div class="block blogs">
|
||||
<div class="tl"><div class="tr"></div></div>
|
||||
<div class="cl"><div class="cr">
|
||||
|
||||
<h1>{$aLang.profiler_dbstat_title}</h1>
|
||||
|
||||
<form action="{router page='profiler'}" method="POST" name="profiler_import_form">
|
||||
<p>{$aLang.profiler_dbstat_count}: {$aDatabaseStat.count}<br />
|
||||
{$aLang.profiler_dbstat_max_date}: {$aDatabaseStat.max_date}</p>
|
||||
<p>
|
||||
<label for="profiler_date_import">{$aLang.profiler_import_label}:</label><br />
|
||||
<input type="text" id="profiler_date_import" name="profiler_date_import" value="{if $_aRequest.date_import}{$_aRequest.date_import}{else}{if $aDatabaseStat.max_date}{$aDatabaseStat.max_date}{else}{date_format date=$smarty.now format='Y-m-d \0\0\:\0\0\:\0\0'}{/if}{/if}" class="w100p" /><br />
|
||||
<span class="form_note">{$aLang.profiler_import_notice}</span>
|
||||
</p>
|
||||
<p class="buttons">
|
||||
<input type="submit" name="submit_profiler_import" value="{$aLang.profiler_import_submit}"/>
|
||||
</p>
|
||||
</form>
|
||||
<br/>
|
||||
</div></div>
|
||||
<div class="bl"><div class="br"></div></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="block blogs">
|
||||
<div class="tl"><div class="tr"></div></div>
|
||||
<div class="cl"><div class="cr">
|
||||
|
||||
<h1>{$aLang.profiler_filter_title}</h1>
|
||||
|
||||
{literal}
|
||||
<script language="JavaScript" type="text/javascript">
|
||||
document.addEvent('domready', function() {
|
||||
new vlaDatePicker(
|
||||
$('profiler_filter_start'),
|
||||
{
|
||||
separator: '.',
|
||||
leadingZero: true,
|
||||
twoDigitYear: false,
|
||||
alignX: 'center',
|
||||
alignY: 'top',
|
||||
offset: { y: 3 },
|
||||
filePath: DIR_WEB_ROOT+'/engine/lib/external/MooTools_1.2/plugs/vlaCal-v2.1/inc/',
|
||||
prefillDate: false,
|
||||
startMonday: true
|
||||
}
|
||||
);
|
||||
new vlaDatePicker(
|
||||
$('profiler_filter_end'),
|
||||
{
|
||||
separator: '.',
|
||||
leadingZero: true,
|
||||
twoDigitYear: false,
|
||||
alignX: 'center',
|
||||
alignY: 'top',
|
||||
offset: { y: 3 },
|
||||
filePath: DIR_WEB_ROOT+'/engine/lib/external/MooTools_1.2/plugs/vlaCal-v2.1/inc/',
|
||||
prefillDate: false,
|
||||
startMonday: true
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
function eraseFilterForm() {
|
||||
$$("#profiler_filter_per_page, #profiler_filter_time, #profiler_filter_start, #profiler_filter_end").each(
|
||||
function(item,index){
|
||||
return item.set('value','');
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
{/literal}
|
||||
<form action="{router page='profiler'}" method="GET" name="profiler_filter_form">
|
||||
<p><label for="profiler_filter_start">{$aLang.profiler_filter_label_date}:</label><br />
|
||||
<input type="text" id="profiler_filter_start" name="start" value="{$_aRequest.start}" class="w100p" style="width: 44%" readonly="readonly" /> —
|
||||
<input type="text" id="profiler_filter_end" name="end" value="{$_aRequest.end}" class="w100p" style="width: 44%" readonly="readonly" /><br />
|
||||
<span class="form_note">{$aLang.profiler_filter_notice_date}</span>
|
||||
</p>
|
||||
|
||||
<p><label for="profiler_filter_time">{$aLang.profiler_filter_label_time}:</label>
|
||||
<input type="text" id="profiler_filter_time" name="time" value="{$_aRequest.time}" class="w100" /><br />
|
||||
<span class="form_note">{$aLang.profiler_filter_notice_time}</span>
|
||||
</p>
|
||||
|
||||
<p><label for="profiler_filter_per_page">{$aLang.profiler_filter_label_per_page}:</label>
|
||||
<input type="text" id="profiler_filter_per_page" name="per_page" value="{if $_aRequest.per_page}{$_aRequest.per_page}{else}{cfg name='module.profiler.per_page'}{/if}" class="w50" /><br />
|
||||
<span class="form_note">{$aLang.profiler_filter_notice_per_page}</span>
|
||||
</p>
|
||||
|
||||
<p class="buttons">
|
||||
<input type="submit" name="submit_profiler_filter" value="{$aLang.profiler_filter_submit}"/>
|
||||
</p>
|
||||
</form>
|
||||
<div class="right"><a href="#" onclick="return eraseFilterForm();">{$aLang.profiler_filter_erase_form}</a> | <a href="{router page='profiler'}">{$aLang.profiler_filter_erase}</a></div>
|
||||
</div></div>
|
||||
<div class="bl"><div class="br"></div></div>
|
||||
</div>
|
207
plugins/profiler/templates/skin/new/js/profiler.js
Normal file
207
plugins/profiler/templates/skin/new/js/profiler.js
Normal file
|
@ -0,0 +1,207 @@
|
|||
var lsProfilerClass = new Class({
|
||||
|
||||
Implements: Options,
|
||||
|
||||
options: {
|
||||
img : {
|
||||
path: DIR_STATIC_SKIN+'/images/',
|
||||
openName: 'open.gif',
|
||||
closeName: 'close.gif'
|
||||
},
|
||||
classes: {
|
||||
visible: 'lsProfiler_visible',
|
||||
hidden: 'lsProfiler_hidden',
|
||||
openImg: 'lsProfiler_open',
|
||||
closeImg: 'lsProfiler_close',
|
||||
treeNode: 'lsProfiler_tree',
|
||||
filterNode: 'lsProfiler_filter'
|
||||
},
|
||||
prefix: {
|
||||
img: 'img_',
|
||||
td: 'report_',
|
||||
entry: 'entry_',
|
||||
tree: 'tree_',
|
||||
treeNode: 'tree_node_'
|
||||
},
|
||||
path: {
|
||||
loadReport: aRouter['profiler']+'ajaxloadreport/',
|
||||
loadEntries: aRouter['profiler']+'ajaxloadentriesbyfilter/'
|
||||
}
|
||||
},
|
||||
|
||||
initialize: function(options){
|
||||
this.setOptions(options);
|
||||
this.make();
|
||||
},
|
||||
|
||||
make: function(expandClass){
|
||||
var thisObj = this;
|
||||
var aImgFolding=(!expandClass)?$$('img.folding'):$$('img.folding.'+expandClass);
|
||||
aImgFolding.each(function(img, i){thisObj.makeImg(img);});
|
||||
},
|
||||
|
||||
makeImg: function(img) {
|
||||
var thisObj = this;
|
||||
img.setStyles({
|
||||
'cursor' : 'pointer',
|
||||
'display' : 'inline'
|
||||
});
|
||||
img.removeClass(this.options.classes.closeImg);
|
||||
img.addClass(this.options.classes.openImg);
|
||||
img.removeEvents('click');
|
||||
img.addEvent('click',function(){
|
||||
thisObj.toggleNode(img);
|
||||
});
|
||||
},
|
||||
|
||||
toggleNode: function(img) {
|
||||
if (img.hasClass(this.options.classes.closeImg)) {
|
||||
this.collapseNode(img);
|
||||
} else {
|
||||
this.expandNode(img);
|
||||
}
|
||||
},
|
||||
|
||||
expandNode: function(img) {
|
||||
var thisObj = this;
|
||||
|
||||
img.setProperties({'src': this.options.img.path + this.options.img.closeName});
|
||||
img.removeClass(this.options.classes.openImg);
|
||||
img.addClass(this.options.classes.closeImg);
|
||||
|
||||
if(img.hasClass(thisObj.options.classes.treeNode)) {
|
||||
// Это элемент дерева - обрабатываем его соответствующим образом
|
||||
ids = img.get('id').replace(this.options.prefix.tree,'').split('_');
|
||||
|
||||
reportId=ids[0];
|
||||
var trReportId=this.options.prefix.treeNode+ids[0]+'_'+ids[1];
|
||||
var trReport=$(trReportId);
|
||||
var parentId=ids[1];
|
||||
} else {
|
||||
reportId=img.get('id').replace(this.options.prefix.img,this.options.prefix.td);
|
||||
var trReport = $(reportId);
|
||||
var parentId = 0;
|
||||
var trReportId = 0;
|
||||
}
|
||||
|
||||
if(trReport){
|
||||
trReport.show();
|
||||
} else {
|
||||
thisObj.loadReport(img.getParent('tr'),reportId,parentId,trReportId);
|
||||
}
|
||||
},
|
||||
|
||||
loadReport: function(obj,reportId,parentId,namedId) {
|
||||
var thisObj=this;
|
||||
var trCurrent = obj;
|
||||
|
||||
JsHttpRequest.query(
|
||||
'POST '+thisObj.options.path.loadReport,
|
||||
{
|
||||
reportId: reportId,
|
||||
bTreeView: true,
|
||||
parentId: parentId,
|
||||
security_ls_key: LIVESTREET_SECURITY_KEY
|
||||
},
|
||||
function(result, errors) {
|
||||
if (!result) {
|
||||
msgErrorBox.alert('Error','Please try again later');
|
||||
}
|
||||
if (result.bStateError) {
|
||||
msgErrorBox.alert(result.sMsgTitle,result.sMsg);
|
||||
} else {
|
||||
var trReport=new Element('tr', {'id':(!namedId)?reportId:namedId});
|
||||
trReport.adopt(new Element('td',{
|
||||
'colspan': 6,
|
||||
'html' : result.sReportText
|
||||
}));
|
||||
trReport.inject(trCurrent,'after');
|
||||
trReport.getElements('img').each(function(img, i){thisObj.makeImg(img);});
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
collapseNode: function(img) {
|
||||
var thisObj = this;
|
||||
|
||||
img.setProperties({'src': this.options.img.path + this.options.img.openName});
|
||||
img.removeClass(this.options.classes.closeImg);
|
||||
img.addClass(this.options.classes.openImg);
|
||||
|
||||
if(img.hasClass(thisObj.options.classes.treeNode)) {
|
||||
// Это элемент дерева - обрабатываем его соответствующим образом
|
||||
trReport=img.getParent('tr').getNext('tr');
|
||||
} else {
|
||||
reportId=img.get('id').replace(this.options.prefix.img,this.options.prefix.td);
|
||||
var trReport = $(reportId);
|
||||
}
|
||||
|
||||
trReport.hide();
|
||||
},
|
||||
|
||||
toggleEntriesByClass: function(reportId,name,link) {
|
||||
var thisObj=this;
|
||||
$$('a.profiler').removeClass('active');
|
||||
$$('a.profiler.'+name).addClass('active');
|
||||
|
||||
//var trCurrent = link.getParent('tr').getPrevious('tr');
|
||||
|
||||
JsHttpRequest.query(
|
||||
'POST '+thisObj.options.path.loadEntries+name+'/',
|
||||
{
|
||||
reportId: reportId,
|
||||
security_ls_key: LIVESTREET_SECURITY_KEY
|
||||
},
|
||||
function(result, errors) {
|
||||
if (!result) {
|
||||
msgErrorBox.alert('Error','Please try again later');
|
||||
}
|
||||
if (result.bStateError) {
|
||||
msgErrorBox.alert(result.sMsgTitle,result.sMsg);
|
||||
} else {
|
||||
var trReport = $(thisObj.options.prefix.td+reportId).empty();
|
||||
trReport.adopt(new Element('td',{
|
||||
'colspan': 5,
|
||||
'html' : result.sReportText
|
||||
}));
|
||||
trReport.getElements('img').each(function(img, i){thisObj.makeImg(img);});
|
||||
}
|
||||
},
|
||||
true
|
||||
);
|
||||
},
|
||||
|
||||
filterNode: function(obj) {
|
||||
var thisObj = this;
|
||||
var iTime=obj.get('value');
|
||||
if(iTime!='' && parseFloat(iTime)){ thisObj.highlightFilterNode(iTime); }
|
||||
},
|
||||
|
||||
highlightFilterNode: function(iTime) {
|
||||
var thisObj = this;
|
||||
|
||||
$$('.time').each(function(el,i){
|
||||
el.getParent('tr').removeClass(thisObj.options.classes.filterNode);
|
||||
if(el.get('text')>iTime) {
|
||||
el.getParent('tr').addClass(thisObj.options.classes.filterNode);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var lsProfiler;
|
||||
|
||||
window.addEvent('domready', function() {
|
||||
lsProfiler = new lsProfilerClass({
|
||||
img: {
|
||||
path: DIR_STATIC_SKIN+'/images/'
|
||||
},
|
||||
classes: {
|
||||
openImg: 'folding-open',
|
||||
closeImg: 'folding',
|
||||
filterNode: 'filter'
|
||||
}
|
||||
});
|
||||
});
|
33
templates/skin/new/actions/ActionAdmin/plugins.tpl
Normal file
33
templates/skin/new/actions/ActionAdmin/plugins.tpl
Normal file
|
@ -0,0 +1,33 @@
|
|||
{include file='header.tpl' showWhiteBack=true}
|
||||
|
||||
<div class="page people top-blogs plugins">
|
||||
<form action="{router page='admin'}plugins/" method="post" id="form_plugins_list">
|
||||
<input type="hidden" name="security_ls_key" value="{$LIVESTREET_SECURITY_KEY}" />
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td width="20px"><input type="checkbox" name="" onclick="checkAllPlugins(this);"></td>
|
||||
<td class="name">{$aLang.plugins_plugin_name}</td>
|
||||
<td class="version">{$aLang.plugins_plugin_version}</td>
|
||||
<td class="author">{$aLang.plugins_plugin_author}</td>
|
||||
<td class="action">{$aLang.plugins_plugin_action}</td>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{foreach from=$aPlugins item=aPlugin}
|
||||
<tr>
|
||||
<td><input type="checkbox" name="plugin_del[{$aPlugin.code}]" class="form_plugins_checkbox"></td>
|
||||
<td class="name"><a class="title">{$aPlugin.name}</a><br />{$aPlugin.description}<br />{$aPlugin.homepage}</td>
|
||||
<td class="version">{$aPlugin.version}</td>
|
||||
<td class="author">{$aPlugin.author}</td>
|
||||
<td class="{if $aPlugin.is_active}deactivate{else}activate{/if}"><strong>{if $aPlugin.is_active}<a href="{router page='admin'}plugins/?plugin={$aPlugin.code}&action=deactivate">{$aLang.plugins_plugin_deactivate}</a>{else}<a href="{router page='admin'}plugins/?plugin={$aPlugin.code}&action=activate">{$aLang.plugins_plugin_activate}</a>{/if}</strong></td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</tbody>
|
||||
</table>
|
||||
<input type="submit" name="submit_plugins_del" value="{$aLang.plugins_submit_delete}" onclick="return ($$('.form_plugins_checkbox:checked').length==0)?false:confirm('{$aLang.plugins_delete_confirm}');">
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{include file='footer.tpl'}
|
Loading…
Reference in a new issue