You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
6.7 KiB

<?php
/**
* Класс модели данных
*
* @copyright NetMonsters <team@netmonsters.ru>
* @link http://netmonsters.ru
* @package Majestic
* @subpackage Model
* @since 2010-02-16
* @version SVN: $Id$
* @filesource $URL$
*/
abstract class Model implements iCacheable
{
/**
* DbDriver instance
*
* @var DbDriver
*/
protected $db;
/**
* Cache instance
*
* @var 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 $connection = 'default';
protected $key = 'id';
public function __construct()
{
$this->db = Db::connect($this->connection);
}
/**
* @return int
*/
public function getInsertId()
{
return $this->db->getInsertId($this->table(false), $this->key);
}
/**
* @param string $ident
* @return string Quoted identifier.
*/
public function identify($ident)
{
return $this->db->quoteIdentifier($ident);
}
/**
* @param mixed $value
* @return string Quoted value.
*/
public function quote($value)
{
return $this->db->quote($value);
}
/**
* @param int $id
* @return object
*/
public function get($id)
{
$sql = 'SELECT * FROM ' . $this->table() . ' WHERE ' . $this->identify($this->key) . '=?';
return $this->fetch($sql, $id);
}
/**
* @param array $data
* @param array $on_duplicate
* @return int Id of inserted row
*/
public function insert($data, $on_duplicate = array())
{
$affected = $this->db->insert($this->table(false), $data, $on_duplicate);
return ($this->getInsertId()) ? $this->getInsertId() : $affected;
}
/**
* @param array $data
* @param mixed $where
* @return int Number of affected rows
*/
public function update($data, $where)
{
if (is_int($where)) {
$where = $this->identify($this->key) . '=' . (int) $where;
}
return $this->db->update($this->table(false), $data, $where);
}
/**
* @param int|array $where Int or array ids
* @return int Number of affected rows
*/
public function delete($where)
{
if (is_array($where)) {
$where = $this->identify($this->key) . ' IN (' . $this->quote($where) . ')';
} else {
$where = $this->identify($this->key) . '=' . (int) $where;
}
return $this->db->delete($this->table(false), $where);
}
/**
* @param bool $autoindent
* @return string
*/
protected function table($autoindent = true)
{
if (!$this->table) {
$this->table = substr(strtolower(get_class($this)), 0, -5/*strlen('Model')*/);
}
return $autoindent ? $this->identify($this->table) : $this->table;
}
/**
* Creates order sql string
*
* @param array $params
* @param array $sortable
* @return string
*/
protected function order($params, $sortable = array('id'))
{
$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;
}
}
return $sql;
}
/**
* Searches using like
*
* @param array $params
* @param array $searchable
* @param string $table_prefix
* @return string
*/
protected function search($params, $searchable = array('id'), $table_prefix = '')
{
$sql = '';
if (isset($params['q']) && isset($params['qt']) && in_array($params['qt'], $searchable)) {
if ($table_prefix) {
$sql = $table_prefix . '.';
}
$sql .= $this->identify($params['qt']) . ' LIKE ' . $this->quote('%' . $params['q'] . '%');
}
return $sql;
}
/**
* @return Cache
*/
public function getCache()
{
if (!$this->cache) {
$this->cache = Cacher::get(Config::get(__CLASS__, 'MemcacheCache'));
}
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;
}
}