Browse Source
Code refactoring, #16
Code refactoring, #16
git-svn-id: svn+ssh://code.netmonsters.ru/svn/majestic/branches/evo@114 4cb57b5f-5bbd-dd11-951b-001d605cbbc5master
pzinovkin
15 years ago
26 changed files with 688 additions and 1310 deletions
-
6Config.php
-
37Load.php
-
51app/Action.php
-
127app/FrontController.php
-
25app/StaticViewAction.php
-
41app/ViewAction.php
-
72app/router/Route.php
-
65app/router/Router.php
-
109classes/Action.class.php
-
159classes/DBConnector.class.php
-
62classes/Decorator.class.php
-
16classes/DynamicPageException.class.php
-
56classes/Env.class.php
-
45classes/Load.class.php
-
262classes/Model.class.php
-
60classes/PageController.class.php
-
131classes/Router.class.php
-
18classes/StaticPageException.class.php
-
175classes/Sublimer.class.php
-
110classes/pg_DBConnector.class.php
-
28init/init.inc.php
-
100init/sys.inc.php
-
53layout/Layout.php
-
94util/AutoloadBuilder.php
-
72view/PHPView.php
-
16view/iView.php
@ -0,0 +1,37 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage Load |
||||
|
* @since 2010-02-24 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
class Load |
||||
|
{ |
||||
|
|
||||
|
static protected $autoload; |
||||
|
|
||||
|
static public function autoload($class) |
||||
|
{ |
||||
|
if (! isset(self::$autoload[$class])) { |
||||
|
throw new MJException('There is no such class "' . $class . '" in autoload.'); |
||||
|
} |
||||
|
require(PATH . self::$autoload[$class]); |
||||
|
} |
||||
|
|
||||
|
static public function setAutoloadFrom($file) |
||||
|
{ |
||||
|
if (! file_exists($file)) { |
||||
|
throw new MJException('Autoload source doesn\'t exists! Try to generate it!'); |
||||
|
} |
||||
|
self::$autoload = require($file); |
||||
|
} |
||||
|
|
||||
|
static public function getFilePath($class) |
||||
|
{ |
||||
|
return self::$autoload[$class]; |
||||
|
} |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage app |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
abstract class Action |
||||
|
{ |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
$this->extractParams(); |
||||
|
$this->execute(); |
||||
|
} |
||||
|
|
||||
|
protected function extractParams() |
||||
|
{ |
||||
|
$params = FrontController::getInstance()->getRouter()->getRoute()->getParams(); |
||||
|
if ($params) { |
||||
|
foreach ($params as $name => $value) { |
||||
|
if (is_string($name)) { |
||||
|
$this->$name = $value; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
abstract protected function execute(); |
||||
|
|
||||
|
/** |
||||
|
* Redirect |
||||
|
* |
||||
|
* @param mixed $url |
||||
|
* @param mixed $relative Default to true |
||||
|
*/ |
||||
|
protected function redirect($url = null, $relative = true) |
||||
|
{ |
||||
|
$url = ($url) ? $url : Env::getRequestUri(); |
||||
|
|
||||
|
if ($relative) { |
||||
|
$url = FrontController::getInstance()->getBaseUrl() . $url; |
||||
|
} |
||||
|
header('Location: ' . $url); |
||||
|
exit(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,127 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage app |
||||
|
* @since 2010-02-24 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
class FrontController |
||||
|
{ |
||||
|
/** |
||||
|
* @var Router |
||||
|
*/ |
||||
|
protected $router; |
||||
|
|
||||
|
/** |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $view = 'PHPView'; |
||||
|
|
||||
|
/** |
||||
|
* @var string |
||||
|
*/ |
||||
|
protected $view_path; |
||||
|
|
||||
|
protected $base_url = ''; |
||||
|
|
||||
|
/** |
||||
|
* @var FrontController |
||||
|
*/ |
||||
|
protected static $instance; |
||||
|
|
||||
|
|
||||
|
private function __construct() |
||||
|
{ |
||||
|
$this->router = new Router(); |
||||
|
} |
||||
|
|
||||
|
private function __clone(){} |
||||
|
|
||||
|
/** |
||||
|
* @return FrontController |
||||
|
*/ |
||||
|
static public function getInstance() |
||||
|
{ |
||||
|
if (! isset(self::$instance)) { |
||||
|
self::$instance = new self(); |
||||
|
} |
||||
|
return self::$instance; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $path |
||||
|
* @return FrontController |
||||
|
*/ |
||||
|
public function setViewPath($path) |
||||
|
{ |
||||
|
$this->view_path = $path; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $view |
||||
|
* @return FrontController |
||||
|
*/ |
||||
|
public function setView($view) |
||||
|
{ |
||||
|
$this->view = $view; |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* |
||||
|
* @return iView |
||||
|
*/ |
||||
|
public function getView($view = null) |
||||
|
{ |
||||
|
$view = ($view) ? $view : $this->view; |
||||
|
return new $view($this->view_path); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $url |
||||
|
*/ |
||||
|
public function setBaseUrl($url) |
||||
|
{ |
||||
|
$this->base_url = rtrim($url, '/'); |
||||
|
return $this; |
||||
|
} |
||||
|
|
||||
|
public function getBaseUrl() |
||||
|
{ |
||||
|
return $this->base_url; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Router |
||||
|
*/ |
||||
|
public function getRouter() |
||||
|
{ |
||||
|
return $this->router; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public function execute() |
||||
|
{ |
||||
|
|
||||
|
try { |
||||
|
$request = Env::getRequestUri(); |
||||
|
$route = $this->getRouter()->route($request); |
||||
|
if (! $route) { |
||||
|
throw new Exception('Route "' . $request . '" not found'); |
||||
|
} |
||||
|
|
||||
|
$action_class = $route->getAction(); |
||||
|
$action = new $action_class(); |
||||
|
$layout_class = $route->getLayout(); |
||||
|
$layout = new $layout_class(); |
||||
|
return $layout->fetch($action); |
||||
|
} catch (Exception $e) { |
||||
|
throw $e; |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage app |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
abstract class StaticViewAction extends ViewAction |
||||
|
{ |
||||
|
|
||||
|
protected function getTemplate() |
||||
|
{ |
||||
|
$template = ($this->template) ? $this->template : substr(get_class($this), 0, -6/*strlen('Action')*/); |
||||
|
return '/static/' . $template; |
||||
|
} |
||||
|
|
||||
|
public function fetch() |
||||
|
{ |
||||
|
return $this->view->fetch($this->getTemplate()); |
||||
|
} |
||||
|
} |
@ -0,0 +1,41 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage app |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
abstract class ViewAction extends Action |
||||
|
{ |
||||
|
|
||||
|
protected $template; |
||||
|
|
||||
|
/** |
||||
|
* @var PHPView |
||||
|
*/ |
||||
|
protected $view; |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
$this->view = FrontController::getInstance()->getView(); |
||||
|
parent::__construct(); |
||||
|
} |
||||
|
|
||||
|
protected function getTemplate() |
||||
|
{ |
||||
|
$class = get_class($this); |
||||
|
$template = ($this->template) ? $this->template : substr($class, 0, -6/*strlen('Action')*/); |
||||
|
$dir = array_slice(explode('/', Load::getFilePath($class)), -2, 1); |
||||
|
return '/actions/' . array_pop($dir) . '/' . $template; |
||||
|
} |
||||
|
|
||||
|
public function fetch() |
||||
|
{ |
||||
|
$this->view->assignObject($this); |
||||
|
return $this->view->fetch($this->getTemplate()); |
||||
|
} |
||||
|
} |
@ -0,0 +1,72 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage app |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
class Route |
||||
|
{ |
||||
|
|
||||
|
protected $route; |
||||
|
protected $action; |
||||
|
protected $params; |
||||
|
protected $layout; |
||||
|
|
||||
|
public function __construct($route, $action, $params = null, $layout = null) |
||||
|
{ |
||||
|
$this->route = $route; |
||||
|
$this->action = $action; |
||||
|
$this->params = $params; |
||||
|
$this->layout = $layout; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param array $request |
||||
|
*/ |
||||
|
public function match($request) |
||||
|
{ |
||||
|
$parts = explode('/', $this->route); |
||||
|
$cnt = count($parts); |
||||
|
|
||||
|
if(count($request) != $cnt) { |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
for ($i = 0; $i < $cnt; $i++) { |
||||
|
if (substr($parts[$i], 0, 1) == ':') { |
||||
|
$this->params[substr($parts[$i], 1)] = $request[$i]; |
||||
|
} elseif (substr($parts[$i], 0, 2) == '(?') { |
||||
|
$match = array(); |
||||
|
if (!preg_match('#^' . $parts[$i] . '$#iu', $request[$i], $match)) { |
||||
|
return false; |
||||
|
} |
||||
|
$start = strpos($parts[$i], '<') + 1; |
||||
|
$key = substr($parts[$i], $start, strpos($parts[$i], '>', $start) - $start); |
||||
|
$this->params[$key] = $match[$key]; |
||||
|
} elseif ($parts[$i] != $request[$i]) { |
||||
|
return false; |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
public function getAction() |
||||
|
{ |
||||
|
return $this->action . 'Action'; |
||||
|
} |
||||
|
|
||||
|
public function getLayout() |
||||
|
{ |
||||
|
return $this->layout . 'Layout'; |
||||
|
} |
||||
|
|
||||
|
public function getParams() |
||||
|
{ |
||||
|
return $this->params; |
||||
|
} |
||||
|
} |
@ -0,0 +1,65 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage app |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
class Router |
||||
|
{ |
||||
|
|
||||
|
protected $routes = array(); |
||||
|
|
||||
|
protected $route_name; |
||||
|
|
||||
|
protected $default_layout = 'Default'; |
||||
|
|
||||
|
/** |
||||
|
* @var Route |
||||
|
*/ |
||||
|
protected $route; |
||||
|
|
||||
|
public function add($name, $route, $action, $params = null, $layout = null) |
||||
|
{ |
||||
|
if (! $layout) { |
||||
|
$layout = $this->default_layout; |
||||
|
} |
||||
|
$this->routes[$name] = new Route($route, $action, $params, $layout); |
||||
|
} |
||||
|
|
||||
|
public function route($request) |
||||
|
{ |
||||
|
$req = explode('/', trim($request, '/')); |
||||
|
|
||||
|
foreach ($this->routes as $name => $route) { |
||||
|
if ($route->match($req)) { |
||||
|
$this->route_name = $route; |
||||
|
$this->route = $route; |
||||
|
return $this->route; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public function setDefaultLayout($layout = 'Default') |
||||
|
{ |
||||
|
$this->default_layout = $layout; |
||||
|
} |
||||
|
|
||||
|
public function getRouteName() |
||||
|
{ |
||||
|
return $this->route_name; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @return Route |
||||
|
*/ |
||||
|
public function getRoute() |
||||
|
{ |
||||
|
return $this->route; |
||||
|
} |
||||
|
} |
@ -1,109 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Рутовый класс для любого действия. |
|
||||
* Описывает основной функционал для работы с классами действий. |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Action |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
abstract class Action |
|
||||
{ |
|
||||
public $template; //шаблон действия
|
|
||||
public $template_dir = '.'; //путь к шаблону действия
|
|
||||
public $class; //имя дочернего класса
|
|
||||
|
|
||||
protected $templater; //шаблонизатор
|
|
||||
|
|
||||
public function __construct() |
|
||||
{ |
|
||||
$this->class = get_class($this); |
|
||||
$this->template = substr($this->class, 0, -strlen(ACTION_POSTFIX)); |
|
||||
|
|
||||
if (CACHE_ENABLE && ($cache_name = $this->getCacheKey()) !== false) { |
|
||||
$cache = new Cache($this->class.'_'.$cache_name, $this->getCacheTime()); |
|
||||
if ($cache->isCached()) { |
|
||||
$this->restore($cache->load()); |
|
||||
} else { |
|
||||
$this->init(); |
|
||||
$cache->save($this->store()); |
|
||||
} |
|
||||
} else { |
|
||||
$this->init(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Выдает результат действия. |
|
||||
* |
|
||||
* @return string |
|
||||
*/ |
|
||||
public function display() |
|
||||
{ |
|
||||
$this->templater = Load::templater(); |
|
||||
$this->prepare(); |
|
||||
$this->templater->setPath(ACTION_TPL_PATH.'/'.$this->template_dir); |
|
||||
return $this->templater->fetch($this->template.'.tpl'); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Инициализация данных действия. |
|
||||
* Тут должна быть ВСЯ работа с установкой данных, |
|
||||
* дабы потом они нормально закешировались. |
|
||||
* Этот метод НЕ исполняется при срабатывании кеша. |
|
||||
* |
|
||||
*/ |
|
||||
abstract protected function init(); |
|
||||
|
|
||||
/** |
|
||||
* Подготовка данных для шаблона. |
|
||||
* Этот метод выполняется ВСЕГДА |
|
||||
*/ |
|
||||
protected function prepare() {} |
|
||||
|
|
||||
/** |
|
||||
* Возвращает имя файла для кеширования |
|
||||
* Переопределяется в доченрих классах. |
|
||||
* |
|
||||
* @return false/string - имя файла кеша либо false если кеш запрещен |
|
||||
*/ |
|
||||
protected function getCacheKey() |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Возвращает время жизни кеша в секундах |
|
||||
* При отрицательном значении кеш вечен. |
|
||||
* Переопределяется в доченрих классах. |
|
||||
* |
|
||||
* @return false/integer - время жизни кеша либо false если кеш запрещен |
|
||||
*/ |
|
||||
protected function getCacheTime() |
|
||||
{ |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Выдает строку для кеширования. |
|
||||
*/ |
|
||||
protected function store() |
|
||||
{ |
|
||||
return serialize(get_object_vars($this)); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Разбирает строку кеша, созданную методом store |
|
||||
*/ |
|
||||
protected function restore($data) |
|
||||
{ |
|
||||
foreach(unserialize($data) as $key => $val) { |
|
||||
$this->$key = $val; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,159 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Класс базы данных. |
|
||||
* Возвращает идентификатор соединения |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage DB |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
class DBConnector |
|
||||
{ |
|
||||
|
|
||||
/** |
|
||||
* PDO constant values. |
|
||||
*/ |
|
||||
const FETCH_ASSOC = 2; |
|
||||
const FETCH_BOTH = 4; |
|
||||
const FETCH_NUM = 3; |
|
||||
const FETCH_OBJ = 5; |
|
||||
|
|
||||
static private $handlers = array(); |
|
||||
static public $queries = array(); |
|
||||
|
|
||||
/** |
|
||||
* Запрещаем new и клонирование |
|
||||
*/ |
|
||||
private function __construct(){} |
|
||||
|
|
||||
private function __clone(){} |
|
||||
|
|
||||
/** |
|
||||
* Получение соединения. |
|
||||
* Если соединение с такими параметрами уже есть - новое не создается. |
|
||||
* |
|
||||
* @param array $db_settings - массив настроек |
|
||||
* @return resource - идентификатор соединения |
|
||||
*/ |
|
||||
static public function getConnect($db_settings) |
|
||||
{ |
|
||||
$handler_name = self::getConnectionName($db_settings); |
|
||||
|
|
||||
if (isset(self::$handlers[$handler_name])) { |
|
||||
return self::$handlers[$handler_name]; |
|
||||
} |
|
||||
|
|
||||
if (!$handler = mysqli_connect($db_settings['host'], $db_settings['user'], $db_settings['password'], $db_settings['database'])) { |
|
||||
throw new MJException('Can\'t connect to DB '.mysqli_connect_error(), 2); |
|
||||
} |
|
||||
|
|
||||
self::query($handler, "SET NAMES 'utf8'"); //cheat!!!
|
|
||||
return self::$handlers[$handler_name] = $handler; |
|
||||
} |
|
||||
|
|
||||
static protected function getConnectionName($db_settings) |
|
||||
{ |
|
||||
return $db_settings['host'] . '-' . $db_settings['database']; |
|
||||
} |
|
||||
|
|
||||
/////////
|
|
||||
|
|
||||
static public function query($handler, $sql) |
|
||||
{ |
|
||||
return mysqli_query($handler, $sql); |
|
||||
} |
|
||||
|
|
||||
static public function escape($handler, $str) |
|
||||
{ |
|
||||
return mysqli_real_escape_string($handler, $str); |
|
||||
} |
|
||||
|
|
||||
static public function error($handler) |
|
||||
{ |
|
||||
return mysqli_error($handler); |
|
||||
} |
|
||||
|
|
||||
static public function free($result) |
|
||||
{ |
|
||||
return mysqli_free_result($result); |
|
||||
} |
|
||||
|
|
||||
static public function fetchObject($result, $class_name = false) |
|
||||
{ |
|
||||
return $class_name ? mysqli_fetch_object($result, $class_name) : mysqli_fetch_object($result); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Fetches a row from the result set. |
|
||||
* |
|
||||
* @param mysqli_result $result |
|
||||
* @param int $style OPTIONAL Fetch mode for this fetch operation. |
|
||||
* @return mixed Array, object, or scalar depending on fetch mode. |
|
||||
* @throws Exception |
|
||||
*/ |
|
||||
static public function fetchArray($result, $style = null) |
|
||||
{ |
|
||||
if (!$result) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if ($style === null) { |
|
||||
$style = self::FETCH_ASSOC; |
|
||||
} |
|
||||
|
|
||||
$row = false; |
|
||||
switch ($style) { |
|
||||
case self::FETCH_NUM: |
|
||||
$row = mysqli_fetch_array($result, MYSQLI_NUM); |
|
||||
break; |
|
||||
case self::FETCH_ASSOC: |
|
||||
$row = mysqli_fetch_array($result, MYSQLI_ASSOC); |
|
||||
break; |
|
||||
case self::FETCH_BOTH: |
|
||||
$row = mysqli_fetch_array($result, MYSQLI_BOTH); |
|
||||
break; |
|
||||
case self::FETCH_OBJ: |
|
||||
$row = mysqli_fetch_object($result, MYSQLI_BOTH); |
|
||||
break; |
|
||||
default: |
|
||||
throw new Exception('Invalid fetch mode "' . $style . '" specified'); |
|
||||
break; |
|
||||
} |
|
||||
return $row; |
|
||||
} |
|
||||
|
|
||||
static public function numRows($result) |
|
||||
{ |
|
||||
return mysqli_num_rows($result); |
|
||||
} |
|
||||
|
|
||||
static public function affectedRows($handler, $result) |
|
||||
{ |
|
||||
return mysqli_affected_rows($handler); |
|
||||
} |
|
||||
|
|
||||
static public function getId($handler) |
|
||||
{ |
|
||||
return mysqli_insert_id($handler); |
|
||||
} |
|
||||
|
|
||||
static public function autocommit($handler, $switch) |
|
||||
{ |
|
||||
return mysqli_autocommit($handler, (bool) $switch); |
|
||||
} |
|
||||
|
|
||||
static public function commit($handler) |
|
||||
{ |
|
||||
return mysqli_commit($handler); |
|
||||
} |
|
||||
|
|
||||
static public function rollback($handler) |
|
||||
{ |
|
||||
return mysqli_rollback($handler); |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,62 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Родительский класс для всех декораторов. Содержит основной функционал. |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Decorator |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
abstract class Decorator |
|
||||
{ |
|
||||
protected $layout = false; |
|
||||
protected $action = false; |
|
||||
protected $action_name = 'Action'; |
|
||||
|
|
||||
protected $templater = false; |
|
||||
|
|
||||
function __construct() |
|
||||
{ |
|
||||
if (!$this->layout) { |
|
||||
throw new MJException('$layout not set in '.get_class($this)); |
|
||||
} |
|
||||
$this->templater = Load::templater(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Основной метод вывода |
|
||||
* |
|
||||
*/ |
|
||||
function display(Action $action) |
|
||||
{ |
|
||||
$this->action = $action; |
|
||||
$this->templater->assign($this->action_name, $this->action->display(), $this->layout); |
|
||||
|
|
||||
$this->exec(); |
|
||||
|
|
||||
$this->templater->setPath(WRAPPERS_TPL_PATH); |
|
||||
return $this->templater->fetch($this->layout); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Добавить данные на вывод |
|
||||
* |
|
||||
* @param string $var_name - имя переменной, в которую будет осуществлен вывод |
|
||||
* @param Action $action - действие |
|
||||
* @param Decorator $decorator - декоратор, в котором должно выполнится действие. |
|
||||
*/ |
|
||||
function addOutput($var_name, Action $action, Decorator $decorator = null) |
|
||||
{ |
|
||||
$this->templater->assign($var_name, $decorator ? $decorator->display($action) : $action->display(), $this->layout); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Основной метод для дочерних декораторов |
|
||||
* |
|
||||
*/ |
|
||||
abstract function exec(); |
|
||||
} |
|
||||
?>
|
|
@ -1,16 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
/** |
|
||||
* Эксепшен для выводя результата работы класса |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Core |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
class DynamicPageException extends Exception |
|
||||
{} |
|
||||
?>
|
|
@ -1,45 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Load |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
class Load |
|
||||
{ |
|
||||
static $models = array(); |
|
||||
static $templater = false; |
|
||||
static $router = false; |
|
||||
|
|
||||
static function model($model_name) |
|
||||
{ |
|
||||
if (isset(self::$models[$model_name])) { |
|
||||
return self::$models[$model_name]; |
|
||||
} |
|
||||
|
|
||||
$class_name = $model_name.MODEL_POSTFIX; |
|
||||
return self::$models[$model_name] = new $class_name; |
|
||||
} |
|
||||
|
|
||||
static function templater($path = '') |
|
||||
{ |
|
||||
if (self::$templater) { |
|
||||
if ($path) { |
|
||||
self::$templater->setPath($path); |
|
||||
} |
|
||||
return self::$templater; |
|
||||
} |
|
||||
return self::$templater = new Sublimer($path); |
|
||||
} |
|
||||
|
|
||||
static function router() |
|
||||
{ |
|
||||
return self::$router ? self::$router : self::$router = new Router; |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,262 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Класс модели данных |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage DB |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
abstract class Model |
|
||||
{ |
|
||||
private $handler; |
|
||||
|
|
||||
protected $table = false; |
|
||||
protected $primary_key = 'id'; |
|
||||
|
|
||||
function __construct() |
|
||||
{ |
|
||||
$this->handler = DBConnector::getConnect(Env::getParam('db_settings')); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Выполняет запрос и возвращает сырой результат |
|
||||
* |
|
||||
* @param string $sql |
|
||||
* @return resource |
|
||||
*/ |
|
||||
function exec($sql) |
|
||||
{ |
|
||||
if (DEBUG_ENABLE) { |
|
||||
$time = microtime(true); |
|
||||
} |
|
||||
$res = DBConnector::query($this->handler, $sql); |
|
||||
if ($error = DBConnector::error($this->handler)) { |
|
||||
throw new MJException("<b>Query Error:</b>\n".$sql."\n<b>Error:</b>\n".$error, 1); |
|
||||
} |
|
||||
|
|
||||
if (DEBUG_ENABLE) { |
|
||||
DBConnector::$queries[] = $sql.'; ('.round((microtime(true)-$time)*1000, 1).'ms)'; |
|
||||
} |
|
||||
|
|
||||
return $res; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Выполняет запрос и возвращает объект результата |
|
||||
* |
|
||||
* @param string $sql |
|
||||
* @return object |
|
||||
*/ |
|
||||
function query($sql) |
|
||||
{ |
|
||||
$res = $this->exec($sql); |
|
||||
|
|
||||
switch (strtolower(substr($sql, 0, 6))) { |
|
||||
case 'select': |
|
||||
case '(selec': |
|
||||
return new ModelSelectResult($res); |
|
||||
case 'insert': |
|
||||
case 'replac': |
|
||||
return new ModelInsertResult($this->handler, $res); //$res for postgreSQL
|
|
||||
default: |
|
||||
return new ModelChangeResult($this->handler, $res); //$res for postgreSQL
|
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Экранирует строку |
|
||||
* |
|
||||
* @param mixed $data - строка для экранирования |
|
||||
* @return mixed |
|
||||
*/ |
|
||||
function escape($data) |
|
||||
{ |
|
||||
if(is_array($data)){ |
|
||||
foreach($data as $id => $val){ |
|
||||
$data[$id] = DBConnector::escape($this->handler, $val); |
|
||||
} |
|
||||
return $data; |
|
||||
} |
|
||||
return DBConnector::escape($this->handler, $data); |
|
||||
} |
|
||||
|
|
||||
//////////////////////////
|
|
||||
function update($id, $data) |
|
||||
{ |
|
||||
$sql = ''; |
|
||||
foreach ($data as $key => $val) { |
|
||||
$sql .= $key."='".$this->escape($val)."', "; |
|
||||
} |
|
||||
return $this->query('UPDATE '.$this->table.' SET '.rtrim($sql, ', ').' WHERE '.$this->primary_key.'='.(int) $id); |
|
||||
} |
|
||||
|
|
||||
function insert($data, $postfix = '') |
|
||||
{ |
|
||||
$keys = array(); |
|
||||
$values = array(); |
|
||||
|
|
||||
foreach ($data as $key => $val) { |
|
||||
$keys[] = $key; |
|
||||
$values[] = $this->escape($val); |
|
||||
} |
|
||||
return $this->query('INSERT INTO '.$this->table.' ('.implode(',', $keys).") VALUES('".implode("','", $values)."') ".$postfix); |
|
||||
} |
|
||||
|
|
||||
function delete($id) |
|
||||
{ |
|
||||
return $this->query('DELETE FROM '.$this->table.' WHERE '.$this->primary_key.'='.(int) $id); |
|
||||
} |
|
||||
|
|
||||
function get($id) |
|
||||
{ |
|
||||
return $this->query('SELECT * FROM '.$this->table.' WHERE '.$this->primary_key.'='.(int) $id); |
|
||||
} |
|
||||
|
|
||||
function getList($limit = false, $sort = 'ASC') |
|
||||
{ |
|
||||
return $this->query('SELECT * |
|
||||
FROM '.$this->table.' |
|
||||
ORDER BY '.$this->primary_key.' '.($sort == 'ASC' ? 'ASC' : 'DESC') |
|
||||
.($limit !== false ? ' LIMIT '.(int) $limit : ''))->fetchAll(); |
|
||||
} |
|
||||
|
|
||||
function setAutocommit($set) |
|
||||
{ |
|
||||
return DBConnector::autocommit($this->handler, (bool) $set); |
|
||||
} |
|
||||
|
|
||||
function commit() |
|
||||
{ |
|
||||
return DBConnector::commit($this->handler); |
|
||||
} |
|
||||
|
|
||||
function rollback() |
|
||||
{ |
|
||||
return DBConnector::rollback($this->handler); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Возвращает значение поля $table |
|
||||
* @return string |
|
||||
*/ |
|
||||
function getTableName() |
|
||||
{ |
|
||||
return $this->table; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class ModelResult |
|
||||
{ |
|
||||
function __call($name, $args) |
|
||||
{ |
|
||||
throw new MJException('Call undeclared method "'.$name.'" in "'.get_class($this).'" class', -1); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class ModelSelectResult extends ModelResult |
|
||||
{ |
|
||||
public $result; |
|
||||
|
|
||||
function __construct($res) |
|
||||
{ |
|
||||
$this->result = $res; |
|
||||
} |
|
||||
|
|
||||
function fetch($class_name = false) |
|
||||
{ |
|
||||
return DBConnector::fetchObject($this->result, $class_name); |
|
||||
} |
|
||||
|
|
||||
function fetchField($field, $default = false) |
|
||||
{ |
|
||||
$row = $this->fetch(); |
|
||||
return isset($row->$field) ? $row->$field : $default; |
|
||||
} |
|
||||
|
|
||||
function fetchAll($key = false) |
|
||||
{ |
|
||||
$array = array(); |
|
||||
if ($key) { |
|
||||
while ($row = DBConnector::fetchObject($this->result)) { |
|
||||
$array[$row->$key] = $row; |
|
||||
} |
|
||||
} else { |
|
||||
while ($row = DBConnector::fetchObject($this->result)) { |
|
||||
$array[] = $row; |
|
||||
} |
|
||||
} |
|
||||
return $array; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Fetches all SQL result rows as an array of key-value pairs. |
|
||||
* |
|
||||
* The first column is the key, the second column is the |
|
||||
* value. |
|
||||
* |
|
||||
* @return array |
|
||||
*/ |
|
||||
public function fetchPairs() |
|
||||
{ |
|
||||
if (!method_exists('DBConnector', 'fetchArray')) { |
|
||||
throw new Exception('Method not implemented yet.'); |
|
||||
} |
|
||||
|
|
||||
$data = array(); |
|
||||
while ($row = DBConnector::fetchArray($this->result, DBConnector::FETCH_NUM)) { |
|
||||
$data[$row[0]] = $row[1]; |
|
||||
} |
|
||||
return $data; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
function count() |
|
||||
{ |
|
||||
return DBConnector::numRows($this->result); |
|
||||
} |
|
||||
|
|
||||
function free() |
|
||||
{ |
|
||||
DBConnector::free($this->result); |
|
||||
} |
|
||||
|
|
||||
function __destruct() { |
|
||||
$this->free(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class ModelChangeResult extends ModelResult |
|
||||
{ |
|
||||
public $affected; |
|
||||
|
|
||||
function __construct($resource, $result) |
|
||||
{ |
|
||||
$this->affected = DBConnector::affectedRows($resource, $result); |
|
||||
} |
|
||||
|
|
||||
function count() |
|
||||
{ |
|
||||
return $this->affected; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
class ModelInsertResult extends ModelChangeResult |
|
||||
{ |
|
||||
public $id; |
|
||||
|
|
||||
function __construct($resource, $result) |
|
||||
{ |
|
||||
parent::__construct($resource, $result); |
|
||||
$this->id = DBConnector::getId($resource); |
|
||||
} |
|
||||
|
|
||||
function getId() |
|
||||
{ |
|
||||
return $this->id; |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,60 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage PageController |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
class PageController |
|
||||
{ |
|
||||
|
|
||||
/** |
|
||||
* Действия на инициализацию. |
|
||||
* |
|
||||
*/ |
|
||||
protected function init() {} |
|
||||
|
|
||||
/** |
|
||||
* Действия после разбора роута. |
|
||||
* |
|
||||
*/ |
|
||||
protected function onDispatch() {} |
|
||||
|
|
||||
/** |
|
||||
* Вывод в браузер всего сайта. |
|
||||
* |
|
||||
*/ |
|
||||
public function display() |
|
||||
{ |
|
||||
try { |
|
||||
$this->init(); |
|
||||
try{ |
|
||||
$this->route = Load::router()->proccess(MJ_PATH); |
|
||||
$this->onDispatch(); |
|
||||
$action = new $this->route->action; |
|
||||
$decorator = new $this->route->decorator; |
|
||||
return $decorator->display($action); |
|
||||
} catch (MJException $e) { |
|
||||
return $e->terminate(); |
|
||||
} |
|
||||
} catch (DynamicPageException $e) { |
|
||||
$decorator_name = DEFAULT_DECORATOR; |
|
||||
$decorator = new $decorator_name; |
|
||||
$action_name = $e->getMessage(); |
|
||||
return $decorator->display(new $action_name); |
|
||||
} catch (StaticPageException $e) { |
|
||||
$decorator_name = DEFAULT_DECORATOR; |
|
||||
$decorator = new $decorator_name; |
|
||||
$action_name = DEFAULT_ACTION; |
|
||||
return $decorator->display(new $action_name($e->getMessage())); |
|
||||
} catch (Exception $e) { |
|
||||
return $e->getMessage(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,131 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Класс для работы с роутерами |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Core |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
|
|
||||
final class Router |
|
||||
{ |
|
||||
|
|
||||
protected $routes = array(); |
|
||||
|
|
||||
static protected $rewrite_base = ''; |
|
||||
static protected $decorator = DEFAULT_DECORATOR; |
|
||||
static protected $route_name = ''; |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Добавить роутер |
|
||||
* |
|
||||
* @param string $name - имя роутера |
|
||||
* @param string $path - путь |
|
||||
* @param string $action - имя действия |
|
||||
* @param array $params - массив параметров |
|
||||
*/ |
|
||||
function add($name, $path, $action, $params = array()) |
|
||||
{ |
|
||||
$this->routes[$name] = new Route($path, $action, $params); |
|
||||
$this->routes[$name]->decorator = self::$decorator; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Установить декоратор для роута (действия), отличный от стандартного |
|
||||
* |
|
||||
* @param string $name - имя роута (действия) |
|
||||
* @param string $decorator - имя декоратора |
|
||||
*/ |
|
||||
function setDecorator($name, $decorator) |
|
||||
{ |
|
||||
if (isset($this->routes[$name])) { |
|
||||
$this->routes[$name]->decorator = $decorator.DECORATOR_POSTFIX; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Найти роутер соответствующий заданному пути |
|
||||
* |
|
||||
* @param stirng $path - путь |
|
||||
* @return Route - роутер |
|
||||
*/ |
|
||||
function proccess($path) |
|
||||
{ |
|
||||
$path = explode('/', $path); |
|
||||
|
|
||||
foreach($this->routes as $name => $route) { |
|
||||
if ($route->match($path)) { |
|
||||
$route->action .= ACTION_POSTFIX; |
|
||||
Env::setParams($route->params); |
|
||||
self::$route_name = $name; |
|
||||
return $route; |
|
||||
} |
|
||||
} |
|
||||
throw new StaticPageException(E_404); |
|
||||
} |
|
||||
|
|
||||
static public function setDefaultDecorator($decorator) |
|
||||
{ |
|
||||
self::$decorator = $decorator.DECORATOR_POSTFIX; |
|
||||
} |
|
||||
|
|
||||
static public function getRouteName() |
|
||||
{ |
|
||||
return self::$route_name; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Роутер |
|
||||
* |
|
||||
*/ |
|
||||
final class Route |
|
||||
{ |
|
||||
const URL_VARIABLE = '&'; |
|
||||
|
|
||||
protected $path; |
|
||||
|
|
||||
public $decorator = DEFAULT_DECORATOR; |
|
||||
public $action; |
|
||||
public $params; |
|
||||
|
|
||||
function __construct($path, $action, $params=array()) |
|
||||
{ |
|
||||
$this->path = $path; |
|
||||
$this->action = $action; |
|
||||
$this->params = $params; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Проверяет соответствие роутера и пути |
|
||||
* |
|
||||
* @param string $path - путь для сравнения |
|
||||
* @return boolean - соответствует или нет |
|
||||
*/ |
|
||||
function match($path_arr) |
|
||||
{ |
|
||||
$parts = explode('/', $this->path); |
|
||||
$cnt = count($parts); |
|
||||
if (end($parts) == self::URL_VARIABLE) { |
|
||||
$cnt--; |
|
||||
} elseif ($cnt != count($path_arr)) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
for ($i=0; $i<$cnt; $i++) { |
|
||||
if (substr($parts[$i], 0, 1) == self::URL_VARIABLE) { |
|
||||
$this->params[substr($parts[$i], 1)] = $path_arr[$i]; |
|
||||
} elseif ($parts[$i] != $path_arr[$i]) { |
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return true; |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,18 +0,0 @@ |
|||||
<?php |
|
||||
|
|
||||
/** |
|
||||
* Эксепшен для вывода статических шаблонов |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Core |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
class StaticPageException extends Exception |
|
||||
{ |
|
||||
|
|
||||
} |
|
||||
?>
|
|
@ -1,175 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Простейший шаблонизатор. |
|
||||
* Зато быстрый. |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage Decorator |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
final class Sublimer |
|
||||
{ |
|
||||
const GLOBAL_KEY = 0; |
|
||||
|
|
||||
public $vars = array(); |
|
||||
public $path = ''; |
|
||||
public $template = ''; |
|
||||
|
|
||||
protected $head_array = array(); |
|
||||
|
|
||||
/** |
|
||||
* Конструктор |
|
||||
* |
|
||||
* @param string $path - путь до шаблонов |
|
||||
*/ |
|
||||
public function __construct($path = '') |
|
||||
{ |
|
||||
$this->setPath($path); |
|
||||
$this->vars[self::GLOBAL_KEY] = array(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Присвоить переменную только |
|
||||
* |
|
||||
* @param string $name - имя переменной |
|
||||
* @param mixed $value - значение переменной |
|
||||
* @param string $template - шаблон, если не указан, то переменная глобальная |
|
||||
*/ |
|
||||
public function assign($name, $value, $template = self::GLOBAL_KEY) |
|
||||
{ |
|
||||
$this->vars[$template][$name] = $value; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Очистить стек переменных |
|
||||
* @param boolean $with_local - включая локальные переменные |
|
||||
*/ |
|
||||
public function clear($template = self::GLOBAL_KEY) |
|
||||
{ |
|
||||
$this->vars[$template] = array(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Обработать шаблон |
|
||||
* |
|
||||
* @param string $template - относительный путь до шаблона |
|
||||
* @return string - обработанное содержимое шаблона |
|
||||
*/ |
|
||||
public function fetch($template) |
|
||||
{ |
|
||||
$this->template = $template; //дабы экстракт не перезатер нам переменную. Это важно! $this то он не перезатрет :)
|
|
||||
extract($this->vars[self::GLOBAL_KEY]); |
|
||||
if (isset($this->vars[$this->template])) { |
|
||||
extract($this->vars[$this->template], EXTR_OVERWRITE); |
|
||||
} |
|
||||
ob_start(); |
|
||||
if (!(include $this->path.'/'.$this->template) == 'OK') { |
|
||||
throw new MJException('Template '.$this->path.'/'.$this->template.' not found'); |
|
||||
} |
|
||||
return ob_get_clean(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Установать путь до шаблонов |
|
||||
* |
|
||||
* @param string $path - путь до шаблонов |
|
||||
*/ |
|
||||
public function setPath($path) |
|
||||
{ |
|
||||
$this->path = $path; |
|
||||
} |
|
||||
|
|
||||
//Функции для вызова из шаблонов.
|
|
||||
|
|
||||
protected function addHead($str) |
|
||||
{ |
|
||||
$this->head_array[] = $str; |
|
||||
} |
|
||||
|
|
||||
protected function getHead() |
|
||||
{ |
|
||||
return $this->head_array; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* обрезает текст до заданной длинны |
|
||||
* |
|
||||
* @param string $text |
|
||||
* @param int $count |
|
||||
* @param string $postfix |
|
||||
*/ |
|
||||
protected function trimString($text, $count = 15, $postfix = "...") |
|
||||
{ |
|
||||
return (mb_strlen($text) > $count) ? mb_substr($text, 0, $count).$postfix : $text; |
|
||||
} |
|
||||
|
|
||||
|
|
||||
/** |
|
||||
* Выполняет разрыв строки на данное количество символов с использованием символа разрыва (wordwrap для utf) |
|
||||
* |
|
||||
* @param string $text |
|
||||
* @param int $width |
|
||||
* @param string $break |
|
||||
* @return string |
|
||||
*/ |
|
||||
protected function wrapString($text, $width = 15, $break = " ") |
|
||||
{ |
|
||||
$words = explode(' ', $text); |
|
||||
for ($i = 0; $i < count($words); $i++) { |
|
||||
if (mb_strlen($words[$i]) > $width) { |
|
||||
for ($j = $width; $j < mb_strlen($words[$i]); $j += $width + (mb_strlen($break))) { |
|
||||
$words[$i] = mb_substr($words[$i], 0, $j) . $break . mb_substr($words[$i], $j); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return implode(' ', $words); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Формирует get-строку для запроса |
|
||||
* |
|
||||
* @param array/string $replace - Имя переменной для замены (либо массив ключ=значение) В случае false вернет весь get |
|
||||
* @param mixed $value - значение переменной для замены, если $replace - массив, то не играет роли. В случае false переменная удаляется из get |
|
||||
* @return string |
|
||||
*/ |
|
||||
function formGet($replace = false, $value = false) |
|
||||
{ |
|
||||
$chunk = true; //обрезать последний & (или ?)
|
|
||||
$get = $_GET; //дабы не менять дефолтный массив
|
|
||||
if (is_array($replace)) { |
|
||||
foreach($replace as $key => $val) { |
|
||||
if($val === false) { |
|
||||
unset($get[$key]); |
|
||||
$chunk = false; |
|
||||
} else { |
|
||||
$get[$key] = $val; |
|
||||
} |
|
||||
} |
|
||||
} else if ($replace !== false) { |
|
||||
if ($value === false) { //для получения строки БЕЗ параметра с именем $replace
|
|
||||
unset($get[$replace]); |
|
||||
$chunk = false; |
|
||||
} else { |
|
||||
$get[$replace] = $value; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
$str = '?'; |
|
||||
foreach($get as $key => $val) { |
|
||||
$str .= $key.'='.$val.'&'; |
|
||||
} |
|
||||
|
|
||||
if ($chunk) { |
|
||||
$str = mb_substr($str, 0, -1); |
|
||||
} |
|
||||
|
|
||||
return htmlspecialchars($str); |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
?>
|
|
@ -1,110 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Класс базы данных. |
|
||||
* Возвращает идентификатор соединения |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Majestic |
|
||||
* @subpackage DB |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
class DBConnector |
|
||||
{ |
|
||||
static private $handlers = array(); |
|
||||
static public $queries = array(); |
|
||||
|
|
||||
/** |
|
||||
* Запрещаем new и клонирование |
|
||||
*/ |
|
||||
private function __construct(){} |
|
||||
|
|
||||
private function __clone(){} |
|
||||
|
|
||||
/** |
|
||||
* Получение соединения. |
|
||||
* Если соединение с такими параметрами уже есть - новое не создается. |
|
||||
* |
|
||||
* @param array $db_settings - массив настроек |
|
||||
* @return resource - идентификатор соединения |
|
||||
*/ |
|
||||
static public function getConnect($db_settings) |
|
||||
{ |
|
||||
$handler_name = self::getConnectionName($db_settings); |
|
||||
|
|
||||
if (isset(self::$handlers[$handler_name])) { |
|
||||
return self::$handlers[$handler_name]; |
|
||||
} |
|
||||
|
|
||||
if (!$handler = pg_connect("host='".$db_settings['host']."' dbname='".$db_settings['database']."' user='".$db_settings['user']."' password='".$db_settings['password']."'")) { |
|
||||
throw new MJException('Can\'t connect to DB '.pg_last_error(), 2); |
|
||||
} |
|
||||
|
|
||||
return self::$handlers[$handler_name] = $handler; |
|
||||
} |
|
||||
|
|
||||
static protected function getConnectionName($db_settings) |
|
||||
{ |
|
||||
return $db_settings['host'] . '-' . $db_settings['database']; |
|
||||
} |
|
||||
|
|
||||
/////////
|
|
||||
|
|
||||
static public function query($handler, $sql) |
|
||||
{ |
|
||||
return pg_query($handler, $sql); |
|
||||
} |
|
||||
|
|
||||
static public function escape($handler, $str) |
|
||||
{ |
|
||||
return pg_escape_string($str); |
|
||||
} |
|
||||
|
|
||||
static public function error($handler) |
|
||||
{ |
|
||||
return pg_last_error($handler); |
|
||||
} |
|
||||
|
|
||||
static public function free($result) |
|
||||
{ |
|
||||
return pg_free_result($result); |
|
||||
} |
|
||||
|
|
||||
static public function fetchObject($result, $class_name = false) |
|
||||
{ |
|
||||
return $class_name ? pg_fetch_object($result, null, $class_name) : pg_fetch_object($result); |
|
||||
} |
|
||||
|
|
||||
static public function numRows($result) |
|
||||
{ |
|
||||
return pg_num_rows($result); |
|
||||
} |
|
||||
|
|
||||
static public function affectedRows($handler, $result) |
|
||||
{ |
|
||||
return pg_affected_rows($result); |
|
||||
} |
|
||||
|
|
||||
static public function getId($handler) |
|
||||
{ |
|
||||
return -1; //DISABLED FORM postgreSQL
|
|
||||
} |
|
||||
|
|
||||
static public function autocommit($handler, $switch) |
|
||||
{ |
|
||||
throw new MJException('Autocommit disabled for postgreSQL Connector' ,1); |
|
||||
} |
|
||||
|
|
||||
static public function commit($handler) |
|
||||
{ |
|
||||
throw new MJException('Commit disabled for postgreSQL Connector' ,1); |
|
||||
} |
|
||||
|
|
||||
static public function rollback($handler) |
|
||||
{ |
|
||||
throw new MJException('Rollback disabled for postgreSQL Connector' ,1); |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -1,28 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Файл роутеров |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Nakon |
|
||||
* @subpackage Config |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
|
|
||||
require('sys.inc.php'); |
|
||||
$path = explode('?', Env::Server('REQUEST_URI')); |
|
||||
$path = trim($path[0], '/'); |
|
||||
define('MJ_URL', '/'.$path.'/'); |
|
||||
if (defined('PATH_TRIM') && PATH_TRIM != '' && strpos($path, PATH_TRIM) === 0) { |
|
||||
$path = substr($path, strlen(PATH_TRIM) + 1); |
|
||||
} |
|
||||
define('MJ_PATH', $path); |
|
||||
unset($path); |
|
||||
|
|
||||
require(CONFIG_PATH.'/routers.inc.php'); |
|
||||
|
|
||||
define('E_404', 404); |
|
||||
define('E_403', 403); |
|
||||
?>
|
|
@ -1,100 +0,0 @@ |
|||||
<?php |
|
||||
/** |
|
||||
* Внутренний файл инициализации. |
|
||||
* Если вы не меняли стандартное расположение файлов, |
|
||||
* то ничего тут править не надо. |
|
||||
* |
|
||||
* @copyright NetMonsters <team@netmonsters.ru> |
|
||||
* @link |
|
||||
* @package Nakon |
|
||||
* @subpackage System |
|
||||
* @since |
|
||||
* @version SVN: $Id$ |
|
||||
* @filesource $URL$ |
|
||||
*/ |
|
||||
/** |
|
||||
* Пути к файлам системы. |
|
||||
*/ |
|
||||
$a = realpath(dirname(__FILE__).'/../..').'/'; |
|
||||
define('INIT_PATH', $a.'config'); |
|
||||
define('CORE_PATH', $a.'core/classes'); |
|
||||
define('LIB_PATH', $a.'lib'); |
|
||||
define('MODEL_PATH', $a.'lib/models'); |
|
||||
|
|
||||
define('CACHE_PATH', $a.'cache'); |
|
||||
|
|
||||
|
|
||||
if (!defined('SITE_PART')) { |
|
||||
define('SITE_PART', 'admin'); |
|
||||
} |
|
||||
|
|
||||
define('HTDOCS_PATH', $a.SITE_PART.'/htdocs'); |
|
||||
define('DECORATOR_PATH', $a.SITE_PART.'/decorators'); |
|
||||
define('ACTION_PATH', $a.SITE_PART.'/actions'); |
|
||||
define('TPL_PATH', $a.SITE_PART.'/templates'); |
|
||||
define('CONFIG_PATH', $a.SITE_PART.'/config'); |
|
||||
unset($a); |
|
||||
|
|
||||
define('WRAPPERS_TPL_PATH', TPL_PATH.'/wrappers'); |
|
||||
define('ACTION_TPL_PATH', TPL_PATH.'/actions'); |
|
||||
define('STATIC_TPL_PATH', TPL_PATH.'/static'); |
|
||||
|
|
||||
define('DECORATOR_POSTFIX', 'Decorator'); |
|
||||
define('MODEL_POSTFIX', 'Model'); |
|
||||
define('ACTION_POSTFIX', 'Action'); |
|
||||
define('EXCEPTION_POSTFIX', 'Exception'); |
|
||||
|
|
||||
define('TIME_NOW', time()); |
|
||||
|
|
||||
/** |
|
||||
* Основные файлы системы. |
|
||||
* Эти файлы загружаются всегда, т.к. без них работа системы невозможна |
|
||||
*/ |
|
||||
require(CORE_PATH.'/Env.class.php'); |
|
||||
require(CORE_PATH.'/Load.class.php'); |
|
||||
require(CORE_PATH.'/Router.class.php'); |
|
||||
require(CORE_PATH.'/PageController.class.php'); |
|
||||
require(CORE_PATH.'/Decorator.class.php'); |
|
||||
require(CORE_PATH.'/Action.class.php'); |
|
||||
|
|
||||
/** |
|
||||
* Файлы конфигурации. |
|
||||
*/ |
|
||||
if (file_exists(INIT_PATH.'/local.inc.php')) { |
|
||||
require(INIT_PATH.'/local.inc.php'); |
|
||||
} else { |
|
||||
require(INIT_PATH.'/global.inc.php'); |
|
||||
} |
|
||||
Env::setParams($CONFIG); |
|
||||
require(CONFIG_PATH.'/config.inc.php'); |
|
||||
Env::setParams($CONFIG); |
|
||||
|
|
||||
function __autoload($name) |
|
||||
{ |
|
||||
preg_match_all('/[A-Z]+[^A-Z]+/', $name, $match); |
|
||||
$type = end($match[0]); |
|
||||
|
|
||||
$class_name = substr($name, 0, -strlen($type)); |
|
||||
|
|
||||
switch ($type) { |
|
||||
case 'DBConnector': |
|
||||
require(CORE_PATH.'/'.(defined('CUSTOM_DBCONNECTOR') ? CUSTOM_DBCONNECTOR.'_' : '').'DBConnector.class.php'); |
|
||||
break; |
|
||||
case $name: |
|
||||
case EXCEPTION_POSTFIX: |
|
||||
require(CORE_PATH.'/'.$name.'.class.php'); |
|
||||
break; |
|
||||
case ACTION_POSTFIX: |
|
||||
require(ACTION_PATH.'/'.strtolower($match[0][0]).'/'.$class_name.'.action.php'); |
|
||||
break; |
|
||||
case DECORATOR_POSTFIX: |
|
||||
require(DECORATOR_PATH.'/'.$class_name.'.decorator.php'); |
|
||||
break; |
|
||||
case MODEL_POSTFIX: |
|
||||
require(MODEL_PATH.'/'.$class_name.'.model.php'); |
|
||||
break; |
|
||||
default: |
|
||||
require(LIB_PATH.'/'.$name.'.lib.php'); |
|
||||
} |
|
||||
} |
|
||||
?>
|
|
@ -0,0 +1,53 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage Layout |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
abstract class Layout |
||||
|
{ |
||||
|
|
||||
|
protected $template; |
||||
|
|
||||
|
/** |
||||
|
* @var PHPView |
||||
|
*/ |
||||
|
protected $view; |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
$this->view = FrontController::getInstance()->getView(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param string $name |
||||
|
* @param ViewAction $action |
||||
|
*/ |
||||
|
protected function assign($name, $action) |
||||
|
{ |
||||
|
$this->view->assign($name, $action->fetch()); |
||||
|
} |
||||
|
|
||||
|
abstract protected function execute(); |
||||
|
|
||||
|
/** |
||||
|
* @param ViewAction $action |
||||
|
*/ |
||||
|
public function fetch($action) |
||||
|
{ |
||||
|
$this->view->assign('content', $action->fetch()); |
||||
|
$this->execute(); |
||||
|
return $this->view->fetch($this->getTemplate()); |
||||
|
} |
||||
|
|
||||
|
protected function getTemplate() |
||||
|
{ |
||||
|
$template = ($this->template) ? $this->template : substr(get_class($this), 0, -6/*strlen('Layout')*/); |
||||
|
return '/layouts/' . $template; |
||||
|
} |
||||
|
} |
@ -0,0 +1,94 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* Generates array of classes for autoload |
||||
|
* |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage util |
||||
|
* @since 2010-02-24 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
class AutoloadBuilder |
||||
|
{ |
||||
|
protected $autoload; |
||||
|
protected $dirs; |
||||
|
protected $handler; |
||||
|
protected $regex = '/(class|interface) ([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)/'; |
||||
|
|
||||
|
public function __construct($autoload, $dirs = array()) |
||||
|
{ |
||||
|
$this->autoload = $autoload; |
||||
|
$this->dirs = $dirs; |
||||
|
} |
||||
|
|
||||
|
public function build() |
||||
|
{ |
||||
|
$this->openAutoload(); |
||||
|
echo "parsing started...\n"; |
||||
|
// for dublicates check
|
||||
|
$classes = array(); |
||||
|
foreach ($this->dirs as $dir) { |
||||
|
$iterator = new RecursiveIteratorIterator( |
||||
|
new RecursiveDirectoryIterator($dir), |
||||
|
RecursiveIteratorIterator::LEAVES_ONLY |
||||
|
); |
||||
|
|
||||
|
foreach ($iterator as $file) { |
||||
|
// skip non php files
|
||||
|
$e = explode('.', $file->getFileName()); |
||||
|
if ((end($e) !== 'php') || strstr((string)$file, 'test')) { |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
$content = file_get_contents($file->getRealPath()); |
||||
|
$matches = array(); |
||||
|
|
||||
|
$relative_path = substr($file->getRealPath(), strlen(PATH)); |
||||
|
|
||||
|
if (preg_match_all($this->regex, $content, $matches, PREG_SET_ORDER)) { |
||||
|
foreach ($matches as $match) { |
||||
|
echo "found {$match[0]}..."; |
||||
|
if (array_key_exists($match[2], $classes)) { |
||||
|
echo " FAULT\n{$match[0]} also found in ". |
||||
|
$file->getRealPath(). ", skipped.\n"; |
||||
|
continue; |
||||
|
} |
||||
|
echo " OK\n"; |
||||
|
$string = "'{$match[2]}'=>'" . $relative_path . "',\n"; |
||||
|
$this->write($string); |
||||
|
$classes[$match[2]] = $file->getRealPath(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
echo "done.\n"; |
||||
|
$this->closeAutoload(); |
||||
|
} |
||||
|
|
||||
|
protected function openAutoload() |
||||
|
{ |
||||
|
$this->write("<?php\n// This file is autogenerated by \n// " . __FILE__ . " script.\nreturn array(\n"); |
||||
|
} |
||||
|
|
||||
|
protected function closeAutoload() |
||||
|
{ |
||||
|
if ($this->write(");\n")) { |
||||
|
fclose($this->handler); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected function write($string) |
||||
|
{ |
||||
|
if (! $this->handler) { |
||||
|
if (! $this->handler = fopen($this->autoload, 'w')) { |
||||
|
echo "{$this->autoload} is not writable\n"; |
||||
|
die; |
||||
|
} |
||||
|
} |
||||
|
return (bool) fwrite($this->handler, $string); |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,72 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage View |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
class PHPView implements iView |
||||
|
{ |
||||
|
|
||||
|
protected $path = ''; |
||||
|
protected $variables = array(); |
||||
|
protected $extension = '.phtml'; |
||||
|
protected $template = ''; |
||||
|
|
||||
|
public function __construct($path) |
||||
|
{ |
||||
|
$this->setPath($path); |
||||
|
} |
||||
|
|
||||
|
public function getPath() |
||||
|
{ |
||||
|
return $this->path; |
||||
|
} |
||||
|
|
||||
|
public function setPath($path) |
||||
|
{ |
||||
|
$this->path = $path; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @param ViewAction $object |
||||
|
*/ |
||||
|
public function assignObject($object) |
||||
|
{ |
||||
|
foreach (get_object_vars($object) as $name => $value) { |
||||
|
$this->assign($name, $value); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function assign($name, $value = null) |
||||
|
{ |
||||
|
$this->variables[$name] = $value; |
||||
|
} |
||||
|
|
||||
|
public function fetch($template) |
||||
|
{ |
||||
|
$this->template = $this->getTemplatePath($template); |
||||
|
unset($template); |
||||
|
extract($this->variables); |
||||
|
ob_start(); |
||||
|
if (!(include($this->template)) == 'OK') { |
||||
|
ob_clean(); |
||||
|
throw new Exception('Template "' . $this->template .'" not found.'); |
||||
|
} |
||||
|
return ob_get_clean(); |
||||
|
} |
||||
|
|
||||
|
public function escape($var) |
||||
|
{ |
||||
|
return htmlentities($var, ENT_QUOTES, 'UTF-8'); |
||||
|
} |
||||
|
|
||||
|
protected function getTemplatePath($template) |
||||
|
{ |
||||
|
return $this->path . $template . $this->extension; |
||||
|
} |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* @copyright NetMonsters <team@netmonsters.ru> |
||||
|
* @link http://netmonsters.ru |
||||
|
* @package Majestic |
||||
|
* @subpackage View |
||||
|
* @since 2010-02-25 |
||||
|
* @version SVN: $Id$ |
||||
|
* @filesource $URL$ |
||||
|
*/ |
||||
|
|
||||
|
interface iView |
||||
|
{ |
||||
|
public function assign($name, $value = null); |
||||
|
public function fetch($template); |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue