Joostina CMS / CMF v2.* API
  • Docs
  • Package
  • Class
  • Tree
  • Todo
Overview

Packages

  • Components
    • Acls
      • Models
        • Admin
        • Site
    • BlogCategory
      • Models
        • Admin
        • Site
    • Blogs
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • Coder
      • Controllers
        • Admin
      • Models
        • Admin
    • Comments
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • CommentsCounter
      • Models
        • Admin
        • Site
    • Mainpage
      • Controllers
        • Site
    • News
      • Controllers
        • Admin
        • Site
      • Helpers
      • Models
        • Admin
        • Site
    • Pages
      • Controllers
        • Admin
        • Site
      • Models
        • Site
    • Search
      • Controllers
        • Site
    • Site
      • Controllers
        • Admin
        • Site
    • Sitemap
      • Controllers
        • Admin
        • Site
      • Models
        • Admin
        • Site
    • Test
      • Controllers
        • Site
    • Torrents
      • Controllers
        • Site
    • Users
      • Controllers
        • Admin
        • Site
      • Models
        • Admin
        • Site
  • Compression
  • Core
    • Libraries
      • Arhive
      • Array
      • Attached
      • Autoadmin
      • Autoloader
      • Benchmark
      • Breadcrumbs
      • Cache
      • Config
      • Cookie
      • Csrf
      • Database
        • Drivers
          • Interfaces
      • Datetime
      • Debug
      • Editor
      • Events
      • File
      • Filter
      • Flashmessage
      • Folder
      • Hit
      • Html
      • Image
      • Inflector
      • Inputfilter
      • Libraries
      • Mail
      • Module
      • Nestedset
      • Pager
      • Pages
      • Params
      • Randomizer
      • Request
      • RobotLoader
      • Route
      • Security
      • Session
      • Static
      • String
      • Text
      • Trash
      • Validate
  • Email
  • Extra
    • Libraries
      • Basket
  • Joostina
    • Controller
    • Core
    • Document
  • JSMin
  • Libraries
    • Extra
      • Basket
        • Models
          • Site
  • None
  • Plugins
    • Autoadmin
    • Editor
    • Sitemap
  • SimpleMail
  • Vendors
    • Libraries
      • Email

