Commits

Alexandr Merekin committed fdc5b53

Imported from svn by Bitbucket

Comments (0)

Files changed (135)

+Order allow,deny
+Deny from all 

engine/classes/.htaccess

+Order allow,deny
+Deny from all 

engine/classes/CoreUtils.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса CoreUtilsclass
+ * 
+ * @author merlex
+ */
+class CoreUtils
+{
+    static function redirect($path = "/")
+    {
+        header('Location: '.$path);
+        exit;
+    }
+    static function pprint($value = "", $vd = false,$pre = true,$name = "")
+    {
+        if (PHP_SAPI == 'cli')
+            $pre = false;
+        if (!is_bool($vd)) $name = $vd;
+        if ($pre) print '<pre title="debug info" style="background-color: white">';
+        if ($name != '') print $name." : ";
+        true === $vd ? var_dump($value) : print_r($value);
+        if ($pre) print '</pre>';
+    }
+    static function usageMem($name = '')
+    {
+        if(!isset($GLOBALS['m'.$name]))
+        {
+            $GLOBALS['m'.$name] = memory_get_usage();
+            return 0;
+        }
+        else
+        {
+            return (memory_get_usage() - $GLOBALS['m'.$name]*1);
+        }
+    }
+    static function usageTime($name = '')
+    {
+        if(!isset($GLOBALS['t'.$name]))
+        {
+            $GLOBALS['t'.$name] = microtime(true);
+            return 0;
+        }
+        else
+        {
+            return round(microtime(true) - $GLOBALS['t'.$name]*1, 4);
+        }
+    }
+    /**
+     * парсит файл и ищет функции
+     * @author Mika
+     */
+    static function findFunctions($path)
+    {
+        $source = file_get_contents($path);
+        $tokens = token_get_all($source);
+
+        $funcList    = array();
+
+        $tClass = $tExtends = $tFunction = $tPublic = $tPrivate = $tProtected = $tStatic = false;
+        $catchClass = $catchExtends = $catchFunction = false;
+
+        $class    = '';
+        $extends  = '';
+        $function = '';
+
+        $parentness = 0;
+        foreach ($tokens as $tokenKey => $token)
+        {
+            if (is_string($token))
+            {
+                switch ($token)
+                {
+                    case ';':
+                        $tPublic = $tPrivate = $tProtected = $tStatic = false;
+                        break;
+                    case '{':
+                        $parentness++;
+                        break;
+                    case '}':
+                        $parentness--;
+                        break;
+                }
+                if (0 == $parentness)
+                {
+                    $tClass = $tExtends = $tFunction = $tPublic = $tPrivate = $tProtected = $tStatic = false;
+                    $catchClass = $catchExtends = $catchFunction = false;
+                }
+            }
+            else
+            {
+                // token array
+                list($id, $text) = $token;
+
+                switch ($id)
+                {
+                    case T_CLASS:// class
+                        $tClass = true;
+                        $catchClass = true;
+                        break;
+                    case T_EXTENDS:
+                        $tExtends = true;
+                        $catchExtends = true;
+                        break;
+                    case T_FUNCTION:
+                        $tFunction = true;
+                        $catchFunction = true;
+                        break;
+                    case T_PUBLIC:
+                        $tPublic = true;
+                        break;
+                    case T_PROTECTED:
+                        $tProtected = true;
+                        break;
+                    case T_PRIVATE:
+                        $tPrivate = true;
+                        break;
+                    case T_STATIC:
+                        $tStatic = true;
+                        break;
+                    case T_STRING:
+                        if ($catchClass)
+                        {
+                            $class = $text;
+                            $catchClass = false;
+                            $funcList['class'][$class] = array('extends'=>'','function'=>array());
+                        }
+                        elseif ($catchExtends)
+                        {
+                            $extends = $text;
+                            $catchExtends = false;
+                            $funcList['class'][$class]['extends'] = $extends;
+                        }
+                        elseif ($catchFunction)
+                        {
+                            $function = $text;
+                            $catchFunction = false;
+                            /**
+                             * если установленны класс - то это методы
+                             * если не установленны модификаторы доступа - то T_PUBLIC
+                             */
+                            if ($tClass)
+                            {
+                                $public = $tProtected || $tPrivate ? 0 : 1;
+                                $funcList['class'][$class]['function'][] = array('name'=>$function,
+                                                                               'public'=>$public,);
+                            }
+                            else
+                                $funcList['function'][] = $function;
+                        }
+                        break;
+                }
+            }
+        }
+        return $funcList;
+    }
+    /**
+     * Возвращаем разницу 2 массивов
+     * @param array $arr1
+     * @param array $arr2
+     * @return array
+     */
+    static function diff_array ($arr1, $arr2)
+    {
+        $result = array();
+        foreach($arr1 as $a1key => $a1val)
+        {
+            $add = true;
+            foreach($arr2 as $a2key => $a2val)
+            {
+                if($a1val === $a2val) $add = false;
+            }
+            if($add)
+            {
+                $result[] = $a1val;
+            }
+        }
+        return $result;
+    }
+    /**
+     * парсит каркас и ищет функции
+     * @author MerLex
+     */
+    static function parseFrame($path)
+    {
+        $source = file_get_contents($path);
+        $tokens = token_get_all($source);
+
+        $blockList    = array();
+
+        $tPrint = $tComent = $tVarName = $tOpenTag = $tCloseTag = false;
+        $vComent = $vVarName = '';
+
+        foreach ($tokens as $tokenKey => $token)
+        {
+            if (!is_string($token))
+            {
+                // token array
+                list($id, $text) = $token;
+                switch ($id)
+                {
+                    case T_ECHO:
+                    case T_PRINT:
+                        if($tOpenTag&&$tComent)
+                        {
+                            $tPrint = true;
+                            $tVarName = false;
+                        }
+                        break;
+                    case T_OPEN_TAG:
+                        $tOpenTag = true;
+                        $tPrint = $tVarName = $tComent = false;
+                        break;
+                    case T_CLOSE_TAG:
+                        $tPrint = $tVarName = $tComent = $tOpenTag = false;
+                        break;
+                    case T_CONSTANT_ENCAPSED_STRING:// class
+                        if($tComent&&$tOpenTag&&$tPrint)
+                        {
+                            $tVarName = true;
+                            $vVarName = trim(trim(trim($text,"'"),'"'));
+                            $tPrint = $tComent = $tOpenTag = false;
+                        }
+                        break;
+                    case T_COMMENT:// class
+                        if($tOpenTag)
+                        {
+                            $tComent = true;
+                            $vComent = trim(trim(trim($text,'/*'),'*/'));
+                            $tVarName = false;
+                        }
+                        break;
+                }
+                if($tVarName)
+                {
+                    $blockList[] = array('block' => $vVarName,'desc' => $vComent);
+                    $tPrint = $tVarName = $tComent = $tOpenTag = false;
+                }
+            }
+        }
+        return $blockList;
+    }
+    /**
+     * Изменение падежа слова (Первое - для нуля, второе - для единицы, третье - для двойки).
+     *
+     * Пример. 0 падежей, 1 падеж, 2 падежа.
+     * Число передаём в $num.
+     * Массив с тремя словами - в $words.
+     * Первое - для нуля, второе - для единицы,
+     * третье - для двойки.
+     *
+     * @param integer $num
+     * @param array $words array('комментариев', 'комментарий', 'комментария')
+     * @param bool $withNum вывести слово вместе с числом?
+     * @return string
+     */
+    static function changeWordForm( $num, $words, $withNum = false )
+    {
+        $array[0] = array( 0, 5, 6, 7, 8, 9 );
+        $array[1] = array( 1 );
+        $array[2] = array( 2, 3, 4 );
+
+        $numLast = substr( $num, -1 );
+
+        if ( $withNum == true )
+        {
+            for ( $i = 0; $i < 3; $i++ )
+            {
+                $words[$i] = $num.' '.$words[$i];
+            }
+        }
+
+        if ( $num > 9 )
+        {
+            if ( substr( $num, -2, 1 ) == 1 )
+            {
+                return $words[0];
+            }
+        }
+
+        for ( $i = 0; $i < 3; $i++ )
+        {
+            if ( in_array( $numLast, $array[$i] ) )
+            {
+                return $words[$i];
+            }
+        }
+
+        return $words[0];
+    }
+    /**
+     * Разбираем путь на части
+     * @param string $path
+     */
+    static function parsePath($path)
+    {
+        $params = array();
+        $request = trim($path,"\/");
+        $pathElement = explode('/', $request);
+        foreach ($pathElement as $pekey => $peval)
+        {
+            $pathElement[$pekey] = preg_replace('/[^A-Za-z0-9_]*/', '', $peval);
+        }
+        $params['parts'] = $pathElement;
+        $params['path'] = implode('/', $pathElement);
+        return $params;
+    }
+}
+?>

