Свои sql запросы в ICMS2

+18
4.3K
Это скорее всего напоминание себе, но пригодится многим, кто пытается адаптировать свои наработки под ICMS2.

Суть в том, что не всегда есть время перевести sql запросы под стандартные запросы в файле model.php у какого-либо компонента.

Поэтому авторы icms2 внедрили все что нам нужно, но не о всем рассказали. Я попробую прояснить один такой фокус.

Например У вас идет большая выборка с перечисление многих параметров и выбирать надо несколько таблиц или столбцов. То для тех, кто плохо знаком с моделью запросов простой выход будет сделать вот так:

Открываем файл model.php вашего компонента.

создаем функцию:

  1.  
  2. public function poiskAbonent($query) { }
  3.  
под переменной $query может быть любая переменная которую вы передаете из action.

Далее как нам выполнить сам запрос в базу?
Да очень просто
Задаем таблицу для запроса

  1.  
  2. $table_name='dogovora';// тут вы можете приравнять переменной, чтоб был запрос универсальнее
  3. $sql="SELECT * FROM cms_".$table_name." WHERE name='ИМЯ' OR name LIKE %'.$query.' %";
  4.  
  5.  
В запрос sql вы можете вставлять любые переменные, главное помнить правильность написания запроса.

Далее нам надо вызвать команду, которая и выполнит данный запрос.
Это будет
  1. $sql_result = $this->db->query($sql);
Тут мы просто просим средствами ICMS2 выполнить sql запрос.

Далее мы получим массив, который надо обработать

  1. while ($item = $this->db->fetchAssoc($sql_result)){ }
Для удобства все операторы совпадают с общепринятыми операторами в SQL, что позволит не трактовать по разному ожидаемый результат.


Ну и общая картинка у нас получается вот такая:


  1. public function poiskAbonent($query){
  2. $table_name='dogovora';
  3. $sql="SELECT * FROM cms_".$table_name." WHERE name='ИМЯ' OR name LIKE %'.$query.' %";
  4.  
  5. $sql_result = $this->db->query($sql);
  6.  
  7. //проверяем есть ли что для нас по запросу
  8. if (!$this->db->numRows($sql_result)){
  9. return false;
  10. }
  11.  
  12. //объявляем массив для переменных
  13. $items = array();
  14.  
  15. //пробегаемся по массиву полученному от запроса
  16. while ($item = $this->db->fetchAssoc($sql_result)){
  17.  
  18. $items[] = $item;
  19. }
  20.  
  21. return $items;
  22.  
  23. }

Код не идеален, можно подправлять и добавлять.

Ну а в tpl файле незабываем, что нам надо массив $items перебрать чтоб все полученное вывести:

  1.  
  2. <?php foreach($results as $item){ ?>
  3.  
  4. вывод переменной: <?php html($item['name']); ?>
  5.  
  6. <? } ?>
Важно, что в action вы должны запрос из model.php вызвать.
  1.  
  2. public function search($query){
  3.  
  4.  
  5. $results=$this->model->poiskAbonent($query);
  6.  
  7. return $results;
  8.  
  9. }
Поэтому в запросе у меня items, а в tpl я перебираю $results

Спасибо ВСЕМ, кто активно помогает разбирать вопросы на форуме.
+1
Yurik Yurik 8 лет назад #
а что мешает использовать готовые методы класса cmsModel ?
для примера под Ваш запрос (в модели):
Код PHP:
  1. public function search($query){
  2. $model->filterStart();
  3. $model->filterEqual('name', 'ИМЯ');
  4. $model->filterOr();
  5. $model->filterLike('name', '%' . $query . '%');
  6. $model->filterEnd();
  7. return $model->get('dogovora');
  8. }
0
Yurik Yurik 8 лет назад #
поправочка, вместо $model - $this
0
kirkr kirkr 8 лет назад #
Вторая строка :
Суть в том, что не всегда есть время перевести sql запросы под стандартные запросы в файле model.php у какого-либо компонента.
и далее указал
Код не идеален, можно подправлять и добавлять.

так что чем больше вариантов, тем проще всем ;)
+1
My-InstantCMS.Ru My-InstantCMS.Ru 8 лет назад #
в место префикса cms_ напишете cms_
0
Старый балбес Старый балбес 8 лет назад #
в место префикса cms_ напишете cms_
Это неверно в отношении поданной задачи.
достаточно в конструктор frontend компонента определить
Код PHP:
  1. public function __construct($request) {
  2. parent::__construct($request);
  3. # core
  4. $this->core = cmsCore::getInstance();
  5. # префикс
  6. $this->prefix = $this->core->db->prefix;
  7. }