Classes

  • joosModel
   1: <?php defined('_JOOS_CORE') or exit();
   2: 
   3: require_once 'database/interface.php';
   4: require_once 'database/mysqli.php';
   5: 
   6: class joosDatabase extends joosDatabaseMysqli
   7: {
   8: }
   9: 
  10: /**
  11:  * Библиотека ORM расширения для гибкой работы с информацией в юазе данных
  12:  *
  13:  * @version    1.0
  14:  * @package    Core\Libraries
  15:  * @subpackage Database
  16:  * @author     Joostina Team <info@joostina.ru>
  17:  * @copyright  (C) 2007-2012 Joostina Team
  18:  * @license    MIT License http://www.opensource.org/licenses/mit-license.php
  19:  * Информация об авторах и лицензиях стороннего кода в составе Joostina CMS: docs/copyrights
  20:  *
  21:  * */
  22: class joosModel
  23: {
  24:     /**
  25:      * Название таблицы, используемой текущей моделью
  26:      *
  27:      * @var string
  28:      */
  29:     protected $_tbl;
  30: 
  31:     /**
  32:      * Название поля первичного ключа таблицы, чаще всего ID
  33:      * По данному полю производится идентификация объекта, и по правильному оно должно содержать уникальное значение
  34:      *
  35:      * @var string
  36:      */
  37:     protected $_tbl_key;
  38: 
  39:     /**
  40:      * Текст ошибки работы с активной моделью
  41:      *
  42:      * @var string
  43:      */
  44:     protected $_error;
  45: 
  46:     /**
  47:      * Объект базы данных
  48:      *
  49:      * @var joosDatabase
  50:      */
  51:     protected $_db;
  52: 
  53:     /**
  54:      * "Мягкое" удаление объектов БД
  55:      * Если в модели переопределить это значение в TRUE - то запись перед удалением будет копироваться в общесистемную корзину
  56:      *
  57:      * @var bool
  58:      */
  59:     protected $_soft_delete = FALSE;
  60: 
  61:     /**
  62:      * Название текущего класса модели
  63:      *
  64:      * @var string
  65:      */
  66:     protected $__obj_name;
  67:     protected $_validation_error_messages = array();
  68: 
  69:     /**
  70:      * Инициализация модели
  71:      *
  72:      * @param string $table название используемой таблицы, можно с преффиксом, например #__news
  73:      * @param string $key   Название поля первичного ключа таблицы,
  74:      */
  75:     public function __construct($table, $key)
  76:     {
  77:         $this->_tbl = $table;
  78:         $this->_tbl_key = $key;
  79:         $this->_db = joosDatabase::instance();
  80:     }
  81: 
  82:     /**
  83:      * Возвращает назание текущей модели
  84:      * @return string
  85:      */
  86:     public function get_class_name()
  87:     {
  88:         return get_class($this);
  89:     }
  90: 
  91:     /**
  92:      * Аналог метода get_class_name
  93:      * @return string
  94:      */
  95:     public function get_model_name()
  96:     {
  97:         return $this->get_class_name();
  98:     }
  99: 
 100:     /**
 101:      * Загрушка для функции получения данных о расширенных возможностях управления данными
 102:      * @return array
 103:      */
 104:     public function get_extrainfo()
 105:     {
 106:         return array();
 107:     }
 108: 
 109:     /**
 110:      * Заглушка получения информации о полях
 111:      * @return array
 112:      */
 113:     public function get_fieldinfo()
 114:     {
 115:         return array();
 116:     }
 117: 
 118:     /**
 119:      * Заглушка получения информации о таблице модели
 120:      * @return array
 121:      */
 122:     public function get_tableinfo()
 123:     {
 124:         return array();
 125:     }
 126: 
 127:     /**
 128:      * Заглушка получения информации о вкладках для оформления информации
 129:      *
 130:      * @return array
 131:      */
 132:     public function get_tabsinfo()
 133:     {
 134:         return array();
 135:     }
 136: 
 137:     /**
 138:      * Заглушка получения правил валидации полей модели
 139:      *
 140:      * @return array
 141:      */
 142:     protected function get_validate_rules()
 143:     {
 144:         return array();
 145:     }
 146: 
 147:     /**
 148:      * Получение массива ошибок валидации модели
 149:      *
 150:      * @return bool|array массив ошибок или
 151:      */
 152:     public function get_validation_error_messages()
 153:     {
 154:         return count($this->_validation_error_messages) > 0 ? $this->_validation_error_messages : false;
 155:     }
 156: 
 157:     /**
 158:      * Валидация полей модели
 159:      *
 160:      * @return boolean
 161:      */
 162:     public function validate()
 163:     {
 164:         $rules = $this->get_validate_rules();
 165: 
 166:         $valid = true;
 167:         foreach ($rules as $rule) {
 168:             $message = joosValidateHelper::valid($this->$rule[0], $rule[1], (isset($rule['message']) ? $rule['message'] : false));
 169:             if ($message !== TRUE) {
 170:                 $this->_validation_error_messages[$rule[0]][] = $message;
 171:                 $valid = false;
 172:             }
 173:             ;
 174:         }
 175: 
 176:         return $valid;
 177:     }
 178: 
 179:     /**
 180:      * Магический метод восстановления объекта
 181:      * Используется при прямом кэшировании модели
 182:      *
 183:      * @param array $values - массив значений востановленного объекта
 184:      *
 185:      * @return stdClass восстановленный объект модели
 186:      */
 187:     public static function __set_state(array $values)
 188:     {
 189:         // формируем объект по сохранённым параметрам
 190:         $obj = new $values['__obj_name']($values['_tbl'], $values['_tbl_key']);
 191:         // заполняем сохранёнными параметрами настоящие поля модели
 192:         $obj->bind($values);
 193: 
 194:         return $obj;
 195:     }
 196: 
 197:     /**
 198:      * Подготовка модели к кэшированию
 199:      * @return stdClass подготовленный к кэшированию объект
 200:      */
 201:     public function to_cache()
 202:     {
 203:         $obj = clone $this;
 204:         // удаляем ненужную ссылку на ресурс базы данных и стек ошибок
 205:         unset($obj->_db, $obj->_error);
 206:         // сохраняем оригинальное название модели
 207:         $obj->__obj_name = get_class($obj);
 208: 
 209:         return $obj;
 210:     }
 211: 
 212:     /**
 213:      * Возвращает название ключевого поя текущей модели
 214:      * @return string
 215:      */
 216:     public function get_key_field()
 217:     {
 218:         return $this->_tbl_key;
 219:     }
 220: 
 221:     /**
 222:      * Получение массива публичных свойств - полей текущей модели
 223:      * @staticvar string $cache статичная переменная для внутреннеего кеширования свойств
 224:      * @return array
 225:      */
 226:     public function get_public_properties()
 227:     {
 228:         static $cache = null;
 229: 
 230:         if ($cache===null) {
 231:             $cache = array();
 232:             foreach (get_class_vars(get_class($this)) as $key => $val) {
 233:                 if (substr($key, 0, 1) != '_') {
 234:                     $cache[] = $key;
 235:                 }
 236:             }
 237:         }
 238: 
 239:         return $cache;
 240:     }
 241: 
 242:     /**
 243:      * Очищает значения публоичных свойств модели от HTML тэгов
 244:      * Пример $this->filter( array('desc','extra') );
 245:      *
 246:      * @param array $ignoreList массив названий полей модели, которые НЕ требуется очистить от HTML кода
 247:      */
 248:     public function filter(array $ignoreList = null)
 249:     {
 250:         $ignore = is_array($ignoreList);
 251: 
 252:         $filter = joosInputFilter::instance();
 253:         foreach ($this->get_public_properties() as $k) {
 254: 
 255:             if ($ignore && in_array($k, $ignoreList)) {
 256: 
 257:                 continue;
 258:             }
 259:             $this->$k = $filter->process($this->$k);
 260:         }
 261:     }
 262: 
 263:     /**
 264:      * Получение текста ошибки при работе с текущей моделью
 265:      * @return string
 266:      */
 267:     public function get_errors()
 268:     {
 269:         return $this->_error;
 270:     }
 271: 
 272:     /**
 273:      * Получение значения поля
 274:      *
 275:      * @param string $_property название поля
 276:      *
 277:      * @return string значение поля
 278:      */
 279:     public function get($_property)
 280:     {
 281:         return isset($this->$_property) ? $this->$_property : null;
 282:     }
 283: 
 284:     /**
 285:      * Установка значения конкретного поля модели
 286:      *
 287:      * @param string $_property название модели
 288:      * @param string $_value    значение поля для установки
 289:      */
 290:     public function set($_property, $_value)
 291:     {
 292:         $this->$_property = $_value;
 293:     }
 294: 
 295:     /**
 296:      * Сброс значения полей активной модели
 297:      *
 298:      * @param string $value значение, устанавливаемое во все поля активной модели
 299:      */
 300:     public function reset($value = null)
 301:     {
 302:         $keys = $this->get_public_properties();
 303:         foreach ($keys as $k) {
 304: 
 305:             $this->$k = $value;
 306:         }
 307:     }
 308: 
 309:     /**
 310:      * Заполнение значения полей модели значениями ассоциативного массива
 311:      *
 312:      * @param array  $array  двумерный массив "название поля"=>"значение поля"
 313:      * @param string $ignore название аттрибута для игнорирования
 314:      *
 315:      * @return boolean результат заполнения
 316:      */
 317:     public function bind(array $array, $ignore = '')
 318:     {
 319:         return $this->_db->bind_array_to_object($array, $this, $ignore);
 320:     }
 321: 
 322:     /**
 323:      * Загрузка данных в модель непосредственно из БД по значению ключевого поля
 324:      * В случае успешного выполнения заполняет поля модели значениями из БД выбранными по ключевому полю
 325:      *
 326:      * @param integer $oid значение уникального ключевого поля, по которому необходимо делать выборку в БД
 327:      *
 328:      * @return boolean результат заполнения свойств модели
 329:      */
 330:     public function load($oid)
 331:     {
 332:         // сброс установок для обнуления назначенных ранее свойств объекта ( проблема с isset($obj->id) )
 333:         $this->reset();
 334: 
 335:         $query = 'SELECT * FROM ' . $this->_tbl . ' WHERE ' . $this->_tbl_key . ' = ' . $this->_db->get_quoted($oid);
 336:         $result = $this->_db->set_query($query)->load_object($this);
 337: 
 338:         $events_name = 'model.on_load.' . $this->get_class_name();
 339:         joosEvents::has_events($events_name) ? joosEvents::fire_events($events_name, $result, $this) : null;
 340: 
 341:         return $result;
 342:     }
 343: 
 344:     /**
 345:      * Загрузка данных в модель непосредственно из БД по значению произвольного поля
 346:      * В случае успешного выполнения заполняет поля модели значениями первого результата из БД выбранными по указанному
 347:      *
 348:      * @param string $field название произвольного поля модели
 349:      * @param string $value значение произвольного поля модели
 350:      *
 351:      * @return boolean результат заполнения свойств модели
 352:      */
 353:     public function load_by_field($field, $value)
 354:     {
 355:         $this->reset();
 356: 
 357:         $query = 'SELECT * FROM ' . $this->_db->get_name_quote($this->_tbl) . ' WHERE ' . $this->_db->get_name_quote($field) . ' = ' . $this->_db->get_quoted($value);
 358: 
 359:         return $this->_db->set_query($query, 0, 1)->load_object($this);
 360:     }
 361: 
 362:     /**
 363:      * Сохранение свойств модели в БД
 364:      * Производит непосредственно запись в БД значений заполненных полей модели. При этом сами свойства должны быть указаны ранее, методом bind, либо set, либо прямого присвоения $news->title='Новость 1'
 365:      *
 366:      * @param bool $update_nulls  флаг обновления неопределённых свойств
 367:      * @param bool $forced_Insert флаг принудительной вставки. Необходимо в случаях, когда значение ключевого поля уже задано, но всё-равно необходимо создать новую запись (например, в компоненте категорий: category_id известно, но в таблице `categories_details` нужно создать запись с этим ключом )
 368:      *
 369:      * @return boolean результат сохранения модели
 370:      */
 371:     public function store($update_nulls = false, $forced_Insert = false)
 372:     {
 373:         $k = $this->_tbl_key;
 374: 
 375:         $this->before_store();
 376: 
 377:         if ((isset($this->$k) && $this->$k != 0) && !$forced_Insert) {
 378: 
 379:             // дата последней модификации
 380:             if (property_exists($this, 'modified_at') && $this->modified_at == null) {
 381:                 $this->modified_at = JCURRENT_SERVER_TIME;
 382:             }
 383: 
 384:             $this->before_update();
 385:             $ret = $this->_db->update_object($this->_tbl, $this, $this->_tbl_key, $update_nulls);
 386:             $this->after_update();
 387:         } else {
 388: 
 389:             // дата создания объекта
 390:             if (property_exists($this, 'created_at') && $this->created_at == null) {
 391:                 $this->created_at = JCURRENT_SERVER_TIME;
 392:             }
 393: 
 394:             $this->before_insert();
 395:             $ret = $this->_db->insert_object($this->_tbl, $this, $this->_tbl_key);
 396:             $this->after_insert();
 397:         }
 398: 
 399:         if (!$ret) {
 400:             return false;
 401:         } else {
 402:             $this->after_store();
 403: 
 404:             return true;
 405:         }
 406:     }
 407: 
 408:     /**
 409:      * Прямое обновление значения полей объекта модели
 410:      *
 411:      * @return bool результат выполнения обновления
 412:      */
 413:     public function update()
 414:     {
 415:         return (bool) $this->_db->update_object($this->_tbl, $this, $this->_tbl_key, false);
 416:     }
 417: 
 418:     /**
 419:      * Переопределяемая функция проверки правильности заполнения полей модели
 420:      *
 421:      * @return boolean результат проверки
 422:      */
 423:     public function check()
 424:     {
 425:         return true;
 426:     }
 427: 
 428:     /**
 429:      * Метод, выполняемый до обновления значений модели
 430:      *
 431:      * @return boolean
 432:      */
 433:     protected function before_update()
 434:     {
 435:         return true;
 436:     }
 437: 
 438:     /**
 439:      * Метод, выполняемый после обновления значений модели
 440:      *
 441:      * @return boolean
 442:      */
 443:     protected function after_update()
 444:     {
 445:         return true;
 446:     }
 447: 
 448:     /**
 449:      * Метод выполняемый до добавления значений модели
 450:      *
 451:      * @return boolean
 452:      */
 453:     protected function before_insert()
 454:     {
 455:         return true;
 456:     }
 457: 
 458:     /**
 459:      * Метод выполняемый после вставки значений модели
 460:      *
 461:      * @return boolean
 462:      */
 463:     protected function after_insert()
 464:     {
 465:         return true;
 466:     }
 467: 
 468:     /**
 469:      * Метод выполняемый до сохранения значений модели ( вставка / обновление )
 470:      *
 471:      * @return boolean
 472:      */
 473:     protected function before_store()
 474:     {
 475:         return true;
 476:     }
 477: 
 478:     /**
 479:      * Метод выполняемый после полного сохранения данных модели ( вставка / обновление )
 480:      *
 481:      * @return boolean
 482:      */
 483:     protected function after_store()
 484:     {
 485:         return true;
 486:     }
 487: 
 488:     /**
 489:      * Метод выполняемый до удаления конкретной записи модели
 490:      *
 491:      * @return boolean
 492:      */
 493:     protected function before_delete()
 494:     {
 495:         return true;
 496:     }
 497: 
 498:     /**
 499:      * Метод выполняемый после удаления конкретной записи модели
 500:      *
 501:      * @return boolean
 502:      */
 503:     protected function after_delete()
 504:     {
 505:         return true;
 506:     }
 507: 
 508:     /**
 509:      * Удаление записи в БД по значению ключевого поля
 510:      * Производит непосредственное удаление записи из БД
 511:      *
 512:      * @param mixed $oid значение ключевого поля
 513:      *
 514:      * @return boolean результат удаления
 515:      */
 516:     public function delete($oid)
 517:     {
 518:         $k = $this->_tbl_key;
 519: 
 520:         if ($oid) {
 521:             $this->$k = (int) $oid;
 522:         }
 523: 
 524:         $this->before_delete();
 525: 
 526:         // активируем "мягкое удаление", т.е. сохраняем копию в корзине
 527:         if ($this->_soft_delete) {
 528:             joosTrash::add($this);
 529:         }
 530: 
 531:         $query = "DELETE FROM $this->_tbl WHERE $this->_tbl_key = " . $this->_db->get_quoted($this->$k);
 532:         $this->_db->set_query($query);
 533: 
 534:         if ($this->_db->query()) {
 535:             $this->after_delete();
 536: 
 537:             return true;
 538:         } else {
 539:             return false;
 540:         }
 541:     }
 542: 
 543:     /**
 544:      * Удаление неограниченного числа записей в БД через указание массива значений ключевого, либо произвольного поля
 545:      * Производит непосредственное удаление записей из БД принимая массив значений вида array(1,15,16,22)
 546:      *
 547:      * @param array       $oid   массив значений ключевого
 548:      * @param string|bool $key   название ключевого поля, по умолчанию - название ключевого поля текущей модели
 549:      * @param string|bool $table название таблицы, в которой необходимо произвести удаление, по умолчанию - таблица текущей модели
 550:      *
 551:      * @return boolean результат удаления записей
 552:      */
 553:     public function delete_array(array $oid = array(), $key = false, $table = false)
 554:     {
 555:         $key = $key ? $key : $this->_tbl_key;
 556:         $table = $table ? $table : $this->_tbl;
 557: 
 558:         $table = $this->_db->get_name_quote($table);
 559: 
 560:         // "мягкое" удаление объектов
 561:         if ($this->_soft_delete) {
 562: 
 563:             $obj = clone $this;
 564:             foreach ($oid as $cur_id) {
 565:                 $obj->load($cur_id);
 566:                 joosTrash::add($obj);
 567:                 $obj->reset();
 568:             }
 569:             unset($obj);
 570:         }
 571: 
 572:         $obj = clone $this;
 573:         foreach ($oid as &$cur_id) {
 574:             $obj->{$key} = $cur_id;
 575:             $obj->before_delete();
 576:             $cur_id = $this->_db->get_quoted($cur_id);
 577:         }
 578: 
 579:         $query = "DELETE FROM $table WHERE $key IN (" . implode(',', $oid) . ')';
 580: 
 581:         if ($this->_db->set_query($query)->query()) {
 582:             return true;
 583:         } else {
 584:             return false;
 585:         }
 586:     }
 587: 
 588:     /**
 589:      * Удаление элементов в БД через указание произвольных условий
 590:      *
 591:      * @param array $params массив параметров для формирования условий удаления
 592:      *
 593:      * @return boolean результат удаления
 594:      */
 595:     public function delete_list(array $params = array())
 596:     {
 597:         $where = isset($params['where']) ? 'WHERE ' . $params['where'] . "\n" : '';
 598: 
 599:         $this->_db->set_query("DELETE FROM $this->_tbl " . $where);
 600: 
 601:         if ($this->_db->query()) {
 602:             return true;
 603:         } else {
 604:             return false;
 605:         }
 606:     }
 607: 
 608:     /**
 609:      * Копирование неограниченного числа записей в БД через указание массива значений ключевого, либо произвольного поля
 610:      *
 611:      * @param array       $oid   массив значений ключевого
 612:      * @param string|bool $key   название ключевого поля, по умолчанию - название ключевого поля текущей модели
 613:      * @param string|bool $table название таблицы, в которой необходимо произвести копирование, по умолчанию - таблица текущей модели
 614:      *
 615:      * @return boolean результат копирования записей
 616:      */
 617:     public function copy_array(array $oid = array(), $key = false, $table = false)
 618:     {
 619:         $key = $key ? $key : $this->_tbl_key;
 620:         $table = $table ? $table : $this->_tbl;
 621: 
 622:         $table = $this->_db->get_name_quote($table);
 623: 
 624:         $query = "SELECT * FROM $table WHERE $key IN (" . implode(',', $oid) . ')';
 625:         $rows = $this->_db->set_query($query)->load_object_list();
 626: 
 627:         foreach ($rows as $row) {
 628: 
 629:             $row->$key = null;
 630:             $this->_db->insert_object($this->_tbl, $row, $this->_tbl_key);
 631:         }
 632: 
 633:         return true;
 634:     }
 635: 
 636:     /**
 637:      * Сохранение свойств модели в БД
 638:      *
 639:      * @param array  $source массив свойств название поля=>значение поля для заполнения свойств модели ( см. self::bind )
 640:      * @param string $ignore название аттрибута для игнорирования
 641:      *
 642:      * @return boolean результат сохранения
 643:      */
 644:     public function save(array $source, $ignore = '')
 645:     {
 646:         if ($source && !$this->bind($source, $ignore)) {
 647:             return false;
 648:         }
 649:         if (!$this->check()) {
 650:             return false;
 651:         }
 652: 
 653:         if (!$this->store()) {
 654:             return false;
 655:         }
 656: 
 657:         $this->_error = '';
 658: 
 659:         return true;
 660:     }
 661: 
 662:     /**
 663:      * @param array $cid
 664:      * @param int   $state
 665:      *
 666:      * @return bool
 667:      */
 668:     public function set_state_group(array $cid = null, $state = 1)
 669:     {
 670:         if (count($cid) < 1) {
 671:             $this->_error = 'Ничего не было выбрано';
 672: 
 673:             return false;
 674:         }
 675: 
 676:         $cids = $this->_tbl_key . '=' . implode(' OR ' . $this->_tbl_key . '=', $cid);
 677: 
 678:         $query = "UPDATE $this->_tbl SET state = " . (int) $state . " WHERE ($cids)";
 679: 
 680:         if (!$this->_db->set_query($query)->query()) {
 681:             return false;
 682:         }
 683: 
 684:         $this->_error = '';
 685: 
 686:         return true;
 687:     }
 688: 
 689:     /**
 690:      * Булево изменение содержимого указанного столбца. Используется для смены статуса элемента
 691:      * Меняет значение указанного поля на противопложное
 692:      *
 693:      * @param string $field_name название свойства модели для изменения на противоположное
 694:      *
 695:      * @return boolean результат смены значения поля
 696:      */
 697:     public function change_state($field_name)
 698:     {
 699:         $key = $this->{$this->_tbl_key};
 700: 
 701:         return $this->_db->set_query("UPDATE `$this->_tbl` SET `$field_name` = !`$field_name` WHERE $this->_tbl_key = $key", 0, 1)->query();
 702:     }
 703: 
 704:     /**
 705:      * Возвращает число записей в таблице БД активной модели
 706:      *
 707:      * @param string $where дополнительное условие для подсчета числа записей, например "WHERE state=1"
 708:      *
 709:      * @return int число записей
 710:      */
 711:     public function count($where = '')
 712:     {
 713:         $sql = "SELECT count(*) FROM $this->_tbl " . $where;
 714: 
 715:         return $this->_db->set_query($sql)->load_result();
 716:     }
 717: 
 718:     /**
 719:      * Возвращает сумму по определенному полю
 720:      *
 721:      * @param string $field поле, по которому считаем
 722:      * @param string $where дополнительное условие
 723:      *
 724:      * @return int число записей
 725:      */
 726:     public function sum($field, $where = '')
 727:     {
 728:         $sql = "SELECT sum($field) FROM $this->_tbl " . $where;
 729: 
 730:         return $this->_db->set_query($sql)->load_result();
 731:     }
 732: 
 733:     /**
 734:      * Возвращает массив результатов выборки
 735:      *
 736:      * @param array $params массив параметров для уточнее области выборки результата
 737:      *     <pre>
 738:      *         select - список поле для выборки, по умолчанию * (все поля)
 739:      *         where - условие WHERE для выборки
 740:      *         join - данные о объединённой выборке с использованием сторонних таблиц
 741:      *         group - название поля для группировки результата, пример - " user_id "
 742:      *         order - название поля и направление сортировки результата, пример - " id DESC ", либо "id DESC, title ASC"
 743:      *         offset - смещение для выборки результата, по умолчанию - 0
 744:      *         limit - лимит выборки для результата, по молчанию - 0, т.е. ВСЕ записи
 745:      *         key - название ключевого поля, для использования в качестве ключа ассоциативного массива результатов. По умолчанию использует ключевое поле модели. key=>FALSE если необходимо сделать простой массив ( 0=>array(),1=>array() )
 746:      *     <pre>
 747:      *
 748:      * @return array ассоциативный или обычный массив результатов
 749:      */
 750:     public function get_list(array $params = array())
 751:     {
 752:         $tbl_key = isset($params['key']) ? $params['key'] : null;
 753: 
 754:         return $this->_db->set_query($this->get_query_list($params))->load_object_list($tbl_key);
 755:     }
 756: 
 757:     /**
 758:      * Функция, формирующая SQL-запрос для метода get_list()
 759:      *
 760:      * @param  array  $params Те же параметры, что и для get_list
 761:      * @return string SQL-запрос
 762:      */
 763:     private function get_query_list($params)
 764:     {
 765:         $select = isset($params['select']) ? $params['select'] . "\n" : '*';
 766:         $where = isset($params['where']) ? 'WHERE ' . $params['where'] . "\n" : '';
 767:         $join = isset($params['join']) ? $params['join'] . "\n" : '';
 768:         $group = isset($params['group']) ? 'GROUP BY ' . $params['group'] . "\n" : '';
 769:         $order = isset($params['order']) ? 'ORDER BY ' . $params['order'] . "\n" : '';
 770:         $pseudonim = isset($params['pseudonim']) ? ' AS ' . $params['pseudonim'] . ' ' : '';
 771: 
 772:         $limit = isset($params['limit']) ? 'LIMIT ' . $params['limit'] . "\n" : '';
 773:         $limit = (isset($params['limit']) && isset($params['offset'])) ? 'LIMIT ' . $params['offset'] . ',' . $params['limit'] . "\n" : $limit;
 774: 
 775:         return "SELECT $select FROM $this->_tbl $pseudonim $join " . $where . $group . $order . $limit;
 776:     }
 777: 
 778:     /**
 779:      * Версия метода get_list с кэшированием
 780:      *
 781:      * @param  array $params     Те же параметры, что и для get_list
 782:      * @param  int   $cache_time Время жизни кэша
 783:      * @return array Закэшированное значение
 784:      */
 785:     public function get_list_cache(array $params = array(), $cache_time = 86400)
 786:     {
 787:         $cache = joosCache::instance();
 788:         $key = md5($this->get_query_list($params));
 789: 
 790:         if (($value = $cache->get($key)) === NULL) {
 791: 
 792:             $value = $this->get_list($params);
 793:             $cache->set($key, $value, $cache_time);
 794:         }
 795: 
 796:         return $value;
 797:     }
 798: 
 799:     /**
 800:      * Возвращает ассоциативный двумерный массив возможных значений модели
 801:      *
 802:      * @param array $key_val - массив array( 'key'=>'название поля - ключа','value'=>'название поля - значения' ). По умолчанияю key=>id, value=>title
 803:      * @param array $params  массив параметров для уточнее области выборки результата
 804:      *     <pre>
 805:      *         select - список поле для выборки, по умолчанию key,value (поля указанные в $key_val)
 806:      *         where - условие WHERE для выборки
 807:      *         order - название поля и направление сортировки результата, пример - " id DESC ", либо "id DESC, title ASC"
 808:      *         offset - смещение для выборки результата, по умолчанию - 0
 809:      *         limit - лимит выборки для результата, по молчанию - 0, т.е. ВСЕ записи
 810:      *         table - название таблицы, из которой необходимо сделать выборку. По умолчанию - таблица текущей модели
 811:      *     <pre>
 812:      *
 813:      * @return array - ассоциативный массив результата
 814:      */
 815:     public function get_selector(array $key_val = array(), array $params = array())
 816:     {
 817:         $key = isset($key_val['key']) ? $key_val['key'] : 'id';
 818:         $value = isset($key_val['value']) ? $key_val['value'] : 'title';
 819: 
 820:         $select = isset($params['select']) ? $params['select'] : $key . ',' . $value;
 821:         $where = isset($params['where']) ? 'WHERE ' . $params['where'] : '';
 822:         $order = isset($params['order']) ? ' ORDER BY ' . $params['order'] : '';
 823:         $offset = isset($params['offset']) ? (int) $params['offset'] : 0;
 824:         $limit = isset($params['limit']) ? (int) $params['limit'] : 0;
 825:         $tablename = isset($params['table']) ? $params['table'] : $this->_tbl;
 826: 
 827:         $opts = $this->_db->set_query("SELECT $select FROM $tablename " . $where . $order, $offset, $limit)->load_assoc_list();
 828: 
 829:         $return = array();
 830:         foreach ($opts as $opt) {
 831:             $return[$opt[$key]] = $opt[$value];
 832:         }
 833: 
 834:         return $return;
 835:     }
 836: 
 837:     // отношение один-ко-многим, список выбранных значений из многих
 838:     public function get_select_one_to_many($table_values, $table_keys, $key_parent, $key_children, array $params = array())
 839:     {
 840:         $select = isset($params['select']) ? $params['select'] : 't_val.*';
 841:         $where = isset($params['where']) ? 'WHERE ' . $params['where'] : "WHERE t_key.$key_parent = $this->{$this->_tbl_key} ";
 842:         $order = isset($params['order']) ? 'ORDER BY ' . $params['order'] : '';
 843:         $offset = isset($params['offset']) ? (int) $params['offset'] : 0;
 844:         $limit = isset($params['limit']) ? (int) $params['limit'] : 0;
 845:         $join = isset($params['join']) ? $params['join'] : 'LEFT JOIN';
 846: 
 847:         $sql = "SELECT $select FROM $table_values AS t_val $join $table_keys AS  t_key ON t_val.id=t_key.$key_children $where $order";
 848: 
 849:         return $this->_db->set_query($sql, $offset, $limit)->load_assoc_list('id');
 850:     }
 851: 
 852:     // сохранение значение одного ко многим
 853:     public function save_one_to_many($name_table_keys, $key_name, $value_name, $key_value, array $values)
 854:     {
 855:         if ($key_value == null || $key_value == '') {
 856:             return false;
 857:         }
 858: 
 859:         //сначала чистим все предыдущие связи
 860:         $this->_db->set_query("DELETE FROM $name_table_keys WHERE $key_name=$key_value ")->query();
 861: 
 862:         // фомируем массив сохраняемых значений
 863:         $vals = array();
 864:         foreach ($values as $value) {
 865:             $vals[] = " ($key_value, $value  ) ";
 866:         }
 867: 
 868:         if (count($vals) == 0) {
 869:             return true;
 870:         }
 871: 
 872:         $values = implode(',', $vals);
 873: 
 874:         $sql = "INSERT IGNORE INTO $name_table_keys ( $key_name,$value_name ) VALUES $values";
 875: 
 876:         return $this->_db->set_query($sql)->query();
 877:     }
 878: 
 879:     // селектор выбора отношений один-ко-многим
 880:     public function get_one_to_many_selectors($name, $table_values, $table_keys, $key_parent, $key_children, array $selected_ids = array(), array $params = array())
 881:     {
 882:         $params['select'] = isset($params['select']) ? $params['select'] : 't_val.id, t_val.title';
 883:         $params['select_children'] = isset($params['select_children']) ? $params['select_children'] : array();
 884: 
 885:         $childrens = $this->get_selector($params['select_children'], array('table' => $table_values));
 886: 
 887:         $rets = array();
 888:         foreach ($childrens as $key => $value) {
 889:             $el_id = $name . $key;
 890:             $checked = (bool) isset($selected_ids[$key]);
 891:             $rets[] = '<label class="checkbox">';
 892:             $rets[] = joosHtml::checkbox($name . '[]', $key, $checked, 'id="' . $el_id . '" ');
 893:             $rets[] = $value;
 894:             $rets[] = '</label>';
 895:             //$rets[] = forms::label($el_id, $value);
 896:         }
 897: 
 898:         return implode("\n\t", $rets);
 899:     }
 900: 
 901:     /**
 902:      * Загрузка значение текущей модели через указание произвольных свойств модели
 903:      *
 904:      * @param array $params массив параметров для условий выборки
 905:      *
 906:      * @return boolean результат поиска и загрузки значений в свойства текущей модели
 907:      */
 908:     public function find(array $params = array('select' => '*'))
 909:     {
 910:         $query = $this->get_find_query_from_params($params);
 911: 
 912:         return $query === false ? false : $this->_db->set_query($query)->load_object($this);
 913:     }
 914: 
 915:     /**
 916:      * Построение строки запроса из параметров метода find();
 917:      *
 918:      * @param $params массив параметров запроса
 919:      * @return bool|string
 920:      */
 921:     private function get_find_query_from_params($params)
 922:     {
 923:         $fmtsql = "SELECT {$params['select']} FROM $this->_tbl WHERE %s";
 924:         $tmp = array();
 925:         foreach (get_object_vars($this) as $k => $v) {
 926: 
 927:             if (is_array($v) or is_object($v) or $k[0] == '_' or $v===null) {
 928:                 continue;
 929:             }
 930: 
 931:             $v = strval($v);
 932: 
 933:             if ($v == '') {
 934:                 $val = "''";
 935:             } else {
 936:                 $val = $this->_db->get_quoted($v);
 937:             }
 938: 
 939:             $tmp[] = $this->_db->get_name_quote($k) . '=' . $val;
 940:         }
 941: 
 942:         // если в параметрах не было ни одного заполненного поля
 943:         if (count($tmp) == 0) {
 944: 
 945:             return false;
 946:         }
 947: 
 948:         return sprintf($fmtsql, implode(' AND ', $tmp));
 949:     }
 950: 
 951:     /**
 952:      * Кэширующая обертка над фунцией find
 953:      *
 954:      * @param  array   $params     Параметры к методу find
 955:      * @param  int     $cache_time Время кэширования
 956:      * @return boolean Найденный объект
 957:      *
 958:      * @todo проверить обоснованность использования $find_result
 959:      */
 960:     public function find_cache(array $params = array('select' => '*'), $cache_time = 86400)
 961:     {
 962:         $cache = joosCache::instance();
 963:         $key = md5($this->get_find_query_from_params($params));
 964: 
 965:         if (($value = $cache->get($key)) === NULL) {
 966: 
 967:             $find_result = $this->find($params);
 968:             //в кэше надо хранить не только значение, но еще и результат поиска
 969:             $cache->set($key, array($find_result, $this->to_cache()), $cache_time);
 970:         } else {
 971: 
 972:             //достаем объект и мэппим его поля на текущий объект
 973:             list($find_result, $obj) = $value;
 974:             foreach ($obj as $k => $v) {
 975: 
 976:                 $this->$k = $v;
 977:             }
 978:         }
 979: 
 980:         return $find_result;
 981:     }
 982: 
 983:     /**
 984:      * Поиск записей, удовлетворяющих указаным свойствам объекта
 985:      *
 986:      * @param array $params массив параметров для уточнения области поиска записей
 987:      *     <pre>
 988:      *         select - список поле для выборки, по умолчанию * (все поля)
 989:      *         where - условие WHERE для выборки
 990:      *         order - название поля и направление сортировки результата, пример - " id DESC ", либо "id DESC, title ASC"
 991:      *         offset - смещение для выборки результата, по умолчанию - 0
 992:      *         limit - лимит выборки для результата, по молчанию - 0, т.е. ВСЕ записи
 993:      *         key - название ключевого поля, для использования в качестве ключа ассоциативного массива результатов. По умолчанию использует ключевое поле модели. key=>FALSE если необходимо сделать простой массив ( 0=>array(),1=>array() )
 994:      *     <pre>
 995:      *
 996:      * @return array ассоциативный массив результата поиска
 997:      */
 998:     public function find_all(array $params = array())
 999:     {
1000:         $def_param = array('select' => '*');
1001:         $params += $def_param;
1002:         $fmtsql = "SELECT {$params['select']} FROM $this->_tbl WHERE %s";
1003:         $fmtsql .= isset($params['order']) ? ' ORDER BY ' . $params['order'] : '';
1004: 
1005:         $tmp = array();
1006: 
1007:         if (isset($params['where'])) {
1008:             $tmp[] = $params['where'];
1009:         }
1010: 
1011:         foreach (get_object_vars($this) as $k => $v) {
1012: 
1013:             if (is_array($v) or is_object($v) or $k[0] == '_' or empty($v)) {
1014:                 continue;
1015:             }
1016: 
1017:             $v = strval($v);
1018: 
1019:             if ($v == '') {
1020:                 $val = "''";
1021:             } else {
1022:                 $val = $this->_db->get_quoted($v);
1023:             }
1024:             $tmp[] = $this->_db->get_name_quote($k) . '=' . $val;
1025:         }
1026:         $tmp = count($tmp) > 0 ? $tmp : array('true');
1027: 
1028:         $offset = isset($params['offset']) ? (int) $params['offset'] : 0;
1029:         $limit = isset($params['limit']) ? (int) $params['limit'] : 0;
1030: 
1031:         $tbl_key = isset($params['key']) ? $params['key'] : $this->_tbl_key;
1032: 
1033:         return $this->_db->set_query(sprintf($fmtsql, implode(' AND ', $tmp)), $offset, $limit)->load_object_list($tbl_key);
1034:     }
1035: 
1036:     /**
1037:      * Возвращает максимальное значение по заданному полю
1038:      *
1039:      * @param string $name Имя поля
1040:      *
1041:      * @return integer максимальное значение
1042:      */
1043:     public function get_max_by_field($name)
1044:     {
1045:         $query = 'SELECT  ' . $name . ' AS max FROM ' . $this->_tbl . ' ORDER BY  ' . $name . ' DESC';
1046: 
1047:         return $this->_db->set_query($query)->load_result();
1048:     }
1049: 
1050:     /**
1051:      * Вставка массива значений в таблицу текущего объекта
1052:      *
1053:      * @example
1054:      * $values = array(
1055:      *      0 => array(
1056:      *          'counter' => 111,
1057:      *          'name' => 'первая запись',
1058:      *      ),
1059:      *      1 => array(
1060:      *          'name' => ' вторая запись ',
1061:      *          'counter' => 2222
1062:      *      ),
1063:      *      2 => array(
1064:      *          'name' => ' третья запись',
1065:      *          'counter' => 123456
1066:      *      ),
1067:      * );
1068:      *
1069:      * @param  array $array_values
1070:      * @return bool  результат вставки массива
1071:      */
1072:     public function insert_array(array $array_values)
1073:     {
1074:         return $this->_db->insert_array($this->_tbl, $this, $array_values);
1075:     }
1076: 
1077:     // @todo обновление неограниченного числа записей
1078:     public function update_all( $attributes, $condition, $params )
1079:     {
1080:     }
1081: 
1082: }
1083: 
1084: /**
1085:  * Обработка ошибок работы с базой данных
1086:  *
1087:  */
1088: class joosDatabaseException extends joosException
1089: {
1090:     public function __construct($message = '', array $params = array())
1091:     {
1092:         if (JDEBUG) {
1093:             // при включенной отладке покажем полные данные о ошибке
1094:             parent::__construct(strtr($message, $params));
1095:         } else {
1096:             // при выключенной отладке - общую информацию о системе
1097:             joosPages::error_database(strtr($message, $params));
1098: 
1099:         }
1100: 
1101:     }
1102: 
1103: }
1104: 
Joostina CMS / CMF v2.* API API documentation generated by ApiGen 2.6.1 – Template adapted by @olvlv and Joostina Team