116 Commits

Author SHA1 Message Date
3126483bae DIGITEC-1105 | Add is_array check for map bind 2019-03-06 20:37:26 +03:00
da17b79291 Добавляю возможность устанавливать параметры, передаваемые в массиве. (Вообще, на практике значения в массиве устанавливаются и так, но не увидел, чтобы такое поведение ArrayObject::offsetSet() было документировано.) 2017-09-13 14:17:15 +03:00
f1eb97348c Коммит обновленной файла для управления коллекциями (при переходе на ларавель 5) 2017-06-05 11:48:58 +03:00
5f6a454e6a toArray in SqlResultCollection 2015-12-25 06:51:24 +03:00
aa9ac8dfe8 SqlCriteria - изменен расчет кол-ва записей при использовании GROUP BY
(In this thread: http://www.cyberforum.ru/mysql/thread681915.html
I have solution for my problem - USE COUNT(DISTINCT pid))
2015-03-19 17:04:46 +03:00
d9573958bd Исправление SqlCriteria::count() 2015-01-30 23:52:16 +03:00
d5a2da7cbf Correct count in SqlCriteria (fix1) 2015-01-30 23:38:09 +03:00
388673d856 Correct count in SqlCriteria 2015-01-30 23:30:22 +03:00
f954f79250 Оптимизация запроса на получения кол-ва записей SqlModel::count
MIRSPORTA-604 Исправление ошибок mysql
2015-01-27 17:43:23 +03:00
823a7af927 whereJoin - разрешено использовать без value 2014-12-10 11:56:42 +03:00
66d342272d Merge branch 'sql_criteria' into namespace
Conflicts:
	Model/SqlResultProvider.php
2014-11-11 13:44:08 +03:00
b6e002f5a8 Исправление ошибки в SqlCriteria.count() - дублирующееся COUNT(COUNT( * во внутреннем sql-запросе 2014-09-29 15:59:55 +04:00
bccd018530 Исправление ошибки в SqlCriteria.count() для запросов в которых есть свой индивидуальный select и groupby (fix1) 2014-09-27 17:05:33 +04:00
67f47b882b Исправление ошибки в SqlCriteria.count() для запросов в которых есть свой индивидуальный select и groupby 2014-09-27 17:00:46 +04:00
b7ff8ab3fc Исправление ошибки в SqlCriteria.count() 2014-09-26 18:44:35 +04:00
b4c3d89020 Correct SqlCriteria.count 2014-08-13 17:59:49 +04:00
9e359e0c25 Add assoc method into SqlResultCollection 2014-08-12 14:47:47 +04:00
776859b3c8 fix count method with saving original sql expression 2014-08-05 13:09:48 +04:00
acec4a521e Merge branch 'namespace' of dimti.ru:majestic into namespace 2014-07-30 21:31:52 +04:00
28efb6c675 fix erro in Form 2014-07-30 21:31:34 +04:00
383396b96d SqlCriteria - count - use $select parameter for preventions error with duplicate fields 2014-07-30 20:01:57 +04:00
d3f367d990 SqlResultProvider fetchField - check for empty result 2014-07-28 15:38:11 +04:00
b7fcfcf476 fix SqlCriteria count 2014-07-28 12:06:47 +04:00
2a98f9b0d7 Correct detect count records in SQlCriteria with use group by 2014-07-28 11:50:27 +04:00
15ea37109d Merge branch 'namespace' of dimti.ru:majestic into namespace 2014-07-28 09:28:00 +04:00
d42074b620 prepend notice error on session_start 2014-07-28 09:27:32 +04:00
0f8c0df4bc Merge branch 'namespace' of dimti.ru:majestic into namespace 2014-07-23 18:49:01 +04:00
b710a63dc7 App::abort(404) if route not found 2014-07-23 18:47:50 +04:00
9c58757641 Cache to namespace 2014-07-21 15:58:15 +04:00
1922886c2f Merge branch 'namespace' of dimti.ru:majestic into namespace 2014-07-03 19:50:13 +04:00
8c57655124 Remove error handler from FrontController 2014-07-03 19:49:43 +04:00
5b7a10e099 Merge branch 'namespace' of dimti.ru:majestic into namespace 2014-07-03 15:59:38 +04:00
b85c96c80e redis-doc hset. hget 2014-07-03 15:59:00 +04:00
60fdc48b2b fix - property_exists вместо isset 2014-06-19 21:45:02 +04:00
61be1700ee Отключение инициализации ErrorHandler 2014-06-19 19:17:28 +04:00
0057d6ff7c namesape fix 2014-06-06 20:03:51 +04:00
0dde2ccb59 Correct CliController for user namespace. Turn off error handler. 2014-06-04 22:30:31 +04:00
37c6dab160 Merge branch 'namespace' of dimti.ru:majestic into namespace 2014-06-04 21:57:29 +04:00
3709fb2a74 Correct namespace in Valdiators. Add namespace Mail. 2014-06-04 21:57:19 +04:00
c9b38314b5 Merge remote-tracking branch 'origin/sql_criteria' into namespace 2014-06-03 22:15:44 +04:00
52de52a17a Fix count 2014-06-03 20:06:56 +04:00
d710b19fed Correct use criteria with use count and join. 2014-06-03 19:56:30 +04:00
1ba341b064 Add namespace. 2014-06-02 18:58:49 +04:00
aec1a60985 Commit with composer.json 2014-05-27 17:56:46 +04:00
c62620593f Add vendor dir to autload. 2014-05-19 21:34:20 +04:00
e8e266a101 Merge branch 'sql_criteria' of dimti.ru:majestic into sql_criteria 2014-05-15 17:47:23 +04:00
ff148f2f95 SqlDbDriver - cancel identifier quotu for symbol "*" 2014-05-15 17:47:07 +04:00
906ffe07a8 Add identify quotes into table in SqlModel.find 2014-05-08 19:12:09 +04:00
cabb17b3c4 Merge branch 'sql_criteria' of dimti.ru:majestic into sql_criteria 2014-04-29 19:48:08 +04:00
3b390d968b Обработка массива term в условии where и строк в том числе. 2014-04-29 19:46:09 +04:00
0b0dc61960 Merge branch 'sql_criteria' of dimti.ru:majestic into sql_criteria 2014-04-25 20:17:15 +04:00
3a560dfe6f Correct PHP-Doc in FrontController for get PHPView. Add some methods into PHPView autocompletion interface (PHP-Doc). 2014-04-25 20:16:48 +04:00
d1c8ecf850 Modifie SqlCriteria.count() - force to use custom sql_expression. 2014-04-10 15:30:09 +04:00
d3b79e594f Use placeholders for table names in join operations. Correct use count with use join connections. 2014-03-14 18:50:51 +04:00
5f9c295c01 DIGITEC-314 Ошибка скрипта импорта
Создан интерфейс для классов SqlResultProvider и SqlResultCollection. В последний добавлены недостающие метода
2014-03-13 12:39:44 +04:00
6b0bf4058e DIGITEC-312 поиск на мобильной версии. зависание
Correct PHP-Doc
2014-03-11 15:48:02 +04:00
2cb51015e6 Fix in SqlResultProvider.getKeys(). 2014-03-11 15:44:20 +04:00
3272d7a903 Add SqlCriteria.join(). Refactoring SqlResultCollection (add SqlResultCollection). 2014-03-06 15:26:59 +04:00
740bd6b7f3 Modify CliController for opportunity to extend this class. 2014-03-05 19:11:11 +04:00
a090d52676 DIGITEC-222 - Автофиллинговые параметры должны иметь постоянный идентификатор
Исправление в SqlCriteria в методе select
2014-01-30 12:48:07 +04:00
94addf4ca9 Correct SqlResultProvider::fetchField() to work with empty results. 2013-12-24 10:00:51 +04:00
7486ab5cf1 Add MySQLiStatement::getMysqliResult() 2013-12-19 15:26:00 +04:00
8b17a8f911 MEBLOG-39 - Вывод наименование каталога 2013-11-21 12:26:09 +04:00
153d6fa20a Correct ordering params in SqlCriteria::order() 2013-11-18 18:47:14 +04:00
049999dfbd Merge branch 'sql_criteria' of dimti.ru:majestic into sql_criteria 2013-10-29 16:42:38 +04:00
4878b32641 Add group by support in sql criteria. 2013-10-29 16:42:33 +04:00
253b303084 Merge branch 'sql_criteria' of dimti.ru:majestic into sql_criteria 2013-10-23 11:57:34 +04:00
1ea6c5acdd Применение функции trim в методе SqlCriteria.select() 2013-10-23 11:54:27 +04:00
d019ae2450 Merge remote-tracking branch 'origin/extended_classes' into sql_criteria 2013-10-22 11:02:24 +04:00
8311fa1c26 Merge branch 'extended_classes' of dimti.ru:majestic into extended_classes 2013-10-21 15:51:34 +04:00
645ffd9ed1 Add support symlink into Autoload. 2013-10-21 15:51:24 +04:00
5d7162480a Добавлен метод whereNot - повтор для whereNotIn 2013-10-20 13:37:38 +04:00
3263af5e18 Add method SqlCriteria.whereNotIn(). 2013-10-17 21:23:32 +04:00
40e049c93e Корректировка в методе SqlCriteria.select(). 2013-10-10 15:28:41 +04:00
ff76d8fa1d Add into MsgViewHelper.getType() and use_as_html protected var. 2013-10-10 11:32:32 +04:00
559d779576 Update placeholder regular expression SqlDbDriver.quoteIdentifier(). 2013-10-09 08:59:54 +04:00
6890827f17 Fix in MySQLiStatement.mapPlaceholders() Use strictly placeholder names started with A-z symbol. 2013-10-09 08:35:15 +04:00
9a881f6560 Extend SqlCriteria::select() - use array or string for setting multiple fields of one call that method. 2013-10-09 07:07:34 +04:00
d1cf95b82c Merge branch 'extended_classes' into sql_criteria 2013-09-26 13:22:49 +04:00
3f6b2adefd SqlDbDriver quote identifier - add checking for string as placeholder. 2013-09-26 10:46:30 +04:00
e06ddba773 Correct call fetchAll in SqlModel.find(). 2013-09-26 10:45:46 +04:00
0fc1884c93 Extend Action.redirect() (add new param "permanently" for set header 301 Moved permanently). 2013-09-23 17:22:35 +04:00
9625b1e7a4 Extend MsgViewHelper. Add MsgViewHelper.getTypeToClass() 2013-09-23 13:41:04 +04:00
9ab3bfc0da Add TODO in SqlResultProvider. 2013-09-20 22:13:02 +04:00
dff9c0b2af Refactoring SqlCriteria, SqlModel. Add SqlResultProvider.fetchField(). 2013-09-20 22:11:54 +04:00
72c38e641d Refactoring assoc use in SqlResultProvider. Write SqlCriteria.find() method. 2013-09-19 12:54:10 +04:00
ba88ac5229 Merge branch 'extended_classes' into sql_criteria 2013-09-19 12:36:58 +04:00
ab01d0a41f Refactoring. Add SqlResultProvider. Add TODO in SqlDbDriver.whereExpr(). 2013-09-19 10:05:00 +04:00
2cb56ad228 Refactoring. Fix errors. Add SqlModel.assoc*() methods. 2013-09-17 18:42:04 +04:00
732b1ca8a5 Refactoring SqlModel.find() add SqlModel.criteria(). Add critera data keys as constants in SqlModel. 2013-09-17 14:57:56 +04:00
c890d082aa Add SqlCriteria class. Add SqlModel.find() with use SqlCriteria. 2013-09-17 09:51:20 +04:00
a51545268d Add CliLogger.generateOutString() for extend this class. 2013-09-16 11:28:09 +04:00
4b31df52c3 Add trait`s support to AutoloadBuilder. 2013-09-12 12:08:12 +04:00
f9de8ee3bc Merge branch 'feature_new_validators' into extended_classes 2013-09-10 18:05:45 +04:00
625752ced7 Modified EmailValidator add links to rfc specifications. 2013-09-10 17:05:14 +04:00
0ac9f3c5e8 Merge branch 'redis-doc' into extended_classes 2013-09-10 17:04:02 +04:00
7fd2961737 sInter 2013-09-10 17:03:22 +04:00
3e30e59e0b lRange, rPush, lTrim 2013-09-10 17:02:32 +04:00
a029cc3c57 sAdd, sCard, sSize, sMembers, sGetMembers, sContains, sIsMember, sRem, sRemove 2013-09-10 16:59:42 +04:00
5dd81b24fc Modified PHP-Doc for CliController::execute(). 2013-09-10 16:56:22 +04:00
8113986276 Add to ErrorHTTPException support code 401. 2013-09-10 16:55:14 +04:00
10c68143cb Изменен FileLogger для возможности расширения класса 2013-09-10 16:43:23 +04:00
ef99a26635 Modife CliController. 2013-09-10 16:41:13 +04:00
8133695eae Add Env.Request(). 2013-09-10 16:40:33 +04:00
5b9eab1067 Merge remote-tracking branch 'origin/fix_error_log' into extended_classes 2013-09-10 16:40:13 +04:00
3b6ae39707 Added new validators without tests 2012-12-12 13:11:54 +04:00
163ac086b0 Merge branch 'fix_error_log' 2012-12-11 19:25:15 +04:00
126d97b020 Added exception name to log 2012-12-11 19:08:37 +04:00
a2cb6a405e Get rid of $this->template logic, switched to type of exception 2012-12-11 18:56:07 +04:00
fce43da00d Fixed test error for testDebugAutoload() with coverage 2012-12-11 18:45:48 +04:00
98324588b7 added test for Mongo::addCondition method 2012-12-11 18:39:26 +04:00
c525a09078 fixed AutoloadBuilderTest to pass without template app 2012-12-11 16:46:53 +04:00
748393f653 Fixed function name 2012-12-11 16:28:04 +04:00
5f47dab73e Use new logError in FrontController, tests 2012-12-11 15:42:17 +04:00
91b364d01a Separate function ErrorHandler::logError() and tests 2012-12-11 15:03:48 +04:00
d007f356c0 Remove duplicate lines from test 2012-11-22 16:41:32 +04:00
163 changed files with 1601 additions and 618 deletions

View File

@ -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;
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\App;
/**
* AjaxAction
*

99
App/CliController.php Normal file
View 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);
}
}

View File

@ -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':
if ($this->exception instanceof \Majestic\Exception\ErrorHTTPException) {
header($this->exception->getHTTPHeader());
break;
default:
} 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
View 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;
}
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\App;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\App\Router;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -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 . '".');
}
}
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\App;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\App;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -6,7 +6,7 @@
* @subpackage Cache
* @since 2010-03-04
*/
namespace Majestic\Core;
abstract class Cache
{

28
Config.php Normal file → Executable file
View 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);
}

View File

@ -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) {

View File

@ -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);
}

View File

@ -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',

View File

@ -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">

View File

@ -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 {}

View File

@ -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 {}

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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)

View File

@ -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,8 +71,12 @@ class Load
static public function getFilePath($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');
$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);
}
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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);
}
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\Mail;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -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;
}

View File

@ -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 . '".');
}
}
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\Model;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\Model;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -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);
}

View File

@ -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.');
}
}

View File

@ -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;

View File

@ -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';

View File

@ -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;

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\Model;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

277
Model/SqlCriteria.php Normal file
View 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;
}
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\Model;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru
@ -110,8 +110,10 @@ abstract class SqlDbDriver extends DbDriver
{
$ident = explode('.', $ident);
foreach ($ident as &$segment) {
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();

View File

@ -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;
@ -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);
}
}

View 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
View 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
View File

@ -0,0 +1,10 @@
<?php namespace Majestic\Model;
interface iSqlResultItems
{
public function fetchAll();
public function fetchField($field);
public function fetch();
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic\Redis;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -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;

View File

@ -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
{

View File

@ -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;
}

View File

@ -1,4 +1,4 @@
<?php
<?php namespace Majestic;
/**
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru

View File

@ -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();
}
/**

View File

@ -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);

View 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)

View 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