engine/classes/DB.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Description of DB class
+ *
+ * @author MerLex
+ */
+class DB
+{
+	public static $link = null;
+
+	public static $queryCount = 0;
+
+	public static $queryLast;
+
+	public static $queryTime = 0;
+
+	public static $queryLong;
+
+	public static $queryArr = array();
+    /**
+     * Коннект
+     */
+    public static function connect($params = null)
+    {
+		if (!$params)
+        {
+			$db = $GLOBALS['DB_SETTINGS'];
+        }
+	    elseif (is_array($params))
+        {
+	        $db = $params;
+        }
+
+        switch ($db['type'])
+        {
+            case 'mysql':
+        		self::$link = mysqli_connect($db['host'],$db['user'],$db['pass'],$db['db'],$db['port']);
+        		break;
+            default:
+                throw new DBException('unsopported db type');
+                break;
+        }
+        if (!self::$link)
+        {
+            throw new DBException('cannt connect to db:'.$db['type']);
+        }
+		return true;
+    }
+    /**
+     * Выполнить запрос
+     */
+    public static function parse($query, $resultType = MYSQLI_ASSOC)
+    {
+        $data=array();
+        if(!($record = self::query($query)))
+        {
+            return $record;
+        }
+		preg_match("/^SELECT|^SHOW|^DESCRIBE|^EXPLAIN|^DELETE|^INSERT|^REPLACE|^UPDATE/",strtoupper(substr(ltrim($query),0,10)),$a);
+		switch (isset($a[0]) ? "".$a[0] : "")
+		{
+			case "INSERT":
+				return mysqli_insert_id(self::$link);
+			case "DELETE":
+			case "REPLACE":
+			case "UPDATE":
+				//для этой группы можно вернуть количество затронутых рядов и все, парсить ничего не надо.
+				return mysqli_affected_rows(self::$link);
+			case "SELECT":
+			case "SHOW":
+			case "DESCRIBE":
+			case "EXPLAIN":
+				//для этой группы только и можно производить дальнейшую обработку, так как у всех остальных $result = TRUE
+				if (!mysqli_num_rows($record)) return null;
+				break;
+			default:
+				return $record;
+		}
+        $rawData=array();
+        while($row=mysqli_fetch_array($record, $resultType))
+        {
+            foreach ($row as $fieldName => $fieldValue)
+            {
+                $rawData["$fieldName"] = $fieldValue;
+            }
+            $data[] = $rawData;
+        }
+        mysqli_free_result($record);
+        return $data;
+    }
+	/**
+	 * Выполняет запрос, возвращает resource# или null или кидает DBException
+	 * @param string $sqlText
+	 * @return resource|null|DBException
+	 */
+	public static function query($query)
+	{
+	    self::$queryLast = $query;
+		self::$queryCount++;
+		if (!self::$link && !self::connect())
+    	    return null;
+
+        $sTime = microtime(true);
+		$result = mysqli_query(self::$link, $query);
+        $queryTime = round(microtime(true) - $sTime, 5);
+        if(DEBUG_INFO)
+            self::$queryArr[]= array('query'=> $query,'time'=> $queryTime);
+        if($queryTime > self::$queryTime)
+        {
+            self::$queryTime = $queryTime;
+            self::$queryLong = self::$queryLast;
+        }
+
+        $errArr = DB::error();
+		if ($errArr['id'] != 0)
+		    throw new DBException('rise db error');
+		return $result;
+	}
+    /**
+     * Отсоединяемся
+     */
+    public static function disconnect()
+    {
+	    @mysqli_close(self::$link);
+    }
+	/**
+	 * возвращает ошибку MySQL
+	 *
+	 * @return array
+	 */
+	public static function error()
+	{
+		if (!self::$link)
+		{
+    		return array("id" => -1,
+                         "text"=>"link to base is null(".mysqli_connect_errno().
+                                 ":".mysqli_connect_error().")"
+                        );
+		}
+		else
+		{
+    		return array("id" => mysqli_errno(self::$link),
+                         "text"=>mysqli_error(self::$link)
+                        );
+		}
+	}
+    /**
+     *
+     * @param string $query
+     * @return string
+     */
+	public static function escape($query)
+	{
+		if (!self::$link)
+		{
+		    self::connect();
+			if (!(self::$link))	return null;
+		}
+		return mysqli_real_escape_string(self::$link,$query);
+	}
+}
+?>

engine/classes/DBException.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса DBExceptionclass
+ *
+ * @author merlex
+ */
+class DBException extends Exception
+{
+	function __construct($text = '')
+	{
+        $err = DB::error();
+	    $message = $err['text']."\nquery:\n".DB::$queryLast;
+		parent::__construct($text.' - '.$message,$err['id']);
+	}
+}
+?>

engine/classes/Debug.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/* 
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ * Description of Debugclass
+ *
+ * @author MerLex
+ */
+class Debug
+{
+    public static $firephp      = null;
+    protected static $outputType   = 'panel';
+    protected static $pathFile     = '';
+    protected static $debugData = '';
+
+    public static function create()
+    {
+        self::$firephp = FirePHP::getInstance(true);
+        return self::$firephp;
+    }
+    public static function setType($type)
+    {
+        self::$outputType = $type;
+    }
+    public static function getType()
+    {
+        return self::$outputType;
+    }
+    public static function setPathFile($pathFile)
+    {
+        self::$pathFile = $pathFile;
+    }
+    public static function write($text)
+    {
+        $position = '';
+        $bt = debug_backtrace();
+        if(is_array($bt))
+        {
+            $position = 'File: '.$bt[0]['file'].' ('.$bt[0]['line'].')';//."\r\n";
+        }
+        switch (self::$outputType)
+        {
+            case 'panel':
+                return self::writeToPanel($text, $position);
+                break;
+            case 'firephp':
+                return self::writeToFirephp($text);
+                break;
+            case 'file':
+                return self::writeToFile($text, $position);
+                break;
+            default:
+                return true;
+                break;
+        }
+    }
+    public static function writeToFirephp($text)
+    {
+        if(!self::$firephp&&!self::create()&&!DEBUG_INFO)
+        {
+            return false;
+        }
+        self::$firephp->log(print_r($text, true));
+        return true;
+    }
+    public static function writeToPanel($text, $position)
+    {
+        self::$debugData .= "\r\n".$position.'<pre>'.print_r($text, true).'</pre>';
+        return true;
+    }
+    public static function writeToFile($text, $position)
+    {
+        if(self::$pathFile&&is_dir(dirname(self::$pathFile)))
+        {
+            $fp = fopen(self::$pathFile, 'a+');
+            if($fp)
+            {
+                flock($fp, LOCK_EX);
+                fwrite($fp, "\r\nDate: ".date('d-m-Y H:m:s')."\r\n".$position."\r\n".print_r($text, true));
+                flock($fp, LOCK_UN);
+                fclose($fp);
+                return true;
+            }
+        }
+        return false;
+    }
+    public static function showPanel()
+    {
+        if(!DEBUG_INFO)
+        {
+            return;
+        }
+        $tpl = new Template(PATH_TO_ENGINE_BLOCK);
+        $responseHtmlArr = array();
+        $responseHtmlArr['content'] = $tpl->render('debug.panel', array('content' => print_r(self::$debugData,true)));
+        return $tpl->render('blank', $responseHtmlArr, PATH_TO_ENGINE_FRAME);
+    }
+
+}
+?>

engine/classes/FileException.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса FileException
+ *
+ * @author merlex
+ */
+class FileException extends Exception
+{
+    function __construct($text = '')
+    {
+        parent::__construct($text,1);
+    }
+}
+?>

engine/classes/FlatPage.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Класс страница
+ *
+ * @author MerLex
+ */
+class FlatPage
+{
+    // Название страницы
+    protected $table = 'core_flatpage';
+    // Название страницы
+    protected $name;
+    // Путь
+    protected $path;
+    // Тело страницы
+    protected $text;
+    // Параметры страницы
+    protected $data = array();
+    /**
+     * Конструктор класса
+     * @param int $id
+     */
+    public function __construct($id = 0)
+    {
+        if($id*=1)
+        {
+            $this->getPageById($id);
+        }
+    }
+    /**
+     * Получить страницу по номеру
+     * @param int $id
+     */
+    public function getPageById($id)
+    {
+        if($id*=1)
+        {
+            $query = 'SELECT * FROM '.DEFAULT_DB.'.'.$this->table.' WHERE id = '.$id;
+            $this->data = db::parse($query);
+            if(is_array($this->data)&&count($this->data))
+            {
+                if(isset($this->data['name']))
+                {
+                    $this->name = $this->data['name'];
+                }
+                if(isset($this->data['path']))
+                {
+                    $this->path = $this->data['path'];
+                }
+                if(isset($this->data['text']))
+                {
+                    $this->text = $this->data['text'];
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+    public function getPageByPath($path)
+    {
+        $params = CoreUtils::parsePath($path);
+        if(is_array($params))
+        {
+            $query = 'SELECT * FROM '.DEFAULT_DB.'.'.$this->table.' WHERE path LIKE "'.$params['path'].'"';
+            $this->data = db::parse($query);
+            if(is_array($this->data)&&count($this->data))
+            {
+                if(isset($this->data['name']))
+                {
+                    $this->name = $this->data['name'];
+                }
+                if(isset($this->data['path']))
+                {
+                    $this->path = $this->data['path'];
+                }
+                if(isset($this->data['text']))
+                {
+                    $this->text = $this->data['text'];
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Получить все страницы
+     */
+    public function getAllPage()
+    {
+        $query = 'SELECT * FROM '.DEFAULT_DB.'.'.$this->table;
+        $data = db::parse($query);
+        return $data;
+    }
+}
+?>

engine/classes/Handler.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса Handlerclass
+ *
+ * @author merlex
+ */
+abstract class Handler
+{
+    /**
+    * Идентификатор контейнера
+    * @var unknown_type
+    */
+    protected $handlerId;
+    /**
+     * Текущий пользователь
+     * @var User
+     */
+    protected $user;
+    protected $userId = 0;
+    /**
+     * Данные запроса
+     * @var array
+     */
+    protected $request = 0;
+
+    public function __construct($handlerId, &$user, &$request)
+    {
+/*        if($user instanceof User)
+            $this->userId = $user->getField('id');
+        else
+            $this->userId = 0;
+*/
+        $this->handlerId = $handlerId;
+        $this->user      = & $user;
+
+        $this->request   = & $request;
+    }
+
+    public function setHandlerId($handlerId)
+    {
+        $this->handlerId = $handlerId;
+    }
+    /**
+     *
+     * @param string $name
+     * @param array $value
+     * @param mixed $default
+     */
+    public function get($name, $value, $default='')
+    {
+        if(isset($value[$name]))
+        {
+            return $value[$name];
+        }
+        return $default;
+    }
+
+    //abstract public function getData($params=null);
+}

engine/classes/Message.class.php

+<?php
+/**
+ * Краткое описание класса Message
+ *
+ * Длинное описание класса (если есть)...
+ *
+ * @author merlex
+ */
+class Message
+{
+    protected static $data = array();
+
+    /**
+     * Добавить сообщение
+     *
+     * @param <type> $text
+     * @param <type> $type
+     */
+    public static function setMessage($text, $type = 'info')
+    {
+        self::$data[] = array('type' => $type, 'text' => $text);
+        return true;
+    }
+    /**
+     * Получить MessageBox
+     */
+    public static function getMessageBox()
+    {
+        if(is_array(self::$data)&&count(self::$data))
+        {
+            $tpl = new Template(PATH_TO_ENGINE_BLOCK);
+            $responseHtmlArr = array();
+            $responseHtmlArr['content'] = $tpl->render('message.box', array('content' => self::$data));
+            return $tpl->render('blank', $responseHtmlArr, PATH_TO_ENGINE_FRAME);
+        }
+    }
+}
+?>

engine/classes/Resolver.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Description of Resolver
+ *
+ * @author MerLex
+ */
+class Resolver
+{
+    public static $pathArr = array();
+    /**
+     *
+     * @param <type> $class
+     */
+    public static function resolveName($class)
+    {
+        if(is_array(self::$pathArr)&&count(self::$pathArr))
+        foreach(self::$pathArr as $pakey => $paval)
+        {
+            if(file_exists($paval.$class.'.class.php'))
+            {
+                require_once($paval.$class.'.class.php');
+                if(class_exists($class))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    /**
+     *
+     * @param <type> $class
+     */
+    public static function classExists($class, $pathToClass)
+    {
+        if ($pathToClass == '')
+            return false;
+        self::$pathArr[] = $pathToClass;
+        $ret = class_exists($class);
+        return $ret;
+    }
+    /**
+     *
+     * @param <type> $pathToClass
+     * @return <type>
+     */
+    public static function addClassPath($pathToClass)
+    {
+        if ($pathToClass == '')
+            return false;
+        if(is_dir($pathToClass))
+        {
+            self::$pathArr[] = $pathToClass;
+            return true;
+        }
+        return false;
+    }
+}
+?>

engine/classes/Router.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/* 
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ * Description of Routerclass
+ *
+ * @author MerLex
+ */
+Class Router
+{
+    private $path;
+
+    private $params = array();
+
+    private $pathType;
+
+    private $pathToAdmin;
+
+    private $subDir;
+    /**
+     * Конструктор
+     */
+    function __construct($pathToAdmin = 'admin', $subDir = '')
+    {
+        $this->pathToAdmin = $pathToAdmin;
+        $this->subDir      = trim($subDir,"\/");
+    }
+    /**
+     * Парсим путь
+     */
+    private function parsePath()
+    {
+        $request = $_SERVER['REQUEST_URI'];
+        list($request,) = explode('?', $request);
+        $request = trim($request,"\/");
+        if($this->subDir)
+        {
+            $request = preg_replace('/^'.$this->subDir.'(.*)$/', '\\1', $request);
+            $request = trim($request,"\/");
+        }
+        $pathElement = explode('/', $request);
+        foreach ($pathElement as $pekey => $peval)
+        {
+            $pathElement[$pekey] = preg_replace('/[^A-Za-z0-9_]*/', '', $peval);
+        }
+        $this->params = $pathElement;
+        $this->path = implode('/', $pathElement);
+        return true;
+    }
+    /**
+     *
+     * @param <type> $pathToAdmin
+     * @return <type>
+     */
+    private function checkInAdmin($pathToAdmin = '')
+    {
+        if($pathToAdmin != '')
+            $this->pathToAdmin = $pathToAdmin;
+            if(is_array($this->params)&&count($this->params))
+            {
+                if($this->params[0] == $this->pathToAdmin)
+                {
+                    return true;
+                }
+            }
+        return false;
+    }
+    /**
+     *
+     * @param <type> $pathToAdmin
+     * @return <type>
+     */
+    public function getPath()
+    {
+        if(!$this->path)
+            $this->parsePath();
+
+        return $this->path;
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function getParams()
+    {
+        if(is_array($this->params)&&count($this->params))
+            return $this->params;
+
+        $this->parsePath();
+
+        return $this->params;
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function dispatcher()
+    {
+        $responseHtml = '';
+        $params   = array();
+        if(!is_array($this->params)||!count($this->params))
+            $this->parsePath();
+        $inAdmin = $this->checkInAdmin();
+        $params['pathInfo'] = array('path'=>$this->path,'params'=>$this->params);
+
+        $user = new User(0);
+        //restore user
+        if(isset($_SESSION['userId'])&&$_SESSION['userId'] *= 1)
+        {
+            $user = new User($_SESSION['userId']);
+        }
+        else if(!$user->initFromCookie())
+        {
+            $_SESSION['userId'] = 0;
+        }
+        //logout
+        if(isset($params['pathInfo']['path'])&&strpos($params['pathInfo']['path'],'logout') !== false)
+        {
+            $user->logout();
+            CoreUtils::redirect('/');
+            die();
+        }
+        //login
+        if(isset($_POST['login'])&&isset($_POST['password'])&&isset($_POST['enterKey'])&&$_POST['enterKey'] == $_SESSION['enterKey'])
+        {
+            $user->login($_POST['login'], $_POST['password']);
+        }
+        if($inAdmin)
+        {
+            $className = (isset($this->params[1]))?($this->params[1]):('Index');
+            $methodName = (isset($this->params[2]))?($this->params[2]):('index');
+
+            if($user->isUnknown())
+            {
+                $className  = 'Index';
+                $methodName = 'login';
+            }
+            if(!Resolver::resolveName($className))
+            {
+                throw new FileException('cannot find class "'.$className.'"');
+            }
+            $class = new $className(null, $user, $params);
+            if(!method_exists($class,$methodName))
+            {
+                throw new FileException('cannot find method "'.$methodName.'" for class "'.$className.'"');
+            }
+            $response = $class->$methodName($params);
+            if(is_array($response)&&count($response))
+            {
+                if (is_array($response['template'])&&count($response['template']))
+                {
+                    $response['params'] = $params;
+                    $tpl = new Template(PATH_TO_ENGINE_BLOCK);
+                    $responseHtmlArr = array();
+                    foreach($response['template'] as $tkey => $tval)
+                    {
+                        $responseHtmlArr[$tkey] = $tpl->render($tval, $response);
+                    }
+                    $responseHtmlArr['params'] = $params;
+                    $adminFrame = (isset($response['template']['frame']))?($response['template']['frame']):(DEFAULT_ADMIN_FRAME);
+                    $responseHtml = $tpl->render($adminFrame, $responseHtmlArr, PATH_TO_ENGINE_FRAME);
+                }
+                else
+                {
+                    $responseHtml = '';
+                }
+            }
+        }
+        else
+        {
+            //TODO получить все пути из базы отсортированные по длинне и сравнивать
+            $curPath  = array();
+            $query    = 'SELECT * FROM '.DEFAULT_DB.'.core_path ORDER BY LENGTH(path) DESC';
+            $dbResult = DB::parse($query);
+            if(is_array($dbResult)&&count($dbResult))
+            {
+                foreach($dbResult as $pval)
+                {
+                    if(stristr('/'.$params['pathInfo']['path'].'/', '/'.$pval['path'].'/') !== false)
+                    {
+                        $curPath = $pval;
+                        break;
+                    }
+                }
+                $dbPages = array();
+                if(is_array($curPath)&&count($curPath))
+                {
+                    $query   = 'SELECT * FROM '.DEFAULT_DB.'.core_page WHERE path_id = '.$curPath['id'];
+                    $dbPages = DB::parse($query);
+                }
+                if(is_array($dbPages)&&count($dbPages))
+                {
+                    $responseHtmlArr = array();
+                    $tpl             = new Template(PATH_TO_PROJECT_BLOCK);
+                    $curFrame        = $dbPages[0]['frame_name'];
+                    foreach($dbPages as $pval)
+                    {
+                        $curParams = $params;
+                        $query   = 'SELECT * FROM '.DEFAULT_DB.'.core_handler WHERE id = '.$pval['handler_id'];
+                        list($dbHandler,) = DB::parse($query);
+                        $className = (isset($dbHandler['class']))?($dbHandler['class']):('Index');
+                        $methodName = (isset($dbHandler['method']))?($dbHandler['method']):('index');
+                        $blockParams = unserialize(trim($pval['param']));
+                        if(is_array($blockParams)&&count($blockParams))
+                        {
+                            $curParams = array_merge_recursive($curParams, $blockParams);
+                        }
+                        $curParams['template'] = $pval['template'];
+                        if(!Resolver::resolveName($className))
+                        {
+                            throw new FileException('cannot find class "'.$className.'"');
+                        }
+                        $class = new $className($dbHandler['id'], $user, $curParams);
+                        if(!method_exists($class,$methodName))
+                        {
+                            throw new FileException('cannot find method "'.$methodName.'" for class "'.$className.'"');
+                        }
+                        //Обработка хендлера
+                        $curParams['data'] = $class->$methodName($curParams);
+                        //рендерим блок
+                        if($curParams['template'])
+                        {
+                            $responseHtmlArr[$pval['block_name']] = $tpl->render($curParams['template'], $curParams);
+                        }
+                        else
+                        {
+                            $responseHtmlArr[$pval['block_name']] = '';
+                        }
+                    }
+                    $responseHtml = $tpl->render($curFrame, $responseHtmlArr, PATH_TO_PROJECT_FRAME);
+                }
+            }
+            else
+            {
+                
+            }
+        }
+
+        return $responseHtml;
+    }
+}
+?>

engine/classes/Template.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса Templateclass
+ *
+ * @author merlex
+ */
+class Template
+{
+    /**
+     * защита от зацикливания include.
+     * @var array
+     */
+    private $include = array();
+    /**
+     * содержит имя файла шаблона, который в данный момент обраьбатывается.
+     * нужно для более информативного вывода в случае обнаружения цикла в инклюде
+     * @var string
+     */
+    private $includeName;
+    /**
+     * данные для заполнения шаблона
+     * @var array
+     */
+    public $data;
+
+    private $pathTemplate  = '';
+
+    public function __construct($pathTemplate = '')
+    {
+        if($pathTemplate  != '')
+        {
+            $this->pathTemplate = $pathTemplate;
+        }
+    }
+    /**
+     *
+     * @param <type> $__text
+     * @param <type> $__exported
+     * @return <type>
+     */
+    private function buildTemplate($__text,$__exported)
+    {
+        if(is_array($__exported)&&count($__exported))
+        foreach($__exported as $__name => $__value)
+        {
+            $PARAM[$__name] = $__value;
+        }
+/*
+        $__filename = tempnam(TEMP_DIR,'TPL_');
+        file_put_contents($__filename,$__text);
+*/
+        ob_start();
+        include $__text;
+        $__contents = ob_get_contents();
+        ob_end_clean();
+//        unlink($__filename);
+        return $__contents;
+    }
+    /**
+     *
+     * @param <type> $fileName
+     * @param <type> $args
+     * @return <type>
+     */
+    public function render($fileName, $args = null, $pathTemplate = '')
+    {
+        $content = '';
+        if($pathTemplate)
+        {
+            $this->pathTemplate = $pathTemplate;
+        }
+        if(isset($this->include[$fileName]))
+        {
+            return '';
+        }
+        if (!file_exists($this->pathTemplate.$fileName.TEMPLATE_EXT))
+        {
+            throw new FileException('cannot find template "'.$fileName.'"');
+        }
+        if($args)
+        {
+            $this->data = $args;
+        }
+        $this->include[$fileName] = 1;
+        $this->includeName = $fileName;
+
+//        $content = file_get_contents($this->pathTemplate.$fileName.TEMPLATE_EXT);
+//        $content = $this->checkTemlpate($content);
+//        $content = $this->buildTemplate($content, $args);
+        $templateFile = $this->pathTemplate.$fileName.TEMPLATE_EXT;
+        $content = $this->buildTemplate($templateFile, $args);
+
+        unset($this->include[$fileName]);
+        return $content;
+    }
+}
+?>

engine/classes/User.class.php

+<?php
+/**
+ * Краткое описание класса User
+ *
+ * Длинное описание класса (если есть)...
+ *
+ * @author merlex
+ */
+class User
+{
+    protected $userId = 0;
+    
+    protected $userData;
+
+    protected $unknownUser = true;
+
+    public function __construct($userId = 0)
+    {
+        $this->unknownUser = true;
+        if($userId *= 1)
+        {
+            $query   = 'SELECT * FROM '.DEFAULT_DB.'.core_user WHERE id = '.$userId;
+            $userVar = db::parse($query);
+            if(is_array($userVar)&&count($userVar))
+            {
+                $this->userId      = $userVar[0]['id'];
+                $this->userData    = $userVar[0];
+                $this->unknownUser = false;
+            }
+            else
+            {
+                $this->userId   = 0;
+                $this->userData = array();
+            }
+        }
+        else
+        {
+            $this->userId   = 0;
+            $this->userData = array();
+        }
+    }
+    /**
+     * Инициализировать пользователя с помощью логина и пароля
+     *
+     * @param string $login
+     * @param string $pass
+     */
+    public function init($login,$pass)
+    {
+        $this->unknownUser = true;
+        if(!$login&&!$pass)
+        {
+            return false;
+        }
+        $md5pass = md5(SECRET_KEY.$login[2].$pass);
+        $login   = preg_replace('/[^0-9a-zA-Z_]*/', '', $login);
+        $query   = 'SELECT * FROM '.DEFAULT_DB.'.core_user WHERE login = "'.db::escape($login).'"';
+        $userVar = db::parse($query);
+        if(is_array($userVar)&&count($userVar))
+        {
+            if($userVar[0]['pass'] == $md5pass)
+            {
+                $this->userId      = $userVar[0]['id'];
+                $this->userData    = $userVar[0];
+                $this->unknownUser = false;
+                return true;
+            }
+        }
+        
+        $this->userId   = 0;
+        $this->userData = array();
+        $this->unknownUser = true;
+        return false;
+    }
+
+    /**
+     * Логинимся
+     */
+    public function login($login,$pass)
+    {
+        $this->unknownUser = true;
+        $_SESSION['userId'] = 0;
+        if(!$login&&!$pass)
+        {
+            return false;
+        }
+        $login   = preg_replace('/[^0-9a-zA-Z_]*/', '', $login);
+        if($this->init($login, $pass))
+        {
+            $md5pass = md5(SECRET_KEY.$this->userData['pass'].$_SERVER['REMOTE_ADDR']);
+            setcookie('eui', $this->userId, time()+3600);
+            setcookie('euh', $md5pass, time()+3600);
+            $_SESSION['userId'] = $this->userId;
+            return true;
+        }
+        return false;
+    }
+    /**
+     * Разлогинимся
+     */
+    public function logout()
+    {
+        setcookie('eui', '');
+        setcookie('euh', '');
+    	unset ($_COOKIE['eui']);
+    	unset ($_COOKIE['euh']);
+        $_SESSION['userId'] = 0;
+        session_destroy();
+        $this->userId       = 0;
+        $this->userData     = array();
+        $this->unknownUser  = true;
+    }
+    /**
+     * Логинимся
+     */
+    public function initFromCookie()
+    {
+        $this->unknownUser = true;
+        if(!isset($_COOKIE['eui'])||!isset($_COOKIE['euh']))
+        {
+            return false;
+        }
+        $userId = $_COOKIE['eui']*1;
+        if(!$userId)
+        {
+            return false;
+        }
+        $query   = 'SELECT * FROM '.DEFAULT_DB.'.core_user WHERE id = '.db::escape($userId);
+        $userVar = db::parse($query);
+        if(is_array($userVar)&&count($userVar))
+        {
+            $md5pass = md5(SECRET_KEY.$userVar[0]['pass'].$_SERVER['REMOTE_ADDR']);
+            if($_COOKIE['euh'] == $md5pass)
+            {
+                $this->userId   = $userVar[0]['id'];
+                $this->userData = $userVar[0];
+                $this->unknownUser = false;
+                $_SESSION['userId'] = $this->userId;
+                return true;
+            }
+        }
+        return false;
+    }
+    /**
+     * Проверяет прошёл ли юзер авторизацию
+     *
+     * @return bool
+     */
+    public function isUnknown()
+    {
+        return $this->unknownUser;
+    }
+    /**
+     * Возвращает набор атрибутов пользователя в виде ассоциативного массива
+     *
+     */
+    public function asArray()
+    {
+        return $this->userData;
+    }
+    /**
+     * Получить значение атрибута
+     *
+     * @param string $field
+     * @return <type>
+     */
+    public function getField($field)
+    {
+        if (isset($this->userData[$field]))
+            return $this->userData[$field];
+        else
+            return null;
+    }
+    /**
+     * Установить значение атрибута
+     *
+     * @param string $field
+     * @return <type>
+     */
+    public function setField($field,$value)
+    {
+        $this->userData[$field] = $value;
+    }
+}
+?>

engine/config.engine.php

+<?php
+/* 
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+    /**
+     * проверка доступа
+     */
+    defined('ACCESS') or die('Direct Access to this location is not allowed.');
+    error_reporting(E_ALL);
+    /**
+     * Выводим отладочную информацию или нет
+     */
+    define('DEBUG_INFO', $debugInfo);
+    /**
+    * Путь до корня
+    */
+    define('PATH_TO_ROOT', dirname(__FILE__).DIRSEP.'..'.DIRSEP);
+    /**
+    * Путь до корня
+    */
+    define('PATH_TO_WWW', $_SERVER['DOCUMENT_ROOT'].DIRSEP);
+    /**
+    * Путь до системы
+    */
+    define('PATH_TO_ENGINE', dirname(__FILE__).DIRSEP);
+    /**
+    * Путь до админки
+    */
+    define('PATH_TO_ADMIN', 'admin');
+    /**
+    * Путь до шаблонов ядра системы
+    */
+    define('PATH_TO_ENGINE_TEMPLATE', PATH_TO_ENGINE.'template'.DIRSEP);
+    /**
+    * Путь до каркасов проекта
+    */
+    define('PATH_TO_ENGINE_FRAME', PATH_TO_ENGINE_TEMPLATE.'frame'.DIRSEP);
+    /**
+    * Путь до блоков проекта
+    */
+    define('PATH_TO_ENGINE_BLOCK', PATH_TO_ENGINE_TEMPLATE.'block'.DIRSEP);
+    /**
+    * Путь до обработчиков ядра системы
+    */
+    define('PATH_TO_ENGINE_HANDLER', PATH_TO_ENGINE.'handler'.DIRSEP);
+    /**
+    * Путь до классов ядра системы
+    */
+    define('PATH_TO_ENGINE_CLASSES', PATH_TO_ENGINE.'classes'.DIRSEP);
+    /**
+    * Путь до классов ядра системы
+    */
+    define('PATH_TO_ENGINE_LIBRARY', PATH_TO_ENGINE.'library'.DIRSEP);
+    /**
+    * Путь до шаблонов проекта
+    */
+    define('PATH_TO_PROJECT_TEMPLATE', PATH_TO_PROJECT.'template'.DIRSEP);
+    /**
+    * Путь до каркасов проекта
+    */
+    define('PATH_TO_PROJECT_FRAME', PATH_TO_PROJECT_TEMPLATE.'frame'.DIRSEP);
+    /**
+    * Путь до блоков проекта
+    */
+    define('PATH_TO_PROJECT_BLOCK', PATH_TO_PROJECT_TEMPLATE.'block'.DIRSEP);
+    /**
+    * Путь до обработчиков проекта
+    */
+    define('PATH_TO_PROJECT_HANDLER', PATH_TO_PROJECT.'handler'.DIRSEP);
+    /**
+    * Путь до классов проекта
+    */
+    define('PATH_TO_PROJECT_CLASSES', PATH_TO_PROJECT.'classes'.DIRSEP);
+    /**
+    * Расширение файлов шаблонов
+    */
+    define('TEMPLATE_EXT', '.tpl');
+
+    define('PATH_TYPE_PAGE', 0);
+
+    define('PATH_TYPE_XHR', 1);
+
+    define('DEFAULT_ADMIN_FRAME', 'admin');
+
+    define('DEFAULT_DB', $DB_SETTINGS['db']);
+
+    $host = '';
+    $port = '';
+    $httpHost = explode(':',$_SERVER['HTTP_HOST'],2);
+    if(isset($httpHost[0])) $host = $httpHost[0];
+    if(isset($httpHost[1])) $host = $httpHost[1];
+    define('DOMAIN_ROOT', $host);
+    define('DOMAIN_PORT', $port);
+
+    define('TEMP_DIR',$_SERVER['DOCUMENT_ROOT'].DIRSEP.'..'.DIRSEP.'..'.DIRSEP.'..'.DIRSEP.'tmp');
+
+    $curPath = '';
+    list($request,) = explode('?', $_SERVER['REQUEST_URI']);
+    if(WWW_SUB_PATH)
+    {
+        $request = preg_replace('/^'.WWW_SUB_PATH.'(.*)$/', '\\1', trim($request,"\/"));
+    }
+    list($curPath,) = explode('/', trim($request,"\/"),2);
+
+    require_once(PATH_TO_ENGINE_CLASSES.'Resolver.class.php');
+    
+    Resolver::addClassPath(PATH_TO_ENGINE_CLASSES);
+
+    if($curPath == PATH_TO_ADMIN)
+    {
+        Resolver::addClassPath(PATH_TO_ENGINE_HANDLER);
+    }
+    else
+    {
+        Resolver::addClassPath(PATH_TO_PROJECT_CLASSES);
+        Resolver::addClassPath(PATH_TO_PROJECT_HANDLER);
+    }
+
+    Resolver::addClassPath(PATH_TO_ENGINE_LIBRARY);
+
+    spl_autoload_register(array('Resolver', 'resolveName'));
+/*
+    function __autoload($class)
+    {
+        print($class);
+    }
+*/
+?>

engine/handler/.htaccess

+Order allow,deny
+Deny from all 

engine/handler/FlatPageManager.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Description of FlatPageManagerclass
+ *
+ * @author merlex
+ */
+class FlatPageManager extends Handler
+{
+    function __construct($handlerId, &$user, &$request)
+    {
+        parent::__construct($handlerId, $user, $request);
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function index($request = '')
+    {
+        $data      = array();
+        $flatpages = array();
+        $paths     = array();
+        $fPage     = new FlatPage();
+        $dbResult = $fPage->getAllPage();
+        if(is_array($dbResult)&&count($dbResult))
+        {
+            foreach($dbResult as $dkey => $dval)
+            {
+                $flatpages[$dval['path_id']][] = $dval;
+            }
+        }
+        if(is_array($flatpages)&&count($flatpages))
+        {
+            $query = 'SELECT * FROM '.DEFAULT_DB.'.core_path WHERE id IN('.implode(',', array_keys($flatpages)).')';
+            $dbResult = DB::parse($query);
+            if(is_array($dbResult)&&count($dbResult))
+            {
+                foreach($dbResult as $dkey => $dval)
+                {
+                    $paths[$dval['id']] = $dval;
+                }
+            }
+        }
+        $data['flatpages'] = $flatpages;
+        $data['paths']     = $paths;
+        $data['userName']  = $this->user->getField('login');
+        return array('template' => array('content'=>'index','left'=>'left.flatpage','footer'=>'footer','header'=>'header','menu'=>'menu'),'data'=>$data);
+    }
+    //put your code here
+}
+?>

engine/handler/FrameManager.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса FrameManagerclass
+ *
+ * @author merlex
+ */
+class FrameManager extends Handler
+{
+    function __construct($handlerId, &$user, &$request)
+    {
+        parent::__construct($handlerId, $user, $request);
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function index($request = '')
+    {
+        Debug::write($_SERVER);
+        $data = array();
+        $frames = array();
+        $query = 'SELECT * FROM '.DEFAULT_DB.'.core_frame';
+        $dbResult = DB::parse($query);
+        if(is_array($dbResult)&&count($dbResult))
+        {
+            foreach($dbResult as $dkey => $dval)
+            {
+                $frames[$dval['frame']][] = $dval['block'];
+            }
+        }
+        $block = array();
+        if ($dir_handle = @opendir(PATH_TO_PROJECT_BLOCK))
+        {
+            while($file = readdir($dir_handle))
+            {
+                //Рекурсивный проход по директориям
+                if (preg_match("/(.*)\.tpl/i",$file, $filematch))
+                {
+                    $block[] = $filematch[1];
+                }
+            }
+        }
+        $data['frames'] = $frames;
+        $data['block']  = $block;
+        $data['userName'] = $this->user->getField('login');
+        return array('template' => array('content'=>'index','left'=>'left.frame','footer'=>'footer','header'=>'header','menu'=>'menu'),'data'=>$data);
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function refresh($request = '')
+    {
+        Debug::write($_SERVER);
+        $data = array();
+        if ($dir_handle = @opendir(PATH_TO_PROJECT_FRAME))
+        {
+            while($file = readdir($dir_handle))
+            {
+                //Рекурсивный проход по директориям
+                if (preg_match("/(.*)\.tpl/i",$file, $filematch))
+                {
+                    $blockList[$filematch[1]] = CoreUtils::parseFrame(PATH_TO_PROJECT_FRAME.$file);
+                    $data['frame'] = $blockList;
+                }
+            }
+        }
+        $frames = array();
+        $frameDesc = array();
+        if(is_array($data['frame'])&&count($data['frame']))
+        foreach($data['frame'] as $fkey => $fval)
+        {
+            foreach($fval as $bkey => $bval)
+            {
+                $frames[] = array('frame' => $fkey,'block' => $bval['block']);
+                $frameDesc[$fkey][$bval['block']] = $bval['descr'];
+            }
+        }
+        $query = 'SELECT * FROM '.DEFAULT_DB.'.core_frame';
+        $dbResult = DB::parse($query);
+        $dbFrames = array();
+        if(is_array($dbResult)&&count($dbResult))
+        {
+            foreach($dbResult as $dkey => $dval)
+            {
+                $dbFrames[] = array('frame'=>$dval['frame'], 'block'=>$dval['block']);
+            }
+        }
+        $diffFrames = CoreUtils::diff_array($frames, $dbFrames);
+
+        if(is_array($diffFrames)&&count($diffFrames))
+        {
+            foreach($diffFrames as $nkey => $nval)
+            {
+                $query = 'INSERT INTO '.DEFAULT_DB.'.core_frame(`id`,`frame`,`block`,`descr`) values ( NULL,"'.$nval['frame'].'","'.$nval['block'].'","'.$frameDesc[$nval['frame']][$nval['block']].'");';
+                DB::parse($query);
+            }
+        }
+        $data['frames'] = $frames;
+        $data['dbFrames'] = $dbFrames;
+        $data['diffFrames'] = $diffFrames;
+        return array('template' => array('content'=>'index','left'=>'left.frame','footer'=>'footer','header'=>'header','menu'=>'menu'),'data'=>$data);
+    }
+    public function xhrFrame($request = '')
+    {
+        if(isset($request['pathInfo']['params'][3])&&isset($request['pathInfo']['params'][4]))
+        {
+            $data = '';
+            $query = 'SELECT * FROM '.DEFAULT_DB.'.core_frame WHERE frame = "'.
+                      $request['pathInfo']['params'][3].'" AND block = "'.
+                      $request['pathInfo']['params'][4].'"';
+            $result = DB::parse($query);
+            $data = print_r($result,true);
+        }
+        return array('template' => array('content'=>'form.frame','left'=>'clear','footer'=>'clear','header'=>'clear','frame'=>'blank','menu'=>'menu'),'data'=>array('frame'=>$result[0]),'qwedata'=>$data);
+    }
+}
+?>

engine/handler/HandlerManager.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса HandlerManager
+ *
+ * @author merlex
+ */
+class HandlerManager extends Handler
+{
+    function __construct($handlerId, &$user, &$request)
+    {
+        parent::__construct($handlerId, $user, $request);
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function index($request = '')
+    {
+        Debug::write($_SERVER);
+        $data = array();
+        $handlers = array();
+        $query = 'SELECT * FROM '.DEFAULT_DB.'.core_handler';
+        $dbResult = DB::parse($query);
+        if(is_array($dbResult)&&count($dbResult))
+        {
+            foreach($dbResult as $dkey => $dval)
+            {
+                $handlers[$dval['class']][] = $dval['method'];
+            }
+        }
+        $data['handlers'] = $handlers;
+        $data['userName'] = $this->user->getField('login');
+        return array('template' => array('content'=>'index','left'=>'left.handler','footer'=>'footer','header'=>'header','menu'=>'menu'),'data'=>$data);
+    }
+    /**
+     *
+     * @param <type> $request
+     * @return <type>
+     */
+    public function xhrHandler($request = '')
+    {
+        $data = '';
+        if(isset($request['pathInfo']['params'][3])&&isset($request['pathInfo']['params'][4]))
+        {
+            $query = 'SELECT * FROM '.DEFAULT_DB.'.core_handler WHERE class = "'.
+                      $request['pathInfo']['params'][3].'" AND method = "'.
+                      $request['pathInfo']['params'][4].'"';
+            $result = DB::parse($query);
+            $data = print_r($result,true);
+        }
+        return array('template' => array('content'=>'form.handler','left'=>'clear','footer'=>'clear','header'=>'clear','frame'=>'blank','menu'=>'menu'),'data'=>array('handler'=>$result[0]),'qwedata'=>$data);
+    }
+    /**
+     *
+     * @param <type> $request
+     * @return <type> 
+     */
+    public function xhrSaveHandler($request = '')
+    {
+        $data = '';
+        $class = DB::escape($_POST['class']);
+        $method = DB::escape($_POST['method']);
+        $desc = DB::escape($_POST['desc']);
+        $params = array();
+        $isSave = false;
+        if(is_array($_POST['paramName'])&&count($_POST['paramName']))
+        foreach ($_POST['paramName'] as $pnkey => $pnval)
+        {
+            $params[] = array('name'=>DB::escape($pnval),
+                              'from'=>DB::escape($_POST['paramFrom'][$pnkey]),
+                              'to'=>DB::escape($_POST['paramTo'][$pnkey])
+                             );
+        }
+        if($class&&$method)
+        {
+            $query = 'SELECT * FROM '.DEFAULT_DB.'.core_handler WHERE '.
+                     'class = "'.$class.'" AND method = "'.$method.'"';
+            $result = DB::parse($query);
+            if($result[0])
+            {
+                $query = 'UPDATE '.DEFAULT_DB.'.core_handler SET '.
+                         ' `descr` = "'.$desc.'", param = "'.DB::escape(trim(serialize($params))).'" WHERE id='.$result[0]['id'];
+                DB::parse($query);
+                $isSave = true;
+            }
+        }
+        $message = ($isSave)?('Данные сохранены'):('Ошибка');
+        return array('template' => array('content'=>'blank','left'=>'clear','footer'=>'clear','header'=>'clear','frame'=>'blank','menu'=>'menu'),'data'=>$message);
+    }
+    /**
+     *
+     * @return <type>
+     */
+    public function refresh($request = '')
+    {
+        Debug::write($_SERVER);
+        $data = array();
+        $data['handlerpath'] = PATH_TO_PROJECT_HANDLER;
+        if ($dir_handle = @opendir(PATH_TO_PROJECT_HANDLER))
+        {
+            while($file = readdir($dir_handle))
+            {
+                //Рекурсивный проход по директориям
+                if (preg_match("/(.*)\.class\.php/i",$file, $filemath))
+                {
+                    $data['handler'][] = $filemath[1];
+                }
+            }
+        }
+        $handlers = array();
+        foreach ($data['handler'] as $hkey => $hval)
+        {
+            $functionList = CoreUtils::findFunctions(PATH_TO_PROJECT_HANDLER.$hval.'.class.php');
+            foreach ($functionList['class'][$hval]['function'] as $mkey => $mval)
+            {
+                if($mval['name'] != '__construct'&&$mval['name'] != '__destructor'&&$mval['public'])
+                {
+                    $handlers[] = array('class'=>$hval, 'method'=>$mval['name']);
+                }
+            }
+        }
+        $query = 'SELECT * FROM '.DEFAULT_DB.'.core_handler';
+        $dbResult = DB::parse($query);
+        $dbHandlers = array();
+        if(is_array($dbResult)&&count($dbResult))
+        {
+            foreach($dbResult as $dkey => $dval)
+            {
+                $dbHandlers[] = array('class'=>$dval['class'], 'method'=>$dval['method']);
+            }
+        }
+        $diffHandlers = CoreUtils::diff_array($handlers, $dbHandlers);
+        if(is_array($diffHandlers)&&count($diffHandlers))
+        {
+            foreach($diffHandlers as $nkey => $nval)
+            {
+                $query = 'INSERT INTO '.DEFAULT_DB.'.core_handler(`id`,`class`,`method`) values ( NULL,"'.$nval['class'].'","'.$nval['method'].'");';
+                DB::parse($query);
+            }
+        }
+        $data['handlers'] = $handlers;
+        $data['dbHandlers'] = $dbHandlers;
+        $data['diffHandlers'] = $diffHandlers;
+        return array('template' => array('content'=>'index','left'=>'left.handler','footer'=>'footer','header'=>'header','menu'=>'menu'),'data'=>$data);
+    }
+}
+?>

engine/handler/Index.class.php

+<?php
+defined('ACCESS') or die('Direct Access to this location is not allowed.');
+/**
+ * Краткое описание класса Indexclass
+ *