Compare commits
116 Commits
Author | SHA1 | Date | |
---|---|---|---|
3126483bae | |||
da17b79291 | |||
f1eb97348c | |||
5f6a454e6a | |||
aa9ac8dfe8 | |||
d9573958bd | |||
d5a2da7cbf | |||
388673d856 | |||
f954f79250 | |||
823a7af927 | |||
66d342272d | |||
b6e002f5a8 | |||
bccd018530 | |||
67f47b882b | |||
b7ff8ab3fc | |||
b4c3d89020 | |||
9e359e0c25 | |||
776859b3c8 | |||
acec4a521e | |||
28efb6c675 | |||
383396b96d | |||
d3f367d990 | |||
b7fcfcf476 | |||
2a98f9b0d7 | |||
15ea37109d | |||
d42074b620 | |||
0f8c0df4bc | |||
b710a63dc7 | |||
9c58757641 | |||
1922886c2f | |||
8c57655124 | |||
5b7a10e099 | |||
b85c96c80e | |||
60fdc48b2b | |||
61be1700ee | |||
0057d6ff7c | |||
0dde2ccb59 | |||
37c6dab160 | |||
3709fb2a74 | |||
c9b38314b5 | |||
52de52a17a | |||
d710b19fed | |||
1ba341b064 | |||
aec1a60985 | |||
c62620593f | |||
e8e266a101 | |||
ff148f2f95 | |||
906ffe07a8 | |||
cabb17b3c4 | |||
3b390d968b | |||
0b0dc61960 | |||
3a560dfe6f | |||
d1c8ecf850 | |||
d3b79e594f | |||
5f9c295c01 | |||
6b0bf4058e | |||
2cb51015e6 | |||
3272d7a903 | |||
740bd6b7f3 | |||
a090d52676 | |||
94addf4ca9 | |||
7486ab5cf1 | |||
8b17a8f911 | |||
153d6fa20a | |||
049999dfbd | |||
4878b32641 | |||
253b303084 | |||
1ea6c5acdd | |||
d019ae2450 | |||
8311fa1c26 | |||
645ffd9ed1 | |||
5d7162480a | |||
3263af5e18 | |||
40e049c93e | |||
ff76d8fa1d | |||
559d779576 | |||
6890827f17 | |||
9a881f6560 | |||
d1cf95b82c | |||
3f6b2adefd | |||
e06ddba773 | |||
0fc1884c93 | |||
9625b1e7a4 | |||
9ab3bfc0da | |||
dff9c0b2af | |||
72c38e641d | |||
ba88ac5229 | |||
ab01d0a41f | |||
2cb56ad228 | |||
732b1ca8a5 | |||
c890d082aa | |||
a51545268d | |||
4b31df52c3 | |||
f9de8ee3bc | |||
625752ced7 | |||
0ac9f3c5e8 | |||
7fd2961737 | |||
3e30e59e0b | |||
a029cc3c57 | |||
5dd81b24fc | |||
8113986276 | |||
10c68143cb | |||
ef99a26635 | |||
8133695eae | |||
5b9eab1067 | |||
3b6ae39707 | |||
163ac086b0 | |||
126d97b020 | |||
a2cb6a405e | |||
fce43da00d | |||
98324588b7 | |||
c525a09078 | |||
748393f653 | |||
5f47dab73e | |||
91b364d01a | |||
d007f356c0 |
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -13,7 +13,7 @@ abstract class Action
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* @var PHPView
|
||||
* @var \Majestic\View\PHPView
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
@ -26,7 +26,7 @@ abstract class Action
|
||||
|
||||
protected function extractParams()
|
||||
{
|
||||
foreach (Env::getParam() as $name => $value) {
|
||||
foreach (\Majestic\Env::getParam() as $name => $value) {
|
||||
if (is_string($name)) {
|
||||
$this->$name = $value;
|
||||
}
|
||||
@ -39,10 +39,14 @@ abstract class Action
|
||||
* Redirect
|
||||
*
|
||||
* @param mixed $url
|
||||
* @param bool $permanently
|
||||
*/
|
||||
protected function redirect($url = null)
|
||||
protected function redirect($url = null, $permanently = false)
|
||||
{
|
||||
header('Location: ' . (($url) ? $url : Env::getRequestUri()));
|
||||
if ($permanently) {
|
||||
header('HTTP/1.1 301 Moved Permanently');
|
||||
}
|
||||
header('Location: ' . (($url) ? $url : \Majestic\Env::getRequestUri()));
|
||||
exit();
|
||||
}
|
||||
|
||||
@ -50,7 +54,7 @@ abstract class Action
|
||||
{
|
||||
$class = get_class($this);
|
||||
$template = ($this->template) ? $this->template : substr($class, 0, -6 /*strlen('Action')*/);
|
||||
$dir = array_slice(explode('/', Load::getFilePath($class)), -2, 1);
|
||||
$dir = array_slice(explode('/', \Majestic\Load::getFilePath($class)), -2, 1);
|
||||
return '/actions/' . array_pop($dir) . '/' . $template;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* AjaxAction
|
||||
*
|
99
App/CliController.php
Normal file
99
App/CliController.php
Normal file
@ -0,0 +1,99 @@
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
* @package Majestic
|
||||
* @subpackage App
|
||||
* @since 27.06.12
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @desc CliController (run cli_class, end profiler)
|
||||
* @author Aleksandr Demidov
|
||||
*/
|
||||
class CliController
|
||||
{
|
||||
/**
|
||||
* @var CliController
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
protected $error_stream;
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
//\Majestic\Exception\ErrorHandler::init();
|
||||
$this->error_stream = \Majestic\Config::get('ErrorStream', 'php://stderr');
|
||||
}
|
||||
|
||||
/**
|
||||
* Refuse cloning
|
||||
* @codeCoverageIgnoreStart
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnoreEnd
|
||||
*/
|
||||
|
||||
/**
|
||||
* @static
|
||||
* @return CliController
|
||||
*/
|
||||
public static function getInstance()
|
||||
{
|
||||
if (!isset(self::$instance)) {
|
||||
self::$instance = new static();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param iCli|string $cli
|
||||
* @throws \ErrorException|\Majestic\Exception\GeneralException
|
||||
*/
|
||||
public function execute($cli)
|
||||
{
|
||||
try {
|
||||
$this->run($cli);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$this->exception($e);
|
||||
}
|
||||
}
|
||||
|
||||
protected function run($cli)
|
||||
{
|
||||
if (is_string($cli)) {
|
||||
if (!class_exists($cli)) {
|
||||
throw new \Majestic\Exception\GeneralException('Action class "' . $cli . '" not found.');
|
||||
}
|
||||
$cli = new $cli;
|
||||
}
|
||||
if (!in_array('Majestic\App\iCli', class_implements($cli))) {
|
||||
throw new \ErrorException('Runner "' . get_class($cli) . '" need implement of "iCli" interface.');
|
||||
}
|
||||
$cli->run();
|
||||
if (\Majestic\Config::get('PROFILER')) {
|
||||
$profile = \Majestic\Util\Profiler\Profiler::getInstance()->getCli();
|
||||
if (\Majestic\Config::get('LOGGING')) {
|
||||
\Majestic\Logger\Logger::getInstance()->log($profile);
|
||||
} else {
|
||||
echo $profile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function exception($e)
|
||||
{
|
||||
$code = $e->getCode();
|
||||
if ($e instanceof \ErrorException) {
|
||||
$code = $e->getSeverity();
|
||||
}
|
||||
file_put_contents($this->error_stream, PHP_EOL . 'Error ' . '#' . $code . ': ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
|
||||
file_put_contents($this->error_stream, PHP_EOL . 'Stack trace: ' . PHP_EOL . $e->getTraceAsString() . PHP_EOL, FILE_APPEND);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -11,7 +11,7 @@ class ErrorAction extends Action
|
||||
{
|
||||
|
||||
/**
|
||||
* @var ErrorException|ErrorHTTPException
|
||||
* @var \ErrorException|\Majestic\Exception\ErrorHTTPException
|
||||
*/
|
||||
public $exception;
|
||||
|
||||
@ -25,11 +25,12 @@ class ErrorAction extends Action
|
||||
|
||||
protected function execute()
|
||||
{
|
||||
$this->template = 500;
|
||||
if ($this->exception instanceof Error404Exception) {
|
||||
if ($this->exception instanceof \Majestic\Exception\Error404Exception) {
|
||||
$this->template = 404;
|
||||
} elseif ($this->exception instanceof ErrorHTTPException) {
|
||||
} elseif ($this->exception instanceof \Majestic\Exception\ErrorHTTPException) {
|
||||
$this->template = 'HTTP';
|
||||
} else {
|
||||
$this->template = 500;
|
||||
}
|
||||
$this->logError();
|
||||
$this->sendHTTPCode();
|
||||
@ -50,42 +51,17 @@ class ErrorAction extends Action
|
||||
|
||||
protected function sendHttpCode()
|
||||
{
|
||||
switch ($this->template) {
|
||||
case 404:
|
||||
case 'HTTP':
|
||||
header($this->exception->getHTTPHeader());
|
||||
break;
|
||||
default:
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
if ($this->exception instanceof \Majestic\Exception\ErrorHTTPException) {
|
||||
header($this->exception->getHTTPHeader());
|
||||
} else {
|
||||
header('HTTP/1.0 500 Internal Server Error');
|
||||
}
|
||||
}
|
||||
|
||||
protected function logError()
|
||||
{
|
||||
if ($this->template == 500) {
|
||||
$error = 0;
|
||||
$ex = $this->exception;
|
||||
if ($ex instanceof ErrorException) {
|
||||
$error = $ex->getSeverity();
|
||||
}
|
||||
|
||||
switch ($error) {
|
||||
case E_NOTICE:
|
||||
$error = 'Notice';
|
||||
break;
|
||||
case E_WARNING:
|
||||
$error = 'Warning';
|
||||
break;
|
||||
case E_ERROR:
|
||||
$error = 'Fatal Error';
|
||||
break;
|
||||
default:
|
||||
$error = 'Unknown Error';
|
||||
break;
|
||||
}
|
||||
$message = 'PHP ' . $error . ': ' . $ex->getMessage() . ' in ' . $ex->getFile()
|
||||
. ' on line ' . $ex->getLine();
|
||||
error_log($message);
|
||||
if (!$this->exception instanceof \Majestic\Exception\Error404Exception) {
|
||||
\Majestic\Exception\ErrorHandler::logError($this->exception);
|
||||
}
|
||||
}
|
||||
|
137
App/FrontController.php
Normal file
137
App/FrontController.php
Normal file
@ -0,0 +1,137 @@
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
* @package Majestic
|
||||
* @subpackage app
|
||||
* @since 2010-02-24
|
||||
*/
|
||||
|
||||
class FrontController
|
||||
{
|
||||
/**
|
||||
* @var Router\Router
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $view = '\Majestic\View\PHPView';
|
||||
|
||||
protected $base_url = '';
|
||||
|
||||
/**
|
||||
* @var FrontController
|
||||
*/
|
||||
protected static $instance;
|
||||
|
||||
|
||||
private function __construct()
|
||||
{
|
||||
// \Majestic\Exception\ErrorHandler::init();
|
||||
$this->router = new Router\Router();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refuse cloning
|
||||
* @codeCoverageIgnoreStart
|
||||
*/
|
||||
private function __clone()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnoreEnd
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return FrontController
|
||||
*/
|
||||
static public function getInstance()
|
||||
{
|
||||
if (!isset(self::$instance)) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $view
|
||||
* @return FrontController
|
||||
*/
|
||||
public function setView($view)
|
||||
{
|
||||
$this->view = $view;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param null $view
|
||||
* @return ..\View\PHPView
|
||||
*/
|
||||
public function getView($view = null)
|
||||
{
|
||||
$view = ($view) ? $view : $this->view;
|
||||
return new $view(\Majestic\Config::get($view));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return FrontController
|
||||
*/
|
||||
public function setBaseUrl($url)
|
||||
{
|
||||
$this->base_url = rtrim($url, '/');
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getBaseUrl()
|
||||
{
|
||||
return $this->base_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Router\Router
|
||||
*/
|
||||
public function getRouter()
|
||||
{
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
$request = \Majestic\Env::getRequestUri(true);
|
||||
$route = $this->getRouter()->route($request);
|
||||
if (!$route) {
|
||||
$message = 'Route for "' . $request . '" not found';
|
||||
\App::abort(404, $message);
|
||||
}
|
||||
|
||||
$action_class = $route->getAction();
|
||||
if (!class_exists($action_class)) {
|
||||
throw new \Majestic\Exception\GeneralException('Action class "' . $action_class . '" not found.');
|
||||
}
|
||||
|
||||
$action = new $action_class();
|
||||
$layout_class = $route->getLayout();
|
||||
if (!class_exists($layout_class)) {
|
||||
throw new \Majestic\Exception\GeneralException('Layout class "' . $layout_class . '" not found.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @var \Majestic\Layout\Layout $layout
|
||||
*/
|
||||
$layout = new $layout_class();
|
||||
$html = $layout->fetch($action);
|
||||
if (\Majestic\Config::get('PROFILER')) {
|
||||
if (is_subclass_of($action, 'AjaxAction')) {
|
||||
\Majestic\Util\Profiler\Profiler::getInstance()->getJson();
|
||||
} else {
|
||||
$html = \Majestic\Util\Profiler\Profiler::getInstance()->end($html);
|
||||
}
|
||||
}
|
||||
return $html;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App\Router;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App\Router;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -48,7 +48,7 @@ class Router
|
||||
if ($route->match($req)) {
|
||||
$this->route_name = $name;
|
||||
$this->route = $route;
|
||||
Env::setParams($route->getParams());
|
||||
\Majestic\Env::setParams($route->getParams());
|
||||
return $this->route;
|
||||
}
|
||||
}
|
||||
@ -94,7 +94,7 @@ class Router
|
||||
/**
|
||||
* @param null|string $name
|
||||
* @return Route
|
||||
* @throws ErrorException
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function getRoute($name = null)
|
||||
{
|
||||
@ -104,7 +104,7 @@ class Router
|
||||
if ($this->routeIsExists($name)) {
|
||||
return $this->getRouteByName($name);
|
||||
} else {
|
||||
throw new ErrorException('Unknown route name: "' . $name . '".');
|
||||
throw new \ErrorException('Unknown route name: "' . $name . '".');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\App;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -6,7 +6,7 @@
|
||||
* @subpackage Cache
|
||||
* @since 2010-03-04
|
||||
*/
|
||||
|
||||
namespace Majestic\Core;
|
||||
abstract class Cache
|
||||
{
|
||||
|
28
Config.php
Normal file → Executable file
28
Config.php
Normal file → Executable file
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -7,31 +7,47 @@
|
||||
* @since 2010-02-17
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class Config extends Registry
|
||||
{
|
||||
|
||||
private static $_class_name = 'Config';
|
||||
|
||||
static public function set($name, $value)
|
||||
/**
|
||||
* Метод устанавливает параметры конфигурации
|
||||
* @param mixed $param
|
||||
* Имя параметра или параметры в массиве
|
||||
* @param mixed $value
|
||||
* Значение параметра. Не требуется, если передаются параметры в массиве
|
||||
*/
|
||||
static public function set($param, $value = null)
|
||||
{
|
||||
// Разбираю массив, если параметры переданы в массиве
|
||||
if (is_array($param)) {
|
||||
foreach ($param as $paramItem => $value) {
|
||||
self::set($paramItem, $value);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
$value = new ConfigArray($value);
|
||||
}
|
||||
self::getInstance()->offsetSet($name, $value);
|
||||
self::getInstance()->offsetSet($param, $value);
|
||||
}
|
||||
}
|
||||
|
||||
class ConfigArray extends ArrayObject
|
||||
class ConfigArray extends \ArrayObject
|
||||
{
|
||||
public function __construct($array)
|
||||
{
|
||||
parent::__construct($array, ArrayObject::ARRAY_AS_PROPS);
|
||||
parent::__construct($array, \ArrayObject::ARRAY_AS_PROPS);
|
||||
}
|
||||
|
||||
public function offsetGet($index)
|
||||
{
|
||||
if (!$this->offsetExists($index)) {
|
||||
throw new GeneralException('Configuration variable "' . $index . '" undefined');
|
||||
throw new Exception\GeneralException('Configuration variable "' . $index . '" undefined');
|
||||
}
|
||||
return parent::offsetGet($index);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic;
|
||||
/**
|
||||
* Класс для работы с переменными окружения.
|
||||
*
|
||||
@ -23,7 +23,7 @@ class Env
|
||||
list(self::$request[$trim_base], ) = explode('?', Env::Server('REQUEST_URI'));
|
||||
if ($trim_base) {
|
||||
// removes base url
|
||||
$base = FrontController::getInstance()->getBaseUrl();
|
||||
$base = \Majestic\App\FrontController::getInstance()->getBaseUrl();
|
||||
if (($length = strlen($base)) > 0 && strpos(self::$request[$trim_base], $base) === 0) {
|
||||
self::$request[$trim_base] = (string) substr(self::$request[$trim_base], $length);
|
||||
}
|
||||
@ -48,6 +48,14 @@ class Env
|
||||
return (isset($_POST[$key])) ? $_POST[$key] : $default;
|
||||
}
|
||||
|
||||
static public function Request($key = null, $default = null)
|
||||
{
|
||||
if ($key === null) {
|
||||
return $_REQUEST;
|
||||
}
|
||||
return (isset($_REQUEST[$key])) ? $_REQUEST[$key] : $default;
|
||||
}
|
||||
|
||||
static public function Cookie($key = null, $default = false)
|
||||
{
|
||||
if ($key === null) {
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Exception;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
class Error404Exception extends ErrorHTTPException {
|
||||
function __construct($message = '', $code = null, Exception $previous = NULL )
|
||||
function __construct($message = '', $code = null, \Exception $previous = NULL )
|
||||
{
|
||||
parent::__construct($message, 404, $previous);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Exception;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -15,6 +15,7 @@ class ErrorHTTPException extends GeneralException
|
||||
{
|
||||
$this->http_headers = array(
|
||||
400 => 'HTTP/1.0 400 Bad Request',
|
||||
401 => 'HTTP/1.0 400 Access allowed only for registered users',
|
||||
402 => 'HTTP/1.0 402 Payment Required',
|
||||
403 => 'HTTP/1.0 403 Forbidden',
|
||||
404 => 'HTTP/1.0 404 Not Found',
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Exception;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -12,7 +12,7 @@ class ErrorHandler
|
||||
|
||||
static public function init()
|
||||
{
|
||||
set_error_handler(array('ErrorHandler', 'error_handler'));
|
||||
//set_error_handler(array('Majestic\Exception\ErrorHandler', 'error_handler'));
|
||||
}
|
||||
|
||||
static public function error_handler($errno, $errstr, $errfile, $errline)
|
||||
@ -22,11 +22,50 @@ class ErrorHandler
|
||||
ob_end_clean();
|
||||
}
|
||||
if (error_reporting() !== 0) {
|
||||
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
throw new \ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static public function logError($exception)
|
||||
{
|
||||
$error = 0;
|
||||
$exception_name = '';
|
||||
if ($exception instanceof \ErrorException) {
|
||||
$error = $exception->getSeverity();
|
||||
} else {
|
||||
$exception_name = get_class($exception) . ': ';
|
||||
}
|
||||
|
||||
switch ($error) {
|
||||
case E_NOTICE:
|
||||
$error = 'Notice';
|
||||
break;
|
||||
case E_WARNING:
|
||||
$error = 'Warning';
|
||||
break;
|
||||
case E_ERROR:
|
||||
$error = 'Fatal Error';
|
||||
break;
|
||||
default:
|
||||
$error = 'Unknown Error';
|
||||
break;
|
||||
}
|
||||
$message = 'PHP ' . $error . ': ' . $exception_name . $exception->getMessage() . ' in ' . $exception->getFile() . ':' . $exception->getLine() . ' \nStack trace:\n' . $exception->getTraceAsString() . self::getHTTPErrorConditions();
|
||||
// PHP Fatal error: Uncaught exception 'LogicException' in /www/test.tfs/face/htdocs/index.php:11\nStack trace:\n#0 {main}\n thrown in /www/test.tfs/face/htdocs/index.php on line 11, referer: http://test.tfs.manekeno.netmonsters.ru/news/create
|
||||
error_log($message);
|
||||
}
|
||||
|
||||
static public function getHTTPErrorConditions()
|
||||
{
|
||||
$text = null;
|
||||
if (!is_null(\Majestic\Env::Server('REQUEST_METHOD')) && !is_null(\Majestic\Env::Server('REQUEST_URI'))) {
|
||||
$text = ', URL: ' . \Majestic\Env::Server('REQUEST_METHOD') . ' ' . \Majestic\Env::Server('REQUEST_URI');
|
||||
$text .= ', referrer: ' . \Majestic\Env::Server('HTTP_REFERER');
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
static protected function getSource($file, $hiline)
|
||||
{
|
||||
$code = array();
|
||||
@ -70,7 +109,7 @@ class ErrorHandler
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $exception
|
||||
* @param \Exception $exception
|
||||
* @return string
|
||||
*/
|
||||
static public function showDebug($exception)
|
||||
@ -81,19 +120,19 @@ class ErrorHandler
|
||||
}
|
||||
$class = get_class($exception);
|
||||
|
||||
$method = Env::Server('REQUEST_METHOD', '');
|
||||
$uri = Env::getRequestUri();
|
||||
$method = \Majestic\Env::Server('REQUEST_METHOD', '');
|
||||
$uri = \Majestic\Env::getRequestUri();
|
||||
$source = self::getSource($exception->getFile(), $exception->getLine());
|
||||
$time = date('r', Env::Server('REQUEST_TIME', time()));
|
||||
$time = date('r', \Majestic\Env::Server('REQUEST_TIME', time()));
|
||||
|
||||
$trace = nl2br($exception->getTraceAsString());
|
||||
|
||||
$get = self::wrapArray(Env::Get(), 'GET');
|
||||
$post = self::wrapArray(Env::Post(), 'POST');
|
||||
$session = self::wrapArray(Session::get(), 'SESSION');
|
||||
$files = self::wrapArray(Env::Files(), 'FILES');
|
||||
$cookies = self::wrapArray(Env::Cookie(), 'COOKIE');
|
||||
$server = self::wrapArray(Env::Server(), 'SERVER');
|
||||
$get = self::wrapArray(\Majestic\Env::Get(), 'GET');
|
||||
$post = self::wrapArray(\Majestic\Env::Post(), 'POST');
|
||||
$session = self::wrapArray(\Majestic\Session\Session::get(), 'SESSION');
|
||||
$files = self::wrapArray(\Majestic\Env::Files(), 'FILES');
|
||||
$cookies = self::wrapArray(\Majestic\Env::Cookie(), 'COOKIE');
|
||||
$server = self::wrapArray(\Majestic\Env::Server(), 'SERVER');
|
||||
|
||||
$message = <<<EOD
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Exception;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -7,4 +7,4 @@
|
||||
* @since 2010-02-26
|
||||
*/
|
||||
|
||||
class GeneralException extends Exception {}
|
||||
class GeneralException extends \Exception {}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Exception;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -9,4 +9,4 @@
|
||||
* Exception from initializtion object
|
||||
*/
|
||||
|
||||
class InitializationException extends Exception {}
|
||||
class InitializationException extends \Exception {}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Form;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -47,7 +47,7 @@ abstract class Form
|
||||
public function isValid($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
throw new InitializationException(__CLASS__ . '::' . __METHOD__ . ' expects an array');
|
||||
throw new \Majestic\Exception\InitializationException(__CLASS__ . '::' . __METHOD__ . ' expects an array');
|
||||
}
|
||||
|
||||
foreach ($this->fields as $field_name => $field) {
|
||||
@ -148,7 +148,7 @@ abstract class Form
|
||||
{
|
||||
$data['messages'] = $this->getMessages();
|
||||
$data['values'] = $this->getSourceValues();
|
||||
Session::set(get_class($this), $data);
|
||||
\Majestic\Session\Session::set(get_class($this), $data);
|
||||
}
|
||||
|
||||
abstract protected function init();
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Form;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -93,7 +93,7 @@ class FormField
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[]|iValidator[] $validators
|
||||
* @param string[]|\Majestic\Validator\iValidator[] $validators
|
||||
* @return FormField
|
||||
*/
|
||||
public function addValidators($validators)
|
||||
@ -105,19 +105,19 @@ class FormField
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|iValidator $validator
|
||||
* @param string|\Majestic\Validator\iValidator $validator
|
||||
* @return FormField
|
||||
* @throws InitializationException
|
||||
* @throws \Majestic\Exception\InitializationException
|
||||
*/
|
||||
public function addValidator($validator)
|
||||
{
|
||||
if ($validator instanceof iValidator) {
|
||||
if ($validator instanceof \Majestic\Validator\iValidator) {
|
||||
$name = get_class($validator);
|
||||
} elseif (is_string($validator)) {
|
||||
$name = $validator . 'Validator';
|
||||
$validator = new $name();
|
||||
} else {
|
||||
throw new InitializationException('Invalid validator provided to addValidator; must be string or iValidator');
|
||||
throw new \Majestic\Exception\InitializationException('Invalid validator provided to addValidator; must be string or iValidator');
|
||||
}
|
||||
$this->validators[$name] = $validator;
|
||||
return $this;
|
||||
@ -139,7 +139,7 @@ class FormField
|
||||
$name = $filter . 'Filter';
|
||||
$filter = new $name();
|
||||
} else {
|
||||
throw new InitializationException('Invalid filter provided to addFilter; must be string or iFilter');
|
||||
throw new \Majestic\Exception\InitializationException('Invalid filter provided to addFilter; must be string or iFilter');
|
||||
}
|
||||
$this->filters[$name] = $filter;
|
||||
return $this;
|
||||
@ -192,7 +192,7 @@ class FormField
|
||||
if (!$validator->isValid($val, $context)) {
|
||||
$valid = false;
|
||||
if (!$this->default_message) {
|
||||
throw new InitializationException('Define default message for array fields');
|
||||
throw new \Majestic\Validator\InitializationException('Define default message for array fields');
|
||||
}
|
||||
$this->message = $this->default_message;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Form;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -16,10 +16,10 @@ class FormViewHelper extends ViewHelper
|
||||
{
|
||||
if ($this->data === null) {
|
||||
if ($form == null) {
|
||||
throw new InitializationException('Form name required for helper init');
|
||||
throw new \Majestic\ExceptionInitializationException('Form name required for helper init');
|
||||
}
|
||||
$this->data = Session::get($form, array());
|
||||
Session::del($form);
|
||||
$this->data = \Majestic\Session\Session::get($form, array());
|
||||
\Majestic\Session\Session::del($form);
|
||||
}
|
||||
return $this;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Layout;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -10,7 +10,7 @@
|
||||
class ErrorLayout extends Layout
|
||||
{
|
||||
/**
|
||||
* @var GeneralException
|
||||
* @var \Majestic\ExceptionGeneralException
|
||||
*/
|
||||
protected $exception;
|
||||
|
||||
@ -19,9 +19,9 @@ class ErrorLayout extends Layout
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Exception $exception
|
||||
* @param \Exception $exception
|
||||
*/
|
||||
public function setException(Exception $exception)
|
||||
public function setException(\Exception $exception)
|
||||
{
|
||||
$this->exception = $exception;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Layout;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -13,18 +13,18 @@ abstract class Layout
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* @var PHPView
|
||||
* @var \Majestic\View\PHPView
|
||||
*/
|
||||
protected $view;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->view = FrontController::getInstance()->getView();
|
||||
$this->view = \Majestic\App\FrontController::getInstance()->getView();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param Action $action
|
||||
* @param \Majestic\App\Action $action
|
||||
*/
|
||||
protected function assign($name, $action)
|
||||
{
|
||||
@ -34,7 +34,7 @@ abstract class Layout
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param Action $action
|
||||
* @param \Majestic\App\Action $action
|
||||
*/
|
||||
protected function append($name, $action)
|
||||
{
|
||||
@ -44,7 +44,7 @@ abstract class Layout
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param Action $action
|
||||
* @param \Majestic\App\Action $action
|
||||
*/
|
||||
protected function prepend($name, $action)
|
||||
{
|
||||
@ -55,7 +55,7 @@ abstract class Layout
|
||||
|
||||
/**
|
||||
* Execute Action, insert action's result html into layout template and return Layout html
|
||||
* @param Action $action
|
||||
* @param \Majestic\App\Action $action
|
||||
* @return string
|
||||
*/
|
||||
public function fetch($action)
|
34
Load.php
34
Load.php
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -16,6 +16,17 @@ class Load
|
||||
|
||||
static protected $exclude = array();
|
||||
|
||||
static protected $builder = null;
|
||||
|
||||
/**
|
||||
* @var \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
static protected $class_loader;
|
||||
|
||||
static public function setClassLoader($class_loader) {
|
||||
self::$class_loader = $class_loader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add exclude path for autoload. Should be called before setAutoloadFrom
|
||||
* @static
|
||||
@ -24,7 +35,7 @@ class Load
|
||||
*/
|
||||
static public function setExclude($exclude = array())
|
||||
{
|
||||
if(!is_array($exclude)) {
|
||||
if (!is_array($exclude)) {
|
||||
$exclude = array($exclude);
|
||||
}
|
||||
self::$exclude = array_merge(self::$exclude, $exclude);
|
||||
@ -60,7 +71,11 @@ class Load
|
||||
|
||||
static public function getFilePath($class)
|
||||
{
|
||||
return self::$autoload[$class];
|
||||
if (self::$class_loader) {
|
||||
return self::$class_loader->findFile($class);
|
||||
} else {
|
||||
return self::$autoload[$class];
|
||||
}
|
||||
}
|
||||
|
||||
static protected function buildAutoload()
|
||||
@ -71,13 +86,16 @@ class Load
|
||||
trigger_error('Can\'t create directory: "' . $dir . '"', E_USER_ERROR);
|
||||
}
|
||||
|
||||
$scan = array(PATH . '/' . APP . '/src', PATH . '/lib');
|
||||
$exclude = array_merge(self::$exclude, array(PATH . '/.git', PATH . '/lib/core/tests', PATH . '/lib/core/.git'));
|
||||
$scan = array(PATH . '/' . APP . '/src', PATH . '/lib', PATH . '/vendor');
|
||||
$exclude = array_merge(self::$exclude, array(PATH . '/.git', PATH . '/lib/core/tests', PATH . '/lib/core/.git'));
|
||||
|
||||
require_once(PATH . '/lib/core/util/AutoloadBuilder.php');
|
||||
|
||||
$builder = new AutoloadBuilder(self::$file, $scan, $exclude);
|
||||
$builder->build();
|
||||
if (!self::$builder) {
|
||||
require_once(PATH . '/lib/core/util/AutoloadBuilder.php');
|
||||
require_once(PATH . '/lib/core/util/AsciiSortedIterator.php');
|
||||
self::$builder = new AutoloadBuilder(self::$file, $scan, $exclude);
|
||||
}
|
||||
self::$builder->build();
|
||||
ignore_user_abort(false);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Logger;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -14,8 +14,13 @@ class CliLogger extends Logger
|
||||
{
|
||||
// Заменяем окончания строк на их символы
|
||||
$message = str_replace(array("\r", "\n"), array('\r', '\n'), $message);
|
||||
$out = microtime(true) . " \t: " . $this->pid . trim($message) . PHP_EOL;
|
||||
$out = $this->generateOutString($message);
|
||||
print($out);
|
||||
}
|
||||
|
||||
protected function generateOutString($message)
|
||||
{
|
||||
return microtime(true) . " \t: " . $this->pid . trim($message) . PHP_EOL;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Logger;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -20,17 +20,22 @@ class FileLogger extends Logger
|
||||
|
||||
protected function __construct()
|
||||
{
|
||||
$this->file_path = Config::get('Logger')->filepath;
|
||||
$this->file_path = \Majestic\Config::get('Logger')->filepath;
|
||||
}
|
||||
|
||||
protected function generateOutString($message)
|
||||
{
|
||||
return microtime(true) . " \t: " . $this->pid . trim($message) . "\r\n";
|
||||
}
|
||||
|
||||
protected function concreteLog($message)
|
||||
{
|
||||
$out = microtime(true) . " \t: " . $this->pid . trim($message) . "\r\n";
|
||||
$out = $this->generateOutString($message);
|
||||
|
||||
if (!$this->handler) {
|
||||
$this->handler = @fopen($this->file_path, "a");
|
||||
if (!$this->handler) {
|
||||
throw new GeneralException('Could not open file ' . $this->file_path);
|
||||
throw new \Majestic\Exception\GeneralException('Could not open file ' . $this->file_path);
|
||||
}
|
||||
}
|
||||
fwrite($this->handler, $out);
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Logger;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -31,7 +31,7 @@ abstract class Logger
|
||||
{
|
||||
if (static::$_instance === null) {
|
||||
//$class = get_called_class();
|
||||
$class = Config::get('Logger')->logger;
|
||||
$class = \Majestic\Config::get('Logger')->logger;
|
||||
static::$_instance = new $class();
|
||||
}
|
||||
return static::$_instance;
|
||||
@ -43,7 +43,7 @@ abstract class Logger
|
||||
*/
|
||||
public function log($message)
|
||||
{
|
||||
if (Config::get('LOGGING')) {
|
||||
if (\Majestic\Config::get('LOGGING')) {
|
||||
$this->concreteLog($message);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Mail;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -29,23 +29,23 @@ class Db
|
||||
* @param array $config Configuration array.
|
||||
*
|
||||
* @return DbDriver
|
||||
* @throws InitializationException
|
||||
* @throws \Majestic\Exception\InitializationException
|
||||
*/
|
||||
static public function connect($name = 'default', $config = null)
|
||||
{
|
||||
if (!isset(self::$connections[$name])) {
|
||||
if (!$config) {
|
||||
if (!is_object(Config::get(__CLASS__))) {
|
||||
throw new InitializationException('Trying to get property of non-object');
|
||||
if (!is_object(\Majestic\Config::get(__CLASS__))) {
|
||||
throw new \Majestic\Exception\InitializationException('Trying to get property of non-object');
|
||||
}
|
||||
$config = Config::get(__CLASS__)->$name;
|
||||
$config = \Majestic\Config::get(__CLASS__)->$name;
|
||||
}
|
||||
|
||||
if (!is_array($config)) {
|
||||
throw new InitializationException('Connection parameters must be an array');
|
||||
throw new \Majestic\Exception\InitializationException('Connection parameters must be an array');
|
||||
}
|
||||
|
||||
$driver = 'MySQLiDriver';
|
||||
$driver = '\Majestic\Model\MySQLiDriver';
|
||||
if (isset($config['driver'])) {
|
||||
$driver = $config['driver'];
|
||||
unset($config['driver']);
|
||||
@ -54,7 +54,7 @@ class Db
|
||||
$connection = new $driver($config);
|
||||
|
||||
if (!$connection instanceof DbDriver) {
|
||||
throw new InitializationException('Database driver must extends DbDriver');
|
||||
throw new \Majestic\Exception\InitializationException('Database driver must extends DbDriver');
|
||||
}
|
||||
self::$connections[$name] = $connection;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -36,7 +36,7 @@ abstract class DbDriver
|
||||
$required = array('database', 'username', 'password', 'hostname');
|
||||
foreach ($required as $option) {
|
||||
if (!isset($config[$option])) {
|
||||
throw new GeneralException('Configuration must have a "' . $option . '".');
|
||||
throw new \GeneralException('Configuration must have a "' . $option . '".');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
|
||||
/**
|
||||
* Класс модели данных
|
||||
@ -23,7 +23,7 @@ abstract class Model
|
||||
/**
|
||||
* Cache instance
|
||||
*
|
||||
* @var Cache
|
||||
* @var \Cache
|
||||
*/
|
||||
protected $cache;
|
||||
|
||||
@ -94,12 +94,12 @@ abstract class Model
|
||||
/* Cache workaround */
|
||||
|
||||
/**
|
||||
* @return Cache
|
||||
* @return \Cache
|
||||
*/
|
||||
public function getCache()
|
||||
{
|
||||
if (!$this->cache) {
|
||||
$this->cache = Cacher::get(Config::get(__CLASS__, 'MemcacheCache'));
|
||||
$this->cache = \Cacher::get(\Majestic\Config::get(__CLASS__, 'MemcacheCache'));
|
||||
}
|
||||
return $this->cache;
|
||||
}
|
||||
@ -107,16 +107,16 @@ abstract class Model
|
||||
/**
|
||||
* @param string $name
|
||||
* @param array $params
|
||||
* @return CacheKey
|
||||
* @return \CacheKey
|
||||
*/
|
||||
protected function cacheKey($name, $params = array())
|
||||
{
|
||||
$expire = (isset($this->cache_keys[$name])) ? ($this->cache_keys[$name] * 60) : 0;
|
||||
return new CacheKey($this->getCache(), $name, $params, $expire);
|
||||
return new \CacheKey($this->getCache(), $name, $params, $expire);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CacheKey $cache
|
||||
* @param \CacheKey $cache
|
||||
*/
|
||||
protected function addCleanCache($cache)
|
||||
{
|
||||
@ -152,21 +152,21 @@ abstract class Model
|
||||
* @param string $data Request
|
||||
* @param array $params Request parameters
|
||||
* @param string $field Requested field name
|
||||
* @param CacheKey $cache_key Key for caching in
|
||||
* @param \CacheKey $cache_key Key for caching in
|
||||
*/
|
||||
abstract protected function fetchField($data, $params = array(), $field, $cache_key = null);
|
||||
|
||||
/**
|
||||
* @param string $data Request
|
||||
* @param array $params Request parameters
|
||||
* @param CacheKey $cache_key Key for caching in
|
||||
* @param \CacheKey $cache_key Key for caching in
|
||||
*/
|
||||
abstract protected function fetch($data, $params = array(), $cache_key = null);
|
||||
|
||||
/**
|
||||
* @param string $data
|
||||
* @param array $params
|
||||
* @param CacheKey $cache_key
|
||||
* @param \CacheKey $cache_key
|
||||
*/
|
||||
abstract protected function fetchAll($data, $params = array(), $cache_key = null);
|
||||
}
|
@ -49,14 +49,14 @@ abstract class MongoDbCommand
|
||||
* Execute Mongo command/query
|
||||
*
|
||||
* @return mixed
|
||||
* @throws GeneralException
|
||||
* @throws \Majestic\Exception\GeneralException
|
||||
*/
|
||||
public function execute()
|
||||
{
|
||||
if ($this->checkParams()) {
|
||||
return $this->concreteExecute();
|
||||
} else {
|
||||
throw new GeneralException(get_called_class() . ' error. Bind all required params first.');
|
||||
throw new \Majestic\Exception\GeneralException(get_called_class() . ' error. Bind all required params first.');
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ abstract class MongoModel extends Model
|
||||
/**
|
||||
* @param array $params Parameters for find query
|
||||
* @return array Query result sort rules
|
||||
* @throws GeneralException
|
||||
* @throws \Majestic\Exception\GeneralException
|
||||
* */
|
||||
private function getOrder($params = array())
|
||||
{
|
||||
@ -170,7 +170,7 @@ abstract class MongoModel extends Model
|
||||
} elseif (is_array($params['order'])) {
|
||||
$order = $params['order'];
|
||||
} else {
|
||||
throw new GeneralException('Wrong order parameter given to query.');
|
||||
throw new \Majestic\Exception\GeneralException('Wrong order parameter given to query.');
|
||||
}
|
||||
}
|
||||
return $order;
|
||||
@ -179,7 +179,7 @@ abstract class MongoModel extends Model
|
||||
/**
|
||||
* @param array $params Parameters for find query
|
||||
* @return array Query result sort rules
|
||||
* @throws GeneralException
|
||||
* @throws \Majestic\Exception\GeneralException
|
||||
* */
|
||||
private function getFields($params)
|
||||
{
|
||||
@ -196,7 +196,7 @@ abstract class MongoModel extends Model
|
||||
$fields = $params['fields'];
|
||||
}
|
||||
} else {
|
||||
throw new GeneralException('Wrong fields parameter given to query.');
|
||||
throw new \Majestic\Exception\GeneralException('Wrong fields parameter given to query.');
|
||||
}
|
||||
}
|
||||
return $fields;
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property MySQLi $connection
|
||||
* @property \MySQLi $connection
|
||||
*/
|
||||
class MySQLiDriver extends SqlDbDriver
|
||||
{
|
||||
@ -51,7 +51,7 @@ class MySQLiDriver extends SqlDbDriver
|
||||
|
||||
public function isConnected()
|
||||
{
|
||||
return ($this->connection instanceof MySQLi);
|
||||
return ($this->connection instanceof \MySQLi);
|
||||
}
|
||||
|
||||
public function disconnect()
|
||||
@ -78,7 +78,7 @@ class MySQLiDriver extends SqlDbDriver
|
||||
$port);
|
||||
// Connection errors check
|
||||
if (mysqli_connect_error()) {
|
||||
throw new GeneralException(mysqli_connect_error(), mysqli_connect_errno());
|
||||
throw new \Majestic\Exception\GeneralException(mysqli_connect_error(), mysqli_connect_errno());
|
||||
}
|
||||
|
||||
$charset = (!empty($this->config['charset'])) ? $this->config['charset'] : 'utf8';
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
/**
|
||||
* @property MySQLiDriver $driver
|
||||
* @property MySQLi_Result $result
|
||||
* @property \MySQLi_Result $result
|
||||
*/
|
||||
class MySQLiStatement extends DbStatement
|
||||
{
|
||||
@ -21,12 +21,12 @@ class MySQLiStatement extends DbStatement
|
||||
if ($this->map === null) {
|
||||
$this->mapPlaceholders();
|
||||
}
|
||||
if (count($this->map) > 0) {
|
||||
if (is_array($this->map) && count($this->map) > 0) {
|
||||
if (!is_string($param) && !is_int($param)) {
|
||||
throw new GeneralException('Placeholder must be an integer or string');
|
||||
throw new \Majestic\Exception\GeneralException('Placeholder must be an integer or string');
|
||||
}
|
||||
if (is_object($value) && ! ($value instanceof DbExpr)) {
|
||||
throw new GeneralException('Objects excepts DbExpr not allowed.');
|
||||
throw new \Majestic\Exception\GeneralException('Objects excepts DbExpr not allowed.');
|
||||
}
|
||||
if (isset($this->map[$param])) {
|
||||
$this->params[$param] = &$value;
|
||||
@ -38,7 +38,7 @@ class MySQLiStatement extends DbStatement
|
||||
protected function mapPlaceholders()
|
||||
{
|
||||
$matches = array();
|
||||
if(preg_match_all('/(\?|:[A-z0-9_]+)/u', $this->request, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
if(preg_match_all('/(\?|:[A-z][A-z0-9_]*+)/u', $this->request, $matches, PREG_OFFSET_CAPTURE)) {
|
||||
$noname = 0;
|
||||
foreach ($matches[0] as $id=>$match) {
|
||||
$match[2] = $matches[1][$id][0];
|
||||
@ -81,7 +81,7 @@ class MySQLiStatement extends DbStatement
|
||||
*
|
||||
* @param mixed $style
|
||||
* @return mixed
|
||||
* @throws GeneralException
|
||||
* @throws \Majestic\Exception\GeneralException
|
||||
*/
|
||||
public function fetch($style = Db::FETCH_OBJ)
|
||||
{
|
||||
@ -103,7 +103,7 @@ class MySQLiStatement extends DbStatement
|
||||
$row = $this->result->fetch_array(MYSQLI_BOTH);
|
||||
break;
|
||||
default:
|
||||
throw new GeneralException('Invalid fetch mode "' . $style . '" specified');
|
||||
throw new \Majestic\Exception\GeneralException('Invalid fetch mode "' . $style . '" specified');
|
||||
}
|
||||
return $row;
|
||||
}
|
||||
@ -150,14 +150,19 @@ class MySQLiStatement extends DbStatement
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getMysqliResult()
|
||||
{
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
protected function driverExecute($request)
|
||||
{
|
||||
/**
|
||||
* @var MySQLi
|
||||
* @var \MySQLi
|
||||
*/
|
||||
$mysqli = $this->driver->getConnection();
|
||||
if (Config::get('PROFILER_DETAILS')) {
|
||||
$profiler = Profiler::getInstance()->profilerCommand('MySQL', $request);
|
||||
if (\Majestic\Config::get('PROFILER_DETAILS')) {
|
||||
$profiler = \Majestic\Util\Profiler\Profiler::getInstance()->profilerCommand('MySQL', $request);
|
||||
$result = $mysqli->query($request);
|
||||
$profiler->end();
|
||||
} else {
|
||||
@ -165,9 +170,9 @@ class MySQLiStatement extends DbStatement
|
||||
}
|
||||
if ($result === false) {
|
||||
$message = $mysqli->error . "\nQuery: \"" . $request . '"';
|
||||
throw new GeneralException($message, $mysqli->errno);
|
||||
throw new \Majestic\Exception\GeneralException($message, $mysqli->errno);
|
||||
}
|
||||
if ($result instanceof MySQLi_Result) {
|
||||
if ($result instanceof \MySQLi_Result) {
|
||||
$this->result = $result;
|
||||
}
|
||||
return true;
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
277
Model/SqlCriteria.php
Normal file
277
Model/SqlCriteria.php
Normal file
@ -0,0 +1,277 @@
|
||||
<?php namespace Majestic\Model;
|
||||
|
||||
class SqlCriteria
|
||||
{
|
||||
const JOIN_TYPE_DEFAULT = 100;
|
||||
const JOIN_TYPE_LEFT = 101;
|
||||
const JOIN_TYPE_RIGHT = 102;
|
||||
const JOIN_TYPE_INNER = 103;
|
||||
const JOIN_TYPE_OUTER = 104;
|
||||
|
||||
private static $join_reserved_keyword = array(
|
||||
self::JOIN_TYPE_DEFAULT => 'JOIN',
|
||||
self::JOIN_TYPE_LEFT => 'LEFT JOIN',
|
||||
self::JOIN_TYPE_RIGHT => 'RIGHT JOIN',
|
||||
self::JOIN_TYPE_INNER => 'INNER JOIN',
|
||||
self::JOIN_TYPE_OUTER => 'OUTER JOIN',
|
||||
);
|
||||
|
||||
private $select = array();
|
||||
|
||||
private $distinct = '';
|
||||
|
||||
private $where = array();
|
||||
|
||||
private $group_by = array();
|
||||
|
||||
private $order = array('sort' => array(), 'order' => array());
|
||||
|
||||
private $limit = '';
|
||||
|
||||
/**
|
||||
* @var SqlModel
|
||||
*/
|
||||
private $model;
|
||||
|
||||
private $sql_expression;
|
||||
|
||||
private $sql_expression_params = array();
|
||||
|
||||
private $sql_join_expressions = array();
|
||||
|
||||
private $join_table_placeholder = array();
|
||||
|
||||
/**
|
||||
* @param $model SqlModel
|
||||
* @param $sql_expression string|null Sql expression with SELECT and FROM operators. If fetched, then SqlCriteria::select(), SqlCriteria::distinct() disabled for use.
|
||||
* @param $sql_expression_params array additional params to be replaced in sql expression
|
||||
*/
|
||||
public function __construct($model, $sql_expression = null, $sql_expression_params = array())
|
||||
{
|
||||
$this->model = $model;
|
||||
$this->sql_expression = $sql_expression;
|
||||
$this->sql_expression_params = $sql_expression_params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SqlResultProvider
|
||||
*/
|
||||
public function find()
|
||||
{
|
||||
$this->defineJoinExpressions();
|
||||
return $this->model->find($this->select, $this->distinct, $this->where, $this->order, $this->limit, null, $this->group_by, $this->sql_expression, $this->sql_expression_params);
|
||||
}
|
||||
|
||||
private function defineJoinExpressions($select = null)
|
||||
{
|
||||
if ($this->sql_join_expressions) {
|
||||
if (!$this->sql_expression) {
|
||||
$select = $this->model->getDb()->selectExpr($select ? : $this->select, $this->distinct);
|
||||
$this->sql_expression = 'SELECT ' . $select . ' FROM :table';
|
||||
}
|
||||
$this->sql_expression .= ' ' . implode(' ', $this->sql_join_expressions);
|
||||
$this->sql_join_expressions = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function delete()
|
||||
{
|
||||
return $this->model->find('', '', $this->where, null, null, null, null, 'DELETE FROM :table', $this->sql_expression_params)->affectedRows();
|
||||
}
|
||||
|
||||
//TODO: перенести определение sql_expression в модель
|
||||
public function count($select = null)
|
||||
{
|
||||
$this->defineJoinExpressions($select);
|
||||
$sql_expression_backup = $this->sql_expression;
|
||||
$group_by_backup = $this->group_by;
|
||||
$select_parent_query = 'COUNT(*) as count';
|
||||
$default_select = '*';
|
||||
if ($this->group_by) {
|
||||
$default_select = 'DISTINCT ' . $this->group_by[0];
|
||||
}
|
||||
$this->group_by = [];
|
||||
if (!$this->sql_expression) {
|
||||
$this->sql_expression = 'SELECT COUNT(' . ($select ? $select : $default_select) . ') as count FROM :table';
|
||||
$select_parent_query = 'x.count';
|
||||
} else {
|
||||
$this->sql_expression = preg_replace('#SELECT.+FROM#i', 'SELECT COUNT(' . ($select ? $select : $default_select) . ') as count FROM', $this->sql_expression);
|
||||
}
|
||||
$count = $this->model->count($select_parent_query, $this->where, null, $this->group_by, $this->sql_expression, $this->sql_expression_params)->fetchField('count');
|
||||
$this->sql_expression = $sql_expression_backup;
|
||||
$this->group_by = $group_by_backup;
|
||||
return $count;
|
||||
}
|
||||
|
||||
private function defineJoinTablePlaceholder($table_name)
|
||||
{
|
||||
if (!isset($this->join_table_placeholder[$table_name])) {
|
||||
$this->join_table_placeholder[$table_name] = ':table' . (count($this->join_table_placeholder) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function getTablePh($table_name)
|
||||
{
|
||||
$this->defineJoinTablePlaceholder($table_name);
|
||||
return $this->join_table_placeholder[$table_name];
|
||||
}
|
||||
|
||||
public function join($join_table_name, $join_field_name, $donor_table_name = null, $donor_field_name = null, $join_type = self::JOIN_TYPE_DEFAULT)
|
||||
{
|
||||
$donor_field_name = $donor_field_name ? : $join_field_name;
|
||||
$donor_table_placeholder = $donor_table_name ? $this->getTablePh($donor_table_name) : ':table';
|
||||
$join_table_placeholder = $this->getTablePh($join_table_name);
|
||||
$this->sql_join_expressions[] = self::$join_reserved_keyword[$join_type]
|
||||
. ' ' . $join_table_placeholder
|
||||
. ' ON ' . $donor_table_placeholder . '.' . $donor_field_name . '='
|
||||
. ' ' . $join_table_placeholder . '.' . $join_field_name;
|
||||
if ($donor_table_name) {
|
||||
$this->sql_expression_params[substr($donor_table_placeholder, 1)] = new DbExpr($this->model->identify($donor_table_name));
|
||||
}
|
||||
$this->sql_expression_params[substr($join_table_placeholder, 1)] = new DbExpr($this->model->identify($join_table_name));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $cond string|array Condition with "?" placeholder @ex 'field=?' or 'field=1' or array('field=?' => 1', 'field=1')
|
||||
* @param $value string|array|DbExpr|null Value. Array transformed to DbExpr(implode(',' Array)) All elements in the array mast be integer
|
||||
* @return SqlCriteria
|
||||
* @desc Allow multiple calls
|
||||
*/
|
||||
public function where($cond, $value = null)
|
||||
{
|
||||
if (is_null($value)) {
|
||||
if (is_array($cond)) {
|
||||
$this->where = $this->where + $cond;
|
||||
} else {
|
||||
$this->where[] = $cond;
|
||||
}
|
||||
} else {
|
||||
$this->where[$cond] = $value;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function whereJoin($join_table_name, $cond, $value = null)
|
||||
{
|
||||
$join_table_placeholder = $this->getTablePh($join_table_name);
|
||||
if (is_array($cond)) {
|
||||
$cond_replace = array();
|
||||
foreach ($cond as $key => $value) {
|
||||
$cond_replace[$this->getCondWithTablePlaceholderIfNeed($join_table_placeholder, $key)] = $value;
|
||||
}
|
||||
} else {
|
||||
$cond = $this->getCondWithTablePlaceholderIfNeed($join_table_placeholder, $cond);
|
||||
}
|
||||
return $this->where($cond, $value);
|
||||
}
|
||||
|
||||
private function getCondWithTablePlaceholderIfNeed($table_placeholder, $cond)
|
||||
{
|
||||
if (!strstr('.', $cond)) {
|
||||
$cond = $table_placeholder . '.' . $cond;
|
||||
}
|
||||
return $cond;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field string
|
||||
* @param $value array
|
||||
* @return SqlCriteria
|
||||
*/
|
||||
public function whereIn($field, $value)
|
||||
{
|
||||
return $this->where($field . ' in ?', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field string
|
||||
* @param $value array
|
||||
* @return SqlCriteria
|
||||
*/
|
||||
public function whereNotIn($field, $value)
|
||||
{
|
||||
return $this->where($field . ' not in ?', $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field string
|
||||
* @param $value array
|
||||
* @return SqlCriteria
|
||||
* @deprecated
|
||||
*/
|
||||
public function whereNot($field, $value)
|
||||
{
|
||||
return $this->whereNotIn($field, $value);
|
||||
}
|
||||
|
||||
public function groupBy($fields)
|
||||
{
|
||||
if (is_array($fields)) {
|
||||
$this->group_by = $this->group_by + $fields;
|
||||
} else {
|
||||
$this->group_by[] = $fields;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field string Field @ex 'field'
|
||||
* @param $order_desc bool Descendant sort direction
|
||||
* @return SqlCriteria
|
||||
* @desc Allow multiple calls
|
||||
*/
|
||||
public function order($field, $order_desc = false)
|
||||
{
|
||||
$this->order['sort'][] = $field;
|
||||
if ($order_desc) {
|
||||
$this->order['order'][$field] = 'desc';
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $offset int
|
||||
* @param $limit int
|
||||
* @return SqlCriteria
|
||||
*/
|
||||
public function limit($offset = 0, $limit)
|
||||
{
|
||||
if ($offset) {
|
||||
$this->limit = (int) $offset . ',';
|
||||
}
|
||||
$this->limit .= (int) $limit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $fields
|
||||
* @param bool $convert_to_db_expression
|
||||
* @ex SqlCriteria::select('field')
|
||||
* @ex SqlCriteria->select(array('field1', 'field2'))
|
||||
* @ex SqlCriteria->select('field1,field2')
|
||||
* @return SqlCriteria
|
||||
*/
|
||||
public function select($fields, $convert_to_db_expression = false)
|
||||
{
|
||||
if (!is_array($fields)) {
|
||||
$fields = explode(',', $fields);
|
||||
}
|
||||
$fields = array_map(function($item){return trim($item);},$fields);
|
||||
if ($convert_to_db_expression) {
|
||||
$fields = array_map(function($item){return new DbExpr($item);},$fields);
|
||||
}
|
||||
$this->select = array_merge($this->select,$fields);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field string|bool If true then distinct by *
|
||||
* @return SqlCriteria
|
||||
*/
|
||||
public function distinct($field)
|
||||
{
|
||||
$this->distinct = $field;
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -110,7 +110,9 @@ abstract class SqlDbDriver extends DbDriver
|
||||
{
|
||||
$ident = explode('.', $ident);
|
||||
foreach ($ident as &$segment) {
|
||||
$segment = $this->identifier_quote . $segment . $this->identifier_quote;
|
||||
if (!preg_match('/^(\?|:[A-z][A-z0-9_]*+|\*)$/u', $segment)) {
|
||||
$segment = $this->identifier_quote . $segment . $this->identifier_quote;
|
||||
}
|
||||
}
|
||||
return implode('.', $ident);
|
||||
}
|
||||
@ -127,8 +129,9 @@ abstract class SqlDbDriver extends DbDriver
|
||||
/**
|
||||
* @param mixed $where
|
||||
* @return string
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
protected function whereExpr($where)
|
||||
public function whereExpr($where)
|
||||
{
|
||||
if (empty($where)) {
|
||||
return $where;
|
||||
@ -139,16 +142,88 @@ abstract class SqlDbDriver extends DbDriver
|
||||
}
|
||||
foreach ($where as $cond => &$term) {
|
||||
if (is_int($cond)) {
|
||||
if (is_int($term)) {
|
||||
throw new \ErrorException('Condition in where expression as integer. ' . $term);
|
||||
}
|
||||
if ($term instanceof DbExpr) {
|
||||
$term = (string) $term;
|
||||
}
|
||||
} else {
|
||||
if (is_array($term)) {
|
||||
foreach ($term as &$val) {
|
||||
$val = $this->driverQuote($val);
|
||||
}
|
||||
$term = new DbExpr('(' . implode(',', $term) . ')');
|
||||
}
|
||||
$term = $this->quoteInto($cond, $term);
|
||||
}
|
||||
}
|
||||
return implode(' AND ', $where);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $group_by
|
||||
* @return string
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function groupByExpr($group_by)
|
||||
{
|
||||
if (empty($group_by)) {
|
||||
return $group_by;
|
||||
}
|
||||
|
||||
if (!is_array($group_by)) {
|
||||
$group_by = array($group_by);
|
||||
}
|
||||
foreach ($group_by as &$term) {
|
||||
if ($term instanceof DbExpr) {
|
||||
$term = (string) $term;
|
||||
} else {
|
||||
$term = $this->quoteIdentifier($term);
|
||||
}
|
||||
}
|
||||
return implode(',', $group_by);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $select array
|
||||
* @param $distinct string|bool
|
||||
* @return string
|
||||
*/
|
||||
public function selectExpr($select, $distinct = false)
|
||||
{
|
||||
if (empty($distinct) && empty($select)) {
|
||||
return '*';
|
||||
}
|
||||
if (!is_array($select)) {
|
||||
$select = array($select);
|
||||
}
|
||||
if ($distinct) {
|
||||
$distinct = ((is_bool($distinct)) ? '*' : $this->quoteIdentifier($distinct));
|
||||
array_unshift($select, new DbExpr('DISTINCT ' . $distinct));
|
||||
}
|
||||
foreach ($select as $field => &$term) {
|
||||
if (is_int($field)) {
|
||||
if ($term instanceof DbExpr) {
|
||||
$term = (string) $term;
|
||||
} else {
|
||||
$term = $this->quoteIdentifier($term);
|
||||
}
|
||||
} else {
|
||||
$term = $this->quoteIdentifier($field) . ' as ' . $this->quoteIdentifier($term);
|
||||
}
|
||||
}
|
||||
return implode(',', $select);
|
||||
}
|
||||
|
||||
public function limitExpr($limit)
|
||||
{
|
||||
if (empty($limit)) {
|
||||
return $limit;
|
||||
}
|
||||
return implode(',',array_map(function($item){return intval($item);},explode(',',$limit)));
|
||||
}
|
||||
|
||||
abstract protected function driverQuote($value);
|
||||
|
||||
abstract protected function driverBeginTransaction();
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Model;
|
||||
|
||||
/**
|
||||
* Класс модели данных
|
||||
@ -15,7 +15,6 @@
|
||||
*/
|
||||
abstract class SqlModel extends Model
|
||||
{
|
||||
|
||||
/**
|
||||
* @param string $ident
|
||||
* @return string Quoted identifier.
|
||||
@ -34,6 +33,11 @@ abstract class SqlModel extends Model
|
||||
return $this->db->quote($value);
|
||||
}
|
||||
|
||||
public function getDb()
|
||||
{
|
||||
return $this->db;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @return object
|
||||
@ -51,8 +55,8 @@ abstract class SqlModel extends Model
|
||||
*/
|
||||
public function update($data, $where)
|
||||
{
|
||||
if (is_int($where) || $where === (string) (int) $where) {
|
||||
$where = $this->identify($this->key) . '=' . (int) $where;
|
||||
if (is_int($where) || $where === (string)(int)$where) {
|
||||
$where = $this->identify($this->key) . '=' . (int)$where;
|
||||
}
|
||||
return parent::update($data, $where);
|
||||
}
|
||||
@ -63,7 +67,7 @@ abstract class SqlModel extends Model
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
$where = $this->identify($this->key) . '=' . (int) $id;
|
||||
$where = $this->identify($this->key) . '=' . (int)$id;
|
||||
return $this->db->delete($this->table(), $where);
|
||||
}
|
||||
|
||||
@ -78,9 +82,21 @@ abstract class SqlModel extends Model
|
||||
{
|
||||
$sql = '';
|
||||
if (isset($params['sort'])) {
|
||||
$order = (isset($params['order']) && $params['order'] == 'desc') ? 'DESC' : 'ASC';
|
||||
if (in_array($params['sort'], $sortable)) {
|
||||
$sql = ' ORDER BY ' . $this->identify($params['sort']) . ' ' . $order;
|
||||
if (!is_array($params['sort'])) {
|
||||
if (isset($params['order'])) {
|
||||
$params['order'] = array($params['sort'] => $params['order']);
|
||||
}
|
||||
$params['sort'] = array($params['sort']);
|
||||
}
|
||||
$order_list = array();
|
||||
for ($i = 0; $i < count($params['sort']); $i++) {
|
||||
$order = (isset($params['order'][$params['sort'][$i]]) && $params['order'][$params['sort'][$i]] == 'desc') ? 'DESC' : 'ASC';
|
||||
if (in_array($params['sort'][$i], $sortable)) {
|
||||
$order_list[] = $this->identify($params['sort'][$i]) . ' ' . $order;
|
||||
}
|
||||
}
|
||||
if ($order_list) {
|
||||
$sql = ' ORDER BY ' . implode(',', $order_list);
|
||||
}
|
||||
}
|
||||
return $sql;
|
||||
@ -101,7 +117,7 @@ abstract class SqlModel extends Model
|
||||
if ($table_prefix) {
|
||||
$sql = $table_prefix . '.';
|
||||
}
|
||||
$sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%');
|
||||
$sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%');
|
||||
}
|
||||
return $sql;
|
||||
}
|
||||
@ -178,4 +194,60 @@ abstract class SqlModel extends Model
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $select array
|
||||
* @param $distinct string|bool
|
||||
* @param $where array @ex array('field=?' => $value, 'field=1')
|
||||
* @param $order array @ex array('sort' => array('field1', 'field2'), 'order' => array('field2' => 'desc'))
|
||||
* @param $limit string @ex '30' or '30,30'
|
||||
* @param $heaving TODO
|
||||
* @param $group_by TODO
|
||||
* @param $sql_expression null|string
|
||||
* @param $sql_expression_params array
|
||||
* @param $cache_key CacheKey|null
|
||||
* @return SqlResultProvider
|
||||
*/
|
||||
public function find($select, $distinct, $where, $order, $limit, $heaving = null, $group_by = null, $sql_expression = null, $sql_expression_params = array(), $cache_key = null)
|
||||
{
|
||||
$select = $this->db->selectExpr($select, $distinct);
|
||||
$where = $this->db->whereExpr($where);
|
||||
$group_by = $this->db->groupByExpr($group_by);
|
||||
$order = isset($order['sort']) ? $this->order($order, $order['sort']) : false;
|
||||
$limit = $this->db->limitExpr($limit);
|
||||
$result = $this->query(
|
||||
(($sql_expression) ? $sql_expression : ('SELECT ' . $select . ' FROM ' . $this->identify($this->table())))
|
||||
. (($where) ? (' WHERE ' . $where) : '')
|
||||
. (($group_by) ? (' GROUP BY ' . $group_by) : '')
|
||||
. (($order) ? ($order) : '')
|
||||
. (($limit) ? (' LIMIT ' . $limit) : ''),
|
||||
$sql_expression_params,
|
||||
$cache_key
|
||||
);
|
||||
return new SqlResultProvider($result);
|
||||
}
|
||||
|
||||
public function count($select_parent_query = 'x.count', $where, $heaving = null, $group_by = null, $sql_expression = null, $sql_expression_params = array(), $cache_key = null)
|
||||
{
|
||||
$where = $this->db->whereExpr($where);
|
||||
$group_by = $this->db->groupByExpr($group_by);
|
||||
$result = $this->query(
|
||||
'SELECT (' .
|
||||
(($sql_expression) ? $sql_expression : ('SELECT * FROM ' . $this->identify($this->table())))
|
||||
. (($where) ? (' WHERE ' . $where) : '')
|
||||
. (($group_by) ? (' GROUP BY ' . $group_by) : '') . ' LIMIT 1) AS count',
|
||||
$sql_expression_params,
|
||||
$cache_key
|
||||
);
|
||||
return new SqlResultProvider($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $sql_expression null
|
||||
* @param $sql_expression_params array
|
||||
* @return SqlCriteria
|
||||
*/
|
||||
public function criteria($sql_expression = null, $sql_expression_params = array())
|
||||
{
|
||||
return new SqlCriteria($this, $sql_expression, $sql_expression_params);
|
||||
}
|
||||
}
|
61
Model/SqlResultCollection.php
Normal file
61
Model/SqlResultCollection.php
Normal file
@ -0,0 +1,61 @@
|
||||
<?php namespace Majestic\Model;
|
||||
|
||||
use Illuminate\Contracts\Support\Arrayable;
|
||||
|
||||
class SqlResultCollection extends \ArrayIterator implements iSqlResultItems, Arrayable
|
||||
{
|
||||
private $items;
|
||||
|
||||
public function __construct($items)
|
||||
{
|
||||
$this->items = $items;
|
||||
foreach ($items as $item) {
|
||||
parent::append($item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DbStatement[]
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
return (array) $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchField($field)
|
||||
{
|
||||
$item = $this->offsetGet(0);
|
||||
return $item->{$field};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetch()
|
||||
{
|
||||
return $this->offsetGet(0);
|
||||
}
|
||||
|
||||
public function assoc($field, $assoc_as_array = false) {
|
||||
$sql_result_provider = new SqlResultProvider($this->items);
|
||||
return $sql_result_provider->assoc($field, $assoc_as_array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the collection of items as a plain array.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function toArray()
|
||||
{
|
||||
return array_map(function($value)
|
||||
{
|
||||
return $value instanceof ArrayableInterface ? $value->toArray() : $value;
|
||||
|
||||
}, $this->items);
|
||||
}
|
||||
}
|
131
Model/SqlResultProvider.php
Normal file
131
Model/SqlResultProvider.php
Normal file
@ -0,0 +1,131 @@
|
||||
<?php namespace Majestic\Model;
|
||||
|
||||
class SqlResultProvider implements iSqlResultItems
|
||||
{
|
||||
/**
|
||||
* @var DbStatement
|
||||
*/
|
||||
private $result;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @desc my be changed in assoc method
|
||||
*/
|
||||
private $result_items;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $result_items_base;
|
||||
|
||||
/**
|
||||
* @param $result DbStatement|array
|
||||
*/
|
||||
public function __construct($result)
|
||||
{
|
||||
$this->result = $result;
|
||||
}
|
||||
|
||||
private function defineResultItems()
|
||||
{
|
||||
if (is_null($this->result_items_base)) {
|
||||
if (is_array($this->result)) {
|
||||
$this->result_items_base = $this->result;
|
||||
} else {
|
||||
$this->result_items_base = $this->result->fetchAll();
|
||||
}
|
||||
$this->result_items = $this->result_items_base;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field string
|
||||
* @param bool $assoc_as_array
|
||||
* @return $this SqlResultProvider
|
||||
* @throws \ErrorException
|
||||
*/
|
||||
public function assoc($field, $assoc_as_array = false)
|
||||
{
|
||||
$this->defineResultItems();
|
||||
$result_items_assoc = array();
|
||||
foreach ($this->result_items_base as $item) {
|
||||
if (!property_exists($item, $field)) {
|
||||
throw new \ErrorException('Undefined field. ' . $field);
|
||||
}
|
||||
if ($assoc_as_array) {
|
||||
if (!isset($result_items_assoc[$item->{$field}])) {
|
||||
$result_items_assoc[$item->{$field}] = array();
|
||||
}
|
||||
$result_items_assoc[$item->{$field}][] = $item;
|
||||
} else {
|
||||
if (isset($result_items_assoc[$item->{$field}])) {
|
||||
throw new \ErrorException('Field not unique. May be use assoc_as_array. ' . $field);
|
||||
}
|
||||
$result_items_assoc[$item->{$field}] = $item;
|
||||
}
|
||||
}
|
||||
// Ассоциирование внутри каждого элемента массива
|
||||
if ($assoc_as_array) {
|
||||
foreach ($result_items_assoc as &$value) {
|
||||
$value = new SqlResultCollection($value);
|
||||
}
|
||||
}
|
||||
$this->result_items = $result_items_assoc;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getKeys()
|
||||
{
|
||||
$this->defineResultItems();
|
||||
return array_keys($this->result_items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $key
|
||||
* @return mixed
|
||||
* метод актуален после вызова assoc
|
||||
*/
|
||||
public function fetchKey($key)
|
||||
{
|
||||
return $this->result_items[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DbStatement[]|SqlResultCollection[]
|
||||
*/
|
||||
public function fetchAll()
|
||||
{
|
||||
$this->defineResultItems();
|
||||
return $this->result_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $field
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetchField($field)
|
||||
{
|
||||
if ($this->result->numRows())
|
||||
{
|
||||
return $this->result->fetchField($field);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function fetch()
|
||||
{
|
||||
return $this->result->fetch(Db::FETCH_OBJ);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function affectedRows()
|
||||
{
|
||||
return $this->result->affectedRows();
|
||||
}
|
||||
}
|
10
Model/iSqlResultItems.php
Normal file
10
Model/iSqlResultItems.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php namespace Majestic\Model;
|
||||
|
||||
interface iSqlResultItems
|
||||
{
|
||||
public function fetchAll();
|
||||
|
||||
public function fetchField($field);
|
||||
|
||||
public function fetch();
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Redis;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Redis;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -23,21 +23,21 @@ class RedisManager
|
||||
* @param string $name connection name. If not set 'default' will be used.
|
||||
* @param array $config Configuration array.
|
||||
*
|
||||
* @throws GeneralException
|
||||
* @throws \Majestic\Exception\GeneralException
|
||||
* @return Redis
|
||||
*/
|
||||
static public function connect($name = 'default', $config = null)
|
||||
{
|
||||
if (!isset(self::$connections[$name])) {
|
||||
if (!$config) {
|
||||
if (!is_object(Config::get('Redis'))) {
|
||||
throw new GeneralException('Redis config no existence');
|
||||
if (!is_object(\Majestic\Config::get('Redis'))) {
|
||||
throw new \Majestic\Exception\GeneralException('Redis config no existence');
|
||||
}
|
||||
$config = Config::get('Redis')->$name;
|
||||
$config = \Majestic\Config::get('Redis')->$name;
|
||||
}
|
||||
|
||||
if (!is_array($config)) {
|
||||
throw new GeneralException('Connection parameters must be an array');
|
||||
throw new \Majestic\Exception\GeneralException('Connection parameters must be an array');
|
||||
}
|
||||
|
||||
$host = isset($config['host']) ? $config['host'] : 'localhost';
|
||||
@ -47,16 +47,16 @@ class RedisManager
|
||||
/**
|
||||
* @var Redis
|
||||
*/
|
||||
$connection = new Redis();
|
||||
if (Config::get('PROFILER_DETAILS')) {
|
||||
$connection = new \Redis();
|
||||
if (\Majestic\Config::get('PROFILER_DETAILS')) {
|
||||
$connection = new RedisDebug($connection);
|
||||
}
|
||||
if (!$connection->connect($host, $port)) {
|
||||
throw new GeneralException('Failed to connect to Redis server at ' . $host . ':' . $port);
|
||||
throw new \Majestic\Exception\GeneralException('Failed to connect to Redis server at ' . $host . ':' . $port);
|
||||
}
|
||||
if ($database) {
|
||||
if (!$connection->select($database)) {
|
||||
throw new GeneralException('Failed to select Redis database with index ' . $database);
|
||||
throw new \Majestic\Exception\GeneralException('Failed to select Redis database with index ' . $database);
|
||||
}
|
||||
}
|
||||
self::$connections[$name] = $connection;
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Redis;
|
||||
/**
|
||||
*
|
||||
*
|
||||
@ -49,6 +49,21 @@
|
||||
* @method float zScore() zScore(string $key, string $value) Returns the score of a given member in the specified sorted set.
|
||||
* @method float zUnionStore() zUnionStore(string $destination, array $keys, array $weights = array(), string $aggregate = 'sum') Creates an union of sorted sets given in second argument and store in in first argument
|
||||
* @method float zInterStore() zInterStore(string $destination, array $keys, array $weights = array(), string $aggregate = 'sum') Creates an intersection of sorted sets given in second argument and store in in first argument
|
||||
* @method int sAdd() sAdd(string $key, string $value) Adds a value to the set value stored at key. If this value is already in the set, FALSE is returned.
|
||||
* @method int sCard() sCard(string $key) Returns the cardinality of the set identified by key.
|
||||
* @method int sSize() sSize(string $key) Returns the cardinality of the set identified by key.
|
||||
* @method array sMembers() sMembers(string $key) Returns the contents of a set.
|
||||
* @method array sGetMembers() sGetMembers(string $key) Returns the contents of a set.
|
||||
* @method bool sContains() sContains(string $key, string $value) Checks if value is a member of the set stored at the key key.
|
||||
* @method bool sIsMember() sIsMember(string $key, string $value) Checks if value is a member of the set stored at the key key.
|
||||
* @method bool sRem() sRem(string $key, string $member) Removes the specified member from the set value stored at key.
|
||||
* @method bool sRemove() sRemove(string $key, string $member) Removes the specified member from the set value stored at key.
|
||||
* @method array lRange() lRange(string $key, int $start, int $end) Returns the specified elements of the list stored at the specified key in the range [start, end]. start and stop are interpretated as indices: 0 the first element, 1 the second ... -1 the last element, -2 the penultimate
|
||||
* @method int rPush() rPush(string $key, string $value) Adds the string value to the tail (right) of the list. Creates the list if the key didn't exist. If the key exists and is not a list, FALSE is returned.
|
||||
* @method array lTrim() lTrim(string $key, int $start, int $stop) Trims an existing list so that it will contain only a specified range of elements.
|
||||
* @method array sInter
|
||||
* @method bool hSet() hSet(string $key, string $hashKey, string $value) Adds a value to the hash stored at key. If this value is already in the hash, FALSE is returned.
|
||||
* @method bool hGet() hGet(string $key, string $hashKey) Gets a value from the hash stored at key. If the hash table doesn't exist, or the key doesn't exist, FALSE is returned.
|
||||
*/
|
||||
class Redis
|
||||
{
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -7,7 +7,7 @@
|
||||
* @since 2010-02-17
|
||||
*/
|
||||
|
||||
class Registry extends ArrayObject
|
||||
class Registry extends \ArrayObject
|
||||
{
|
||||
/**
|
||||
* Class name of the singleton registry object.
|
||||
@ -42,7 +42,7 @@ class Registry extends ArrayObject
|
||||
}
|
||||
|
||||
/**
|
||||
* @codeCoverageIgnoreStart
|
||||
* @codeCoverageIgnoreEnd
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -53,7 +53,7 @@ class Registry extends ArrayObject
|
||||
public static function getInstance()
|
||||
{
|
||||
if (self::$_registry === null) {
|
||||
self::$_registry = new self::$_class_name();
|
||||
self::$_registry = new \Majestic\Registry();
|
||||
}
|
||||
return self::$_registry;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php namespace Majestic\Session;
|
||||
/**
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
@ -178,7 +178,7 @@ class Session
|
||||
return;
|
||||
}
|
||||
self::$started = true;
|
||||
session_start();
|
||||
@session_start();
|
||||
}
|
||||
|
||||
/**
|
@ -36,7 +36,6 @@ class LoadTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @TODO: Load->buildAutoload() should recieve AutoloadBuilder as a parameter
|
||||
* @TODO: Load->buildAutoload() - uses two paths - PATH . '/' . APP . '/src' and PATH . '/lib' those are not checked. Can cause error.
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
@ -113,7 +112,6 @@ class LoadTest extends PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
* @TODO: Load - check if input file returns array
|
||||
*/
|
||||
public function testFileForArray()
|
||||
{
|
||||
@ -142,7 +140,6 @@ class LoadTest extends PHPUnit_Framework_TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO: Load::getFilePath - check for wrong index
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testAutoloadGetFilePathNullIndex()
|
||||
@ -160,6 +157,7 @@ class LoadTest extends PHPUnit_Framework_TestCase
|
||||
public function testDebugAutoload()
|
||||
{
|
||||
$this->setConstants();
|
||||
unlink(self::$file);
|
||||
Load::setAutoloadFrom(self::$file);
|
||||
|
||||
$autoload = require(self::$file);
|
@ -28,6 +28,7 @@ require_once dirname(__FILE__) . '/../../app/AjaxAction.php';
|
||||
|
||||
class FrontControllerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $log_file_name = 'error_log_file';
|
||||
|
||||
public function run(PHPUnit_Framework_TestResult $result = NULL)
|
||||
{
|
||||
@ -132,8 +133,6 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$this->setConstants(false);
|
||||
$controller = FrontController::getInstance();
|
||||
$result = $controller->execute();
|
||||
$controller = FrontController::getInstance();
|
||||
$this->assertNull($controller->execute());
|
||||
}
|
||||
|
||||
@ -143,11 +142,14 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
|
||||
public function testExecuteNoRouteDebug()
|
||||
{
|
||||
$this->setConstants(true);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
$controller = FrontController::getInstance();
|
||||
$result = $controller->execute();
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertContains('Route for "" not found', $result);
|
||||
$this->assertContains('Error404Exception', $result);
|
||||
$error = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Unknown Error: Error404Exception: Route for "" not found in ', $error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,11 +159,14 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/user/account/213';
|
||||
$this->setConstants(true);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
$controller = FrontController::getInstance();
|
||||
$router = $controller->getRouter();
|
||||
$router->add('user', 'user/account/:id', 'user');
|
||||
$result = $controller->execute();
|
||||
$this->assertContains('Action class "userAction" not found.', $result);
|
||||
$error = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Unknown Error: GeneralException: Action class "userAction" not found. in ', $error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,11 +177,14 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
|
||||
$this->getMock('userAction');
|
||||
$_SERVER['REQUEST_URI'] = '/user/account/213';
|
||||
$this->setConstants(true);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
$controller = FrontController::getInstance();
|
||||
$router = $controller->getRouter();
|
||||
$router->add('user', 'user/account/:id', 'user');
|
||||
$result = $controller->execute();
|
||||
$this->assertContains('Layout class "DefaultLayout" not found.', $result);
|
||||
$error = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Unknown Error: GeneralException: Layout class "DefaultLayout" not found. in ', $error);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -269,6 +277,10 @@ class FrontControllerTest extends PHPUnit_Framework_TestCase
|
||||
public function tearDown()
|
||||
{
|
||||
unset_new_overload();
|
||||
if (file_exists($this->log_file_name) && is_writable($this->log_file_name)) {
|
||||
unlink($this->log_file_name);
|
||||
}
|
||||
ini_set('error_log', 'php://stderr');
|
||||
}
|
||||
|
||||
protected function newCallback($className)
|
179
Tests/exception/ErrorHandlerTest.php
Normal file
179
Tests/exception/ErrorHandlerTest.php
Normal file
@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright NetMonsters <team@netmonsters.ru>
|
||||
* @link http://netmonsters.ru
|
||||
* @package Majestic
|
||||
* @subpackage UnitTests
|
||||
* @since 2011-10-11
|
||||
*
|
||||
* Unit tests for ErrorHandler class
|
||||
*/
|
||||
|
||||
require_once dirname(__FILE__) . '/../../classes/Env.class.php';
|
||||
require_once dirname(__FILE__) . '/../../session/Session.php';
|
||||
require_once dirname(__FILE__) . '/../../exception/ErrorHandler.php';
|
||||
|
||||
class ErrorHandlerTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public $old_eh = array('PHPUnit_Util_ErrorHandler', 'handleError');
|
||||
|
||||
protected $log_file_name = 'error_log_file';
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
set_error_handler(array('ErrorHandler', 'error_handler'));
|
||||
ob_start();
|
||||
}
|
||||
|
||||
public function testErrorHandlerInit()
|
||||
{
|
||||
$my_eh = array('ErrorHandler', 'error_handler');
|
||||
ErrorHandler::init();
|
||||
$eh = set_error_handler($my_eh);
|
||||
$this->assertInternalType('array', $eh);
|
||||
$this->assertSame($eh, $my_eh);
|
||||
}
|
||||
|
||||
public function testHandleError()
|
||||
{
|
||||
$this->setExpectedException('ErrorException', 'test error');
|
||||
trigger_error("test error", E_USER_ERROR);
|
||||
}
|
||||
|
||||
public function testHandleAt()
|
||||
{
|
||||
$my_eh = array('ErrorHandler', 'error_handler');
|
||||
ErrorHandler::init();
|
||||
set_error_handler($my_eh);
|
||||
$var = '';
|
||||
$ok = @$var['some'];
|
||||
$this->assertSame('', $var);
|
||||
ob_start();
|
||||
$this->setExpectedException('ErrorException');
|
||||
$ex = $var['some'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO: ErrorHandler->wrapTrace() not used
|
||||
*/
|
||||
public function testShowDebug()
|
||||
{
|
||||
try {
|
||||
throw new ErrorException("test error", E_USER_ERROR);
|
||||
}
|
||||
catch (ErrorException $e) {
|
||||
$_SESSION['some'] = 'value';
|
||||
$result = ErrorHandler::showDebug($e);
|
||||
$this->assertNotEmpty($result);
|
||||
$this->assertStringStartsWith('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', $result);
|
||||
$this->assertStringEndsWith('</html>', $result);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO: ErrorHandler::wrapTrace not used
|
||||
* @TODO: nl2br() adds html <br /> but leaves original linebreak line \n
|
||||
*/
|
||||
public function testWrapTrace()
|
||||
{
|
||||
$class = new ReflectionClass('ErrorHandler');
|
||||
$method = $class->getMethod('WrapTrace');
|
||||
$method->setAccessible(true);
|
||||
$result = $method->invoke(null, "first line\nsecond line");
|
||||
$this->assertSame("<code>first line<br />\nsecond line</code>", $result);
|
||||
$result = $method->invoke(null, "first line\r\nsecond line");
|
||||
$this->assertSame("<code>first line<br />\r\nsecond line</code>", $result);
|
||||
$result = $method->invoke(null, "first line\r\n\r\nsecond line");
|
||||
$this->assertSame("<code>first line<br />\r\n<br />\r\nsecond line</code>", $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testLogErrorDefaultException()
|
||||
{
|
||||
$ex = new Exception('message', 123);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
ErrorHandler::logError($ex);
|
||||
$log = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Unknown Error: Exception: message in ', $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testLogErrorDefaultExceptionWithHTTP()
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['REQUEST_URI'] = '/somelongurl';
|
||||
$_SERVER['HTTP_REFERER'] = 'http://referrer/url';
|
||||
$this->assertEquals('GET', ENV::Server('REQUEST_METHOD'));
|
||||
$this->assertEquals('/somelongurl', ENV::Server('REQUEST_URI'));
|
||||
$this->assertEquals('http://referrer/url', ENV::Server('HTTP_REFERER'));
|
||||
|
||||
$ex = new Exception('message', 123);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
ErrorHandler::logError($ex);
|
||||
$log = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Unknown Error: Exception: message in ', $log);
|
||||
$this->assertContains('URL: GET /somelongurl, referrer: http://referrer/url', $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testLogErrorCustomException()
|
||||
{
|
||||
$ex = new LogicException('Logic', 333);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
ErrorHandler::logError($ex);
|
||||
$log = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Unknown Error: LogicException: Logic in ', $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testLogErrorErrorExceptionNotice()
|
||||
{
|
||||
$ex = new ErrorException('message', 321, E_NOTICE);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
ErrorHandler::logError($ex);
|
||||
$log = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Notice: message in ', $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testLogErrorErrorExceptionWarning()
|
||||
{
|
||||
$ex = new ErrorException('message', 321, E_WARNING);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
ErrorHandler::logError($ex);
|
||||
$log = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Warning: message in ', $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess
|
||||
*/
|
||||
public function testLogErrorErrorExceptionFatal()
|
||||
{
|
||||
$ex = new ErrorException('message', 321, E_ERROR);
|
||||
ini_set('error_log', $this->log_file_name);
|
||||
ErrorHandler::logError($ex);
|
||||
$log = file_get_contents($this->log_file_name);
|
||||
$this->assertContains('PHP Fatal Error: message in ', $log);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
if (file_exists($this->log_file_name) && is_writable($this->log_file_name)) {
|
||||
unlink($this->log_file_name);
|
||||
}
|
||||
ini_set('error_log', 'php://stderr');
|
||||
set_error_handler($this->old_eh);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user