Memcache, refactoring, View helpers, #16
git-svn-id: svn+ssh://code.netmonsters.ru/svn/majestic/branches/evo@124 4cb57b5f-5bbd-dd11-951b-001d605cbbc5
This commit is contained in:
@ -13,7 +13,7 @@ class ErrorAction extends ViewAction
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Exception
|
* @var ErrorException
|
||||||
*/
|
*/
|
||||||
protected $exception;
|
protected $exception;
|
||||||
|
|
||||||
@ -36,12 +36,12 @@ class ErrorAction extends ViewAction
|
|||||||
return '/static/' . $this->template;
|
return '/static/' . $this->template;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function sendHttpCode($code)
|
protected function sendHttpCode()
|
||||||
{
|
{
|
||||||
if (headers_sent()) {
|
if (headers_sent()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch ($code) {
|
switch ($this->template) {
|
||||||
case 404:
|
case 404:
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
break;
|
break;
|
||||||
@ -50,9 +50,40 @@ class ErrorAction extends ViewAction
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function fetch()
|
public function fetch()
|
||||||
{
|
{
|
||||||
$this->sendHTTPCode($this->template);
|
$this->logError();
|
||||||
|
$this->sendHTTPCode();
|
||||||
return $this->view->fetch($this->getTemplate());
|
return $this->view->fetch($this->getTemplate());
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,6 +32,9 @@ class FrontController
|
|||||||
private function __construct()
|
private function __construct()
|
||||||
{
|
{
|
||||||
ErrorHandler::init();
|
ErrorHandler::init();
|
||||||
|
if (DEBUG == true) {
|
||||||
|
Profiler::getInstance()->start();
|
||||||
|
}
|
||||||
$this->router = new Router();
|
$this->router = new Router();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +99,6 @@ class FrontController
|
|||||||
public function execute()
|
public function execute()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
||||||
$request = Env::getRequestUri();
|
$request = Env::getRequestUri();
|
||||||
$route = $this->getRouter()->route($request);
|
$route = $this->getRouter()->route($request);
|
||||||
if (!$route) {
|
if (!$route) {
|
||||||
@ -107,14 +109,16 @@ class FrontController
|
|||||||
if (!class_exists($action_class)) {
|
if (!class_exists($action_class)) {
|
||||||
throw new GeneralException('Action class "' . $action_class . '" not found.');
|
throw new GeneralException('Action class "' . $action_class . '" not found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$action = new $action_class();
|
$action = new $action_class();
|
||||||
$layout_class = $route->getLayout();
|
$layout_class = $route->getLayout();
|
||||||
if (!class_exists($layout_class)) {
|
if (!class_exists($layout_class)) {
|
||||||
throw new GeneralException('Layout class "' . $layout_class . '" not found.');
|
throw new GeneralException('Layout class "' . $layout_class . '" not found.');
|
||||||
}
|
}
|
||||||
$layout = new $layout_class();
|
|
||||||
return $layout->fetch($action);
|
|
||||||
|
|
||||||
|
$layout = new $layout_class();
|
||||||
|
$html = $layout->fetch($action);
|
||||||
|
return (!DEBUG) ? $html : Profiler::getInstance()->end($html);
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
if (DEBUG == true) {
|
if (DEBUG == true) {
|
||||||
return ErrorHandler::showDebug($e);
|
return ErrorHandler::showDebug($e);
|
||||||
|
66
app/PagerAction.php
Normal file
66
app/PagerAction.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage app
|
||||||
|
* @since 2010-03-07
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PagerAction extends ViewAction
|
||||||
|
{
|
||||||
|
public $page;
|
||||||
|
public $last_page;
|
||||||
|
|
||||||
|
//protected $num_rows;
|
||||||
|
|
||||||
|
protected $offset = 0;
|
||||||
|
protected $count = 0;
|
||||||
|
protected $limit;
|
||||||
|
|
||||||
|
public function __construct($count, $limit = 20)
|
||||||
|
{
|
||||||
|
$this->count = $count;
|
||||||
|
$this->limit = $limit;
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function execute()
|
||||||
|
{
|
||||||
|
$page = (int) Env::Get('p');
|
||||||
|
$this->last_page = ceil($this->count/$this->limit);
|
||||||
|
$this->page = ($page <= $this->last_page && $page > 0) ? $page : 1;
|
||||||
|
$this->offset = $this->limit * ($this->page - 1);
|
||||||
|
//$this->num_rows = ($this->limit + $this->offset) <= $this->count ? ($this->limit + $this->offset) : $this->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOffset()
|
||||||
|
{
|
||||||
|
return $this->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLimit()
|
||||||
|
{
|
||||||
|
return $this->limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getTemplate()
|
||||||
|
{
|
||||||
|
$template = ($this->template) ? $this->template : substr(get_class($this), 0, -6/*strlen('Action')*/);
|
||||||
|
return '/actions/' . $template;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* public function setNumRows($num_rows)
|
||||||
|
{
|
||||||
|
$this->num_rows = $num_rows;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*function prepare()
|
||||||
|
{
|
||||||
|
$this->templater->assign('page', $this->page);
|
||||||
|
$this->templater->assign('page_max', $this->max_page_num);
|
||||||
|
}*/
|
||||||
|
}
|
72
cache/CacheKey.php
vendored
Normal file
72
cache/CacheKey.php
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage Cache
|
||||||
|
* @since 2010-03-10
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CacheKey
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $key;
|
||||||
|
protected $params = '';
|
||||||
|
protected $expire = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $params
|
||||||
|
* @param iCacheable $cacheable
|
||||||
|
* @return CacheKey
|
||||||
|
*/
|
||||||
|
public function __construct($key, $params = array(), $cacheable)
|
||||||
|
{
|
||||||
|
$this->key = $key;
|
||||||
|
if (!$cacheable instanceof iCacheable) {
|
||||||
|
throw new GeneralException('CacheKey depends on iCacheable instance');
|
||||||
|
}
|
||||||
|
$this->cache = $cacheable->getCache();
|
||||||
|
$this->expire = $cacheable->getKeyExpire($this->key);
|
||||||
|
$this->params = (is_array($params)) ? implode('', $params) : $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getCacheKey()
|
||||||
|
{
|
||||||
|
$params = ($this->params) ? ('_' . $this->params) : '';
|
||||||
|
return $this->key . $params;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getExpire()
|
||||||
|
{
|
||||||
|
return $this->expire;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $expire
|
||||||
|
*/
|
||||||
|
public function setExpire($expire)
|
||||||
|
{
|
||||||
|
$this->expire = $expire;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get()
|
||||||
|
{
|
||||||
|
return $this->cache->get($this->getCacheKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function set($value)
|
||||||
|
{
|
||||||
|
return $this->cache->set($this->getCacheKey(), $value, $this->expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
return $this->cache->del($this->getCacheKey());
|
||||||
|
}
|
||||||
|
}
|
48
cache/CacheKeySet.php
vendored
Normal file
48
cache/CacheKeySet.php
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage Cache
|
||||||
|
* @since 2010-03-10
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
class CacheKeySet extends CacheKey
|
||||||
|
{
|
||||||
|
public function get()
|
||||||
|
{
|
||||||
|
$set = $this->cache->get($this->key);
|
||||||
|
$item_key = $this->getCacheKey();
|
||||||
|
|
||||||
|
if (!is_array($set) || !array_key_exists($item_key, $set)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return $this->cache->get($item_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $value
|
||||||
|
*/
|
||||||
|
public function set($value)
|
||||||
|
{
|
||||||
|
$set = $this->cache->get($this->key);
|
||||||
|
if (!is_array($set)) {
|
||||||
|
$set = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$item_key = $this->getCacheKey();
|
||||||
|
if (!$this->cache->set($item_key, $value, $this->expire)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$set[$item_key] = $this->cache->getExpire($this->expire);
|
||||||
|
return $this->cache->set($this->key, $set, $this->expire);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function del()
|
||||||
|
{
|
||||||
|
return $this->cache->del($this->key);
|
||||||
|
}
|
||||||
|
}
|
54
cache/MemcacheCache.php
vendored
54
cache/MemcacheCache.php
vendored
@ -17,10 +17,26 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
protected $connection = null;
|
protected $connection = null;
|
||||||
|
|
||||||
|
protected $key_salt = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* One hour to live default
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $expire = 3600;
|
||||||
|
|
||||||
|
protected $keys = array();
|
||||||
|
|
||||||
public function __construct($config)
|
public function __construct($config)
|
||||||
{
|
{
|
||||||
$this->connection = new Memcache();
|
$this->connection = new Memcache();
|
||||||
|
|
||||||
|
if (isset($config['key_salt'])) {
|
||||||
|
$this->key_salt = $config['key_salt'];
|
||||||
|
unset($config['key_salt']);
|
||||||
|
}
|
||||||
|
|
||||||
$required = array('hostname', 'port');
|
$required = array('hostname', 'port');
|
||||||
foreach ($config as $c) {
|
foreach ($config as $c) {
|
||||||
foreach ($required as $option) {
|
foreach ($required as $option) {
|
||||||
@ -42,7 +58,7 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
public function add($key, $value, $expire = 0)
|
public function add($key, $value, $expire = 0)
|
||||||
{
|
{
|
||||||
return $this->connection->add($key, $value, null, $expire);
|
return $this->connection->add($this->getKey($key), $value, null, $this->getExpire($expire));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,7 +70,7 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
public function decrement($key, $decrement = 1)
|
public function decrement($key, $decrement = 1)
|
||||||
{
|
{
|
||||||
return $this->connection->decrement($key, $decrement);
|
return $this->connection->decrement($this->getKey($key), $decrement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,7 +82,7 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
public function del($key)
|
public function del($key)
|
||||||
{
|
{
|
||||||
return $this->connection->delete($key);
|
return $this->connection->delete($this->getKey($key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,12 +98,12 @@ class MemcacheCache extends Cache
|
|||||||
/**
|
/**
|
||||||
* Retrieve item from the cache
|
* Retrieve item from the cache
|
||||||
*
|
*
|
||||||
* @param mixed $key
|
* @param string $key
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function get($key)
|
public function get($key)
|
||||||
{
|
{
|
||||||
return $this->connection->get($key);
|
return $this->connection->get($this->getKey($key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,7 +115,7 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
public function increment($key, $increment = 1)
|
public function increment($key, $increment = 1)
|
||||||
{
|
{
|
||||||
return $this->connection->increment($key, $increment);
|
return $this->connection->increment($this->getKey($key), $increment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -112,7 +128,7 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
public function replace($key, $value, $expire = 0)
|
public function replace($key, $value, $expire = 0)
|
||||||
{
|
{
|
||||||
return $this->connection->replace($key, $value, null, $expire);
|
return $this->connection->replace($this->getKey($key), $value, null, $this->getExpire($expire));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,6 +141,28 @@ class MemcacheCache extends Cache
|
|||||||
*/
|
*/
|
||||||
public function set($key, $value, $expire = 0)
|
public function set($key, $value, $expire = 0)
|
||||||
{
|
{
|
||||||
return $this->connection->set($key, $value, null, $expire);
|
return $this->connection->set($this->getKey($key), $value, null, $this->getExpire($expire));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function getKey($key)
|
||||||
|
{
|
||||||
|
if (!isset($this->keys[$key])) {
|
||||||
|
$this->keys[$key] = md5($this->key_salt . $key);
|
||||||
|
}
|
||||||
|
return $this->keys[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getExpire($expire)
|
||||||
|
{
|
||||||
|
return ($expire > 0) ? $expire : $this->expire;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cleanKeys()
|
||||||
|
{
|
||||||
|
$this->keys = array();
|
||||||
}
|
}
|
||||||
}
|
}
|
24
cache/iCacheable.php
vendored
Normal file
24
cache/iCacheable.php
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage cache
|
||||||
|
* @since 2010-03-12
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface iCacheable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return Cache
|
||||||
|
*/
|
||||||
|
public function getCache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return Expiration time in seconds
|
||||||
|
*/
|
||||||
|
public function getKeyExpire($key);
|
||||||
|
}
|
@ -1,78 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* PagerAction
|
|
||||||
*
|
|
||||||
* @copyright NetMonsters <team@netmonsters.ru>
|
|
||||||
* @link
|
|
||||||
* @package Nakon
|
|
||||||
* @subpackage face
|
|
||||||
* @since 04.02.2008
|
|
||||||
* @version SVN$
|
|
||||||
* @filesource $URL$
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class Pager extends Action
|
|
||||||
{
|
|
||||||
public $template_dir = '.';
|
|
||||||
|
|
||||||
protected $current_page = 1;
|
|
||||||
protected $max_page_num;
|
|
||||||
protected $num_rows;
|
|
||||||
protected $limit;
|
|
||||||
protected $start_offset = 0;
|
|
||||||
protected $count = 0;
|
|
||||||
|
|
||||||
public function __construct($count, $current_page = 1, $records_limit = 20)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
|
|
||||||
$this->count = $count;
|
|
||||||
$this->limit = $records_limit;
|
|
||||||
|
|
||||||
$this->max_page_num = ceil($this->count/$this->limit);
|
|
||||||
$this->current_page = ((int)$current_page <= $this->max_page_num && (int)$current_page > 0) ? (int)$current_page : 1;
|
|
||||||
|
|
||||||
$this->start_offset = $this->limit * ($this->current_page - 1);
|
|
||||||
$this->num_rows = ($this->limit + $this->start_offset) <= $this->count ? ($this->limit + $this->start_offset) : $this->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Возвращает текущую страницу
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getPage()
|
|
||||||
{
|
|
||||||
return $this->current_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function startOffset()
|
|
||||||
{
|
|
||||||
return $this->start_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function limit()
|
|
||||||
{
|
|
||||||
return $this->limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setNumRows($num_rows)
|
|
||||||
{
|
|
||||||
$this->num_rows = $num_rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
function init()
|
|
||||||
{
|
|
||||||
$this->template = "Pager";
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepare()
|
|
||||||
{
|
|
||||||
$this->templater->assign('page', $this->current_page);
|
|
||||||
$this->templater->assign('page_max', $this->max_page_num);
|
|
||||||
$this->templater->assign('limit', $this->limit);
|
|
||||||
$this->templater->assign('count', $this->count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
?>
|
|
@ -51,6 +51,9 @@ class ErrorHandler
|
|||||||
}
|
}
|
||||||
$text = '<table class="req"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody>';
|
$text = '<table class="req"><thead><tr><th>Variable</th><th>Value</th></tr></thead><tbody>';
|
||||||
foreach ($array as $key => $value) {
|
foreach ($array as $key => $value) {
|
||||||
|
if (is_array($value)) {
|
||||||
|
$value = print_r($value, true);
|
||||||
|
}
|
||||||
$value = ($value) ? htmlentities($value, ENT_QUOTES, 'UTF-8') : ' ';
|
$value = ($value) ? htmlentities($value, ENT_QUOTES, 'UTF-8') : ' ';
|
||||||
$text .= '<tr><td>' . $key . '</td><td class="code"><div>' . $value . '</div></td></tr>';
|
$text .= '<tr><td>' . $key . '</td><td class="code"><div>' . $value . '</div></td></tr>';
|
||||||
}
|
}
|
||||||
@ -68,6 +71,7 @@ class ErrorHandler
|
|||||||
*/
|
*/
|
||||||
static public function showDebug($exception)
|
static public function showDebug($exception)
|
||||||
{
|
{
|
||||||
|
ob_clean();
|
||||||
$class = get_class($exception);
|
$class = get_class($exception);
|
||||||
|
|
||||||
$method = Env::Server('REQUEST_METHOD', '');
|
$method = Env::Server('REQUEST_METHOD', '');
|
||||||
|
@ -91,9 +91,10 @@ abstract class DbDriver
|
|||||||
/**
|
/**
|
||||||
* @param string $table
|
* @param string $table
|
||||||
* @param mixed $bind
|
* @param mixed $bind
|
||||||
|
* @param mixed $on_duplicate
|
||||||
* @return int Affected rows count
|
* @return int Affected rows count
|
||||||
*/
|
*/
|
||||||
public function insert($table, $bind)
|
public function insert($table, $bind, $on_duplicate = array())
|
||||||
{
|
{
|
||||||
$columns = array();
|
$columns = array();
|
||||||
foreach ($bind as $col => $val) {
|
foreach ($bind as $col => $val) {
|
||||||
|
@ -34,31 +34,6 @@ abstract class DbStatement
|
|||||||
$this->sql = $sql;
|
$this->sql = $sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $style
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function fetchAll($style = Db::FETCH_OBJ)
|
|
||||||
{
|
|
||||||
$data = array();
|
|
||||||
while ($row = $this->fetch($style)) {
|
|
||||||
$data[] = $row;
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $field
|
|
||||||
*/
|
|
||||||
public function fetchField($field)
|
|
||||||
{
|
|
||||||
$row = $this->fetch(Db::FETCH_ASSOC);
|
|
||||||
if (isset($row[$field])) {
|
|
||||||
return $row[$field];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function bindParam($param, &$value)
|
public function bindParam($param, &$value)
|
||||||
{
|
{
|
||||||
if ($this->map === null) {
|
if ($this->map === null) {
|
||||||
@ -138,6 +113,31 @@ abstract class DbStatement
|
|||||||
{
|
{
|
||||||
$this->close();
|
$this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $style
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function fetchAll($style = Db::FETCH_OBJ)
|
||||||
|
{
|
||||||
|
$data = array();
|
||||||
|
while ($row = $this->fetch($style)) {
|
||||||
|
$data[] = $row;
|
||||||
|
}
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $field
|
||||||
|
*/
|
||||||
|
public function fetchField($field)
|
||||||
|
{
|
||||||
|
$row = $this->fetch(Db::FETCH_ASSOC);
|
||||||
|
if (isset($row[$field])) {
|
||||||
|
return $row[$field];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Abstract methods */
|
/* Abstract methods */
|
||||||
|
|
||||||
|
135
model/Model.php
135
model/Model.php
@ -12,7 +12,7 @@
|
|||||||
* @filesource $URL$
|
* @filesource $URL$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class Model
|
abstract class Model implements iCacheable
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,6 +28,20 @@ abstract class Model
|
|||||||
* @var Cache
|
* @var Cache
|
||||||
*/
|
*/
|
||||||
protected $cache;
|
protected $cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom expiration time for keys
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $cache_keys = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caches to clean.
|
||||||
|
*
|
||||||
|
* @var mixed
|
||||||
|
*/
|
||||||
|
protected $caches_clean = array();
|
||||||
|
|
||||||
protected $table;
|
protected $table;
|
||||||
|
|
||||||
@ -35,7 +49,6 @@ abstract class Model
|
|||||||
|
|
||||||
protected $key = 'id';
|
protected $key = 'id';
|
||||||
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->db = Db::connect($this->connection);
|
$this->db = Db::connect($this->connection);
|
||||||
@ -73,37 +86,21 @@ abstract class Model
|
|||||||
*/
|
*/
|
||||||
public function get($id)
|
public function get($id)
|
||||||
{
|
{
|
||||||
$sql = 'SELECT * FROM ' . $this->table() . ' WHERE ' . $this->identify($this->key) . '=' . (int) $id;
|
$sql = 'SELECT * FROM ' . $this->table() . ' WHERE ' . $this->identify($this->key) . '=?';
|
||||||
return $this->db->query($sql)->fetch();
|
return $this->fetch($sql, $id);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $data
|
|
||||||
* @return int Affect row or id of inserted field.
|
|
||||||
*/
|
|
||||||
public function save($data)
|
|
||||||
{
|
|
||||||
$key = isset($data[$this->key]) ? $data[$this->key] : false;
|
|
||||||
$result = false;
|
|
||||||
if ($key) {
|
|
||||||
unset($data[$this->key]);
|
|
||||||
$result = $this->update($data, $this->identify($this->key) . '=' . (int) $id);
|
|
||||||
} else {
|
|
||||||
$result = $this->insert($data);
|
|
||||||
}
|
|
||||||
return $result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
* @param array $on_duplicate
|
||||||
* @return int Id of inserted row
|
* @return int Id of inserted row
|
||||||
*/
|
*/
|
||||||
public function insert($data)
|
public function insert($data, $on_duplicate = array())
|
||||||
{
|
{
|
||||||
if (!$this->db->insert($this->table(false), $data)) {
|
if (!$res = $this->db->insert($this->table(false), $data, $on_duplicate)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return $this->getInsertId();
|
return ($on_duplicate) ? $res : $this->getInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -146,11 +143,99 @@ abstract class Model
|
|||||||
/**
|
/**
|
||||||
* @return Cache
|
* @return Cache
|
||||||
*/
|
*/
|
||||||
protected function cache()
|
public function getCache()
|
||||||
{
|
{
|
||||||
if (!$this->cache) {
|
if (!$this->cache) {
|
||||||
$this->cache = Cacher::get(Config::get(__CLASS__, 'MemcacheCache'));
|
$this->cache = Cacher::get(Config::get(__CLASS__, 'MemcacheCache'));
|
||||||
}
|
}
|
||||||
return $this->cache;
|
return $this->cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getKeyExpire($key)
|
||||||
|
{
|
||||||
|
return (isset($this->cache_keys[$key])) ? ($this->cache_keys[$key] * 60) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param array $params
|
||||||
|
* @return CacheKey
|
||||||
|
*/
|
||||||
|
protected function cacheKey($name, $params = array())
|
||||||
|
{
|
||||||
|
if (substr(strtolower($name), -3, 3) == 'set') {
|
||||||
|
return new CacheKeySet($name, $params, $this);
|
||||||
|
}
|
||||||
|
return new CacheKey($name, $params, $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param CacheKey | CacheKeySet $cache
|
||||||
|
*/
|
||||||
|
protected function addCleanCache($cache)
|
||||||
|
{
|
||||||
|
$this->caches_clean[] = $cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function cleanCaches()
|
||||||
|
{
|
||||||
|
// cleaning caches
|
||||||
|
foreach ($this->caches_clean as $cache) {
|
||||||
|
$cache->del();
|
||||||
|
}
|
||||||
|
$this->caches_clean = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sql
|
||||||
|
* @param array $params
|
||||||
|
* @param string $field
|
||||||
|
* @param CacheKey | CacheKeySet $cache_key
|
||||||
|
*/
|
||||||
|
protected function fetchField($sql, $params = array(), $field, $cache_key = null)
|
||||||
|
{
|
||||||
|
if (!$cache_key || !$result = $cache_key->get()) {
|
||||||
|
$result = $this->db->query($sql, $params)->fetchField($field);
|
||||||
|
if ($cache_key) {
|
||||||
|
$cache_key->set($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sql
|
||||||
|
* @param array $params
|
||||||
|
* @param CacheKey | CacheKeySet $cache_key
|
||||||
|
*/
|
||||||
|
protected function fetch($sql, $params = array(), $cache_key = null)
|
||||||
|
{
|
||||||
|
if (!$cache_key || !$result = $cache_key->get()) {
|
||||||
|
$result = $this->db->query($sql, $params)->fetch();
|
||||||
|
if ($cache_key) {
|
||||||
|
$cache_key->set($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sql
|
||||||
|
* @param array $params
|
||||||
|
* @param CacheKey | CacheKeySet $cache_key
|
||||||
|
*/
|
||||||
|
protected function fetchAll($sql, $params = array(), $cache_key = null)
|
||||||
|
{
|
||||||
|
if (!$cache_key || !$result = $cache_key->get()) {
|
||||||
|
$result = $this->db->query($sql, $params)->fetchAll();
|
||||||
|
if ($cache_key) {
|
||||||
|
$cache_key->set($result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
@ -15,6 +15,28 @@
|
|||||||
class MySQLiDriver extends DbDriver
|
class MySQLiDriver extends DbDriver
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public function insert($table, $bind, $on_duplicate = array())
|
||||||
|
{
|
||||||
|
$columns = array();
|
||||||
|
foreach ($bind as $col => $val) {
|
||||||
|
$columns[] = $this->quoteIdentifier($col);
|
||||||
|
}
|
||||||
|
$values = array_values($bind);
|
||||||
|
|
||||||
|
if ($on_duplicate) {
|
||||||
|
$update = array();
|
||||||
|
foreach ($on_duplicate as $col => $val) {
|
||||||
|
$update[] = $this->quoteIdentifier($col) . '=' . $this->quote($val);
|
||||||
|
}
|
||||||
|
$on_duplicate = ' ON DUPLICATE KEY UPDATE ' . implode(', ', $update);
|
||||||
|
}
|
||||||
|
|
||||||
|
$sql = 'INSERT INTO ' . $this->quoteIdentifier($table)
|
||||||
|
. ' (' . implode(', ', $columns) . ') VALUES (' . $this->quote($values) . ')'
|
||||||
|
. (($on_duplicate) ? $on_duplicate : '');
|
||||||
|
return $this->query($sql)->affectedRows();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param mixed $sql
|
* @param mixed $sql
|
||||||
* @return DbStatement
|
* @return DbStatement
|
||||||
@ -72,7 +94,6 @@ class MySQLiDriver extends DbDriver
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_bool($value)) {
|
if (is_bool($value)) {
|
||||||
var_dump($value);
|
|
||||||
return (int) $value;
|
return (int) $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,15 @@
|
|||||||
class MySQLiStatement extends DbStatement
|
class MySQLiStatement extends DbStatement
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches single row
|
||||||
|
*
|
||||||
|
* @param mixed $style
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
public function fetch($style = Db::FETCH_OBJ)
|
public function fetch($style = Db::FETCH_OBJ)
|
||||||
{
|
{
|
||||||
if (! $this->result) {
|
if (!$this->result) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +83,13 @@ class MySQLiStatement extends DbStatement
|
|||||||
* @var MySQLi
|
* @var MySQLi
|
||||||
*/
|
*/
|
||||||
$mysqli = $this->driver->getConnection();
|
$mysqli = $this->driver->getConnection();
|
||||||
$result = $mysqli->query($sql);
|
if (DEBUG) {
|
||||||
|
$profiler = Profiler::getInstance()->profilerQuery($sql);
|
||||||
|
$result = $mysqli->query($sql);
|
||||||
|
$profiler->end();
|
||||||
|
} else {
|
||||||
|
$result = $mysqli->query($sql);
|
||||||
|
}
|
||||||
if ($result === false) {
|
if ($result === false) {
|
||||||
throw new Exception($mysqli->error, $mysqli->errno);
|
throw new Exception($mysqli->error, $mysqli->errno);
|
||||||
}
|
}
|
||||||
|
82
util/Profiler.php
Normal file
82
util/Profiler.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage util
|
||||||
|
* @since 2010-03-09
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Profiler
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $start = null;
|
||||||
|
protected $end = null;
|
||||||
|
|
||||||
|
protected $queries = array();
|
||||||
|
|
||||||
|
static protected $instance = null;
|
||||||
|
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
if (DEBUG == false) {
|
||||||
|
throw new GeneralException('Need to turn on DEBUG before use.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refuse cloning
|
||||||
|
*/
|
||||||
|
private function __clone(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Profiler
|
||||||
|
*/
|
||||||
|
static public function getInstance()
|
||||||
|
{
|
||||||
|
if (!isset(self::$instance)) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $query
|
||||||
|
* @return QueryProfiler
|
||||||
|
*/
|
||||||
|
public function profilerQuery($query)
|
||||||
|
{
|
||||||
|
$profiler = new QueryProfiler($query);
|
||||||
|
$this->queries[] = $profiler;
|
||||||
|
return $profiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function start()
|
||||||
|
{
|
||||||
|
$this->start = microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end($html)
|
||||||
|
{
|
||||||
|
$this->end = microtime(true);
|
||||||
|
if (stripos($html, '</body>') == False) {
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
return str_ireplace('</body>', $this->getOutput() . '</body>', $html);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getOutput()
|
||||||
|
{
|
||||||
|
$html = '<div style="clear:both; font:12px monospace; margin: 5px;">'
|
||||||
|
. 'Elapsed time: ' . round(($this->end- $this->start) * 1000) . 'ms.<br/>'
|
||||||
|
. 'Queries: ' . count($this->queries) . '<br/>';
|
||||||
|
|
||||||
|
foreach ($this->queries as $query) {
|
||||||
|
$html .= '[' . round($query->getElapsed() * 1000) . 'ms] ' . $query->getQuery() . '<br/>';
|
||||||
|
}
|
||||||
|
$html .= '</div>';
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
}
|
39
util/QueryProfiler.php
Normal file
39
util/QueryProfiler.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage util
|
||||||
|
* @since 2010-03-09
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
class QueryProfiler
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $query = '';
|
||||||
|
protected $start = null;
|
||||||
|
protected $end = null;
|
||||||
|
|
||||||
|
public function __construct($query)
|
||||||
|
{
|
||||||
|
$this->query = $query;
|
||||||
|
$this->start = microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function end()
|
||||||
|
{
|
||||||
|
$this->end = microtime(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuery()
|
||||||
|
{
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getElapsed()
|
||||||
|
{
|
||||||
|
return $this->end - $this->start;
|
||||||
|
}
|
||||||
|
}
|
@ -9,11 +9,15 @@
|
|||||||
* @filesource $URL$
|
* @filesource $URL$
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @method ViewHelperGet get()
|
||||||
|
*/
|
||||||
class PHPView implements iView
|
class PHPView implements iView
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $path = '';
|
protected $path = '';
|
||||||
protected $variables = array();
|
protected $variables = array();
|
||||||
|
protected $helpers = array();
|
||||||
protected $extension = '.phtml';
|
protected $extension = '.phtml';
|
||||||
protected $template = '';
|
protected $template = '';
|
||||||
|
|
||||||
@ -69,6 +73,31 @@ class PHPView implements iView
|
|||||||
return htmlentities($var, ENT_QUOTES, 'UTF-8');
|
return htmlentities($var, ENT_QUOTES, 'UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helpers call
|
||||||
|
*
|
||||||
|
* @param mixed $name
|
||||||
|
* @param mixed $args
|
||||||
|
* @return ViewHelper
|
||||||
|
*/
|
||||||
|
public function __call($name, $args)
|
||||||
|
{
|
||||||
|
$helper = $this->getHelper($name);
|
||||||
|
return call_user_func_array(array($helper, $name), $args);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHelper($name)
|
||||||
|
{
|
||||||
|
if (!isset($this->helpers[$name])) {
|
||||||
|
$class = 'ViewHelper' . ucfirst($name);
|
||||||
|
if (!class_exists($class)) {
|
||||||
|
throw new GeneralException('View helper "' . $class . '" not found.');
|
||||||
|
}
|
||||||
|
$this->helpers[$name] = new $class($this);
|
||||||
|
}
|
||||||
|
return $this->helpers[$name];
|
||||||
|
}
|
||||||
|
|
||||||
protected function getTemplatePath($template)
|
protected function getTemplatePath($template)
|
||||||
{
|
{
|
||||||
return $this->path . $template . $this->extension;
|
return $this->path . $template . $this->extension;
|
||||||
|
24
view/helpers/ViewHelper.php
Normal file
24
view/helpers/ViewHelper.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage View
|
||||||
|
* @since 2010-03-09
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class ViewHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PHPView
|
||||||
|
*/
|
||||||
|
protected $view = null;
|
||||||
|
|
||||||
|
public function __construct($view)
|
||||||
|
{
|
||||||
|
$this->view = $view;
|
||||||
|
}
|
||||||
|
}
|
57
view/helpers/ViewHelperGet.php
Normal file
57
view/helpers/ViewHelperGet.php
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright NetMonsters <team@netmonsters.ru>
|
||||||
|
* @link http://netmonsters.ru
|
||||||
|
* @package Majestic
|
||||||
|
* @subpackage View
|
||||||
|
* @since 2010-03-09
|
||||||
|
* @version SVN: $Id$
|
||||||
|
* @filesource $URL$
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ViewHelperGet extends ViewHelper
|
||||||
|
{
|
||||||
|
|
||||||
|
protected $get;
|
||||||
|
|
||||||
|
public function get($replace)
|
||||||
|
{
|
||||||
|
$get = $this->getSanitizedRequest();
|
||||||
|
if (!is_array($replace)) {
|
||||||
|
$replace = array($replace);
|
||||||
|
}
|
||||||
|
foreach ($replace as $key => $value) {
|
||||||
|
if (is_int($key)) {
|
||||||
|
unset($get[$value]);
|
||||||
|
} else {
|
||||||
|
$get[$key] = $this->impl($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return '?' . $this->view->escape(implode('&', $get));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSanitizedRequest()
|
||||||
|
{
|
||||||
|
if ($this->get === null) {
|
||||||
|
$get = Env::Get();
|
||||||
|
foreach ($get as $key => $value) {
|
||||||
|
$this->get[$key] = $this->impl($key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->get;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function impl($name, $value)
|
||||||
|
{
|
||||||
|
if (is_array($value)){
|
||||||
|
$result = array();
|
||||||
|
foreach ($value as $key => $val) {
|
||||||
|
$result[] = $name . '[' . $key . ']=' . $val;
|
||||||
|
}
|
||||||
|
$result = implode('&', $result);
|
||||||
|
} else {
|
||||||
|
$result = $name . '=' . $value;
|
||||||
|
}
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user