B тогда выполнение запросов во фронте или модели компонента выполняется так
Код PHP:
  1. # Для ассоциативного массива одной записи
  2. $query = ("Запрос");
  3. if($this->core->db->numRows($query)){
  4. $query_row = $this->core->db->fetchAssoc($query);
  5. return $query_row;
  6. }else {return false;}
  7. # Для многомерного массива
  8. $query = ("Запрос");
  9. $query_rows= array();
  10. if($this->core->db->numRows($query)){
  11. while($data_res = $this->core->db->fetchAssoc($query)){
  12. $query_rows[] = $data_res;
  13. }
  14. return $query_rows;
  15. }else {return false;}
Во всех подключаемых файлах моделей - к основной модели компонента, доступен доступ к методам
Код PHP:
  1. через $this->core->db и $this->prefix
.
+2
Fuze Fuze 8 лет назад #
Геннадий Иванович, только не поймите превратно v

$this->prefix = $this->core->db->prefix;
зачем в свойство контроллера передавать префикс базы данных? И в вашем примере ниже он не используется, вы вероятно предполагали, что будут писать
Код PHP:
  1. $query = ("{$this->prefix}Запрос");
Контроллер не работает с базой, он о ней вообще не знает по идее. Он знает о модели (если таковая есть), а модель знает о базе. Это в идеале.
Могу понять (гипотетически) передачу в свойство модели префикс и то это вызывает большие сомнения. Но, как говорится, хозяин-барин.
$this->core = cmsCore::getInstance();
тогда уже, учитывая ваш пример,
Код PHP:
  1. $this->db = cmsDatabase::getInstance();
Кроме этого, если мы обратимся к классу БД, то увидим
Код PHP:
  1. $sql = str_replace('cms_', $this->prefix, $sql);
Соответственно жестко писать префикс в запросах не имеет никакого смысла и комментарий выше
Evanescence:
в место префикса cms_ напишете cms_
самый правильный в данном контексте.

И самое важное. Объект базы данных оправдано использовать (опять же в идеале):
а) в модели
б) для сложных запросов, которые нельзя выполнить стандартными методами основной модели, например вот такой

Код SQL:
  1. DELETE FROM `cms_auth_logs` WHERE id IN (SELECT id FROM (SELECT id FROM `cms_auth_logs` WHERE user_id = '{$user_id}' ORDER BY `id` DESC LIMIT {$this->options['limit']}, 10) AS x)
+1
Yurik Yurik 8 лет назад #
как на меня, так мало тех. документации... что немного "штопорит" разработку под общий стиль в системе
0
Старый балбес Старый балбес 8 лет назад #
Нечего не мешает если это простой запрос и разработчик выполняющий это задание имеет уже измененный характер к подходу о выполнении запросов предлагаемых самой (идеологией) в рамках системы.
Такой подход имеет определенный плюс
1- ПЛЮС _ для молодых разработчиков которые постепенно вросли и поняли идеологию двойки, поняли суть типов контента
а-простая формулировка запросов
б- простое восприятие выполняемых запросов
с- легкая обучаемость и ассоциативная запоминаемость выполняемых действий
2- МИНУС _ для молодых кадров понятие $model->filterEqual('name', 'ИМЯ'); однозначно в дальнейшей жизни кроме инстанта и не понадобится.
Подвожу итог.
Двойка неоднозначная система.
И заявление - (не программистов а простых пользователей, хоть и с мудреным умом и опытом ) - что : Я,
ВСЕ МОГУ ТИПАМИ КОНТЕНТА выполнить...
Меня всегда приводит к поднятию настроения и понимания что если тебя никто не ограничил в рамках используемой системы , то это просто нереальная фантастика.

Но прямой запрос будет отправлен на обработку быстрее.
Это и ранее называлось
0
kirkr kirkr 8 лет назад #
Не все так печально, даже наоборот. Единственное что сейчас ограничивает многих и меня - отсутствие документации. Поэтому очень хорошо помогает форум.
Начинается все с файлов module.php у других компонентов, но в главном файле модуль.пхп все намного богаче и куча вариаций.

Я привел данный пример лишь для того, чтоб проблема с запросом не тормозила разработку, а когда результат получен и остальные ошибки подправлены, то можно изучить детальнее файлик module.php

Не знаю надо нет написать про динамичные формы в ICMS2, мне помогли разобраться на форуме. Когда уже их сам наделал несколько штук, то форма вызова всего кажется очень простой и понятной. И подключение одного компонента в другом реализовано очень просто.

Еще от автора

Политика безопасности и соглашение
Много споров было что в текст публиковать.
Google & Yandex баннеры в компоненты Banners
Добрый день! Была поставлена задача добавить возможность выводить через позиции {Баннер=номер позиции} баннеры гугла и яндекса.
Готовим сервер VDS Nginx + php7.0-fpm +MySQL для Inst2
Добрый день! Данная записка более чем напоминание о том, что не забыть при установке и настройке VDS Nginx + php7.0-fpm +MySQL для Inst2.
Используя этот сайт, вы соглашаетесь с тем, что мы используем файлы cookie.