__call или вызов рутинных методов в движке

Комментарии ()

В каждом объекте, который работает с БД, плодятся методы, которые я называю рутинными. Примеров тьма: getLoginById, getIdByLogin, getAliasByName. getNameById и так далее. Поскольку практически суть везде одна и таже (выполнить select с некой таблицы БД по некому признаку и вернуть value) я утвердил в своем движке стандарт вызова метода __call

Для начала договоримся, что в каждом классе, который унаследован от Core, должно присутствовать свойство $call, которое содержит ассоциативный масив следующего виду

  • table - название таблицы по умолчанию, с которой брать данные. Значение задается в конструкторе класса.
  • fields_private - масив с перечнем названия полей, доступ к которым через метод __call нужно закрыть

public function __call($methodName, $args)

$methodName - название несуществующего метода, которого мы вызываем

$args - массив параметров:

первый параметр - значение поля, по которому ищем запись в БД

второй параметр - название таблицы, если нету - используется $call['table']

Пример

В классе User вызываем не существующий метод getEnableById - в даном случаи мне нужно получить значени поля enable из таблицы users по значению поля id. В классе задано свойсто   protected $call = array('table' => 'users', 'fields_private' => array()); 

На самом деле я создал метод   getEnableById только ради автодополнения в IDE. Также методы следует задавать явно, если необходимо выполнить дополнительные действия. В этом примере выполняется проверка на существование  $id (если отсутствует, тогда присвоить  $_SESSION['user']['id'])

 

 public function getEnableById($id = '')
    {
        if ($id == '')
        {
            $id = $_SESSION['user']['id'];
        }
        return parent::__call(__METHOD__, $id);
    }

 


Читать далее

Форма

Комментарии ()

Form - один из самих больших моих класов. В чем собственно суть? Посколья я далеко не дизайнер, Bootstrap стал для меня как манна небесная в плане веб-строительства. Уже вышла третья версия, но я пока по прежнему на второй, так как треться еще сырая, да и вторая меня вполне устраивает.


Читать далее

Пагинация

Комментарии ()

Пагинация, это такая штука, которая позволяет разбить некие данные, которые выводяться на страничке, на несколько страниц

Пример использования пагинации

$pagination = new Pagination();
$pagination->setPage(@$_GET['page']); // передаем номер выбраной страницы
$pagination->setRowsCount(200); // передаем количество елементов
$pages = $pagination->getHtml();
$tpl->setVariable('pages', $pages);

Также, можно задать дополнительные параметры

$pagination->setPageRowsCount(10); // задаем количество елементов на одной странице
$pagination->setWidth(3); // количество страниц по  левую и 
правую сторону относительно активной страницы в панели выбора страниц

Все параметры заданы по умолчанию, единственный важный параметр, который нужно задать, это количество елементов, которые нужно разбить на страницы

$pagination->setRowsCount( { тут количество елементов } ) 

Пример взаимодействия объекта Sql с пагинатором

$pagination = new Pagination();
$pagination->setPage(@$_GET['page']);

$query = "SELECT * FROM articles WHERE `visible`=1";
$res = $sql->select(array('sql' => $query, 'pagination' => &$pagination));

$pages = $pagination->getHtml();
$tpl->setVariable('pages', $pages);

В даном примере объекту Sql передается по ссылке объект пагинатора, который получает общее количество найденых записей и формирует LIMIT для sql-запроса. В даном случае sql-запрос выполняется два раза. Первый раз с целью получения общего количества записей, второй раз с LIMIT'ом


Читать далее

Мультиязычность

Комментарии ()

Инструменты для работа с мультиязычностю собраны в классе Lang. Понятие мультиязычности рассматривается в двух плоскостях:  текстовые елементы шаблона  и контекст веб-сайта.

Текстовые елементы шаблона 

Таблица dictionary является своего рода словарем, где некоторому оригинальному alias'у соотвествуют слова на разных языках word_* (* - алиас языка, например en,ru,ua и т.д.). Тоесть, для английского, руского и украинского, таблица будет иметь три поля: word_en,word_ru,word_ua.

Все страницы сайта формируются шаблонизатором, который парсит шаблоны. В шаблонах, мультиязычные елементы заканчиваються нижнем подчеркиванием. Например, если в шаблоне присутствует {name_},и активным языком является украинский, то необходиом подставить значение word_ua, значение алиаса которогого является "name".

Само значение читается не с базы данных, а с мультиязычных файлов, которые формируються, в процессе редактирования словаря через админку, тем самым уменьшаем количество запросов к БД во время работы с веб-сайтом.

Контекст веб-сайта

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

caption_en
caption_ru
...
text_en
text_ru
...
preview_en
preview_ru

Таблица multilang содержит название таблиц, которые имеют мультиязычне поля, а таблица multilang_fields содержит название полей (соответственно без алиаса языка, например:caption, text, preview) этих таблиц. Таким образом, при управлении языками (добавление, изминение, удаление) все поля в таблицах будут изменены/добавлены/удалены (хотя удаление отключено, дабы в случаи возврата того же языка, сохранить ранее введенные даные)

Сессии мультиязычности

$_SESSION['lang']['alias'] - алиас активного языка
 


Читать далее

Логер

Комментарии ()

Механизм логирования событий характерезируется:

  • датой создания (date_create)
  • уровнем (level:[debug,info,warn,error,fatal])
  • идентификатором пользователя, который создал запись (create_by)
  • идентификатором пользователя, к которому имеет отношение лог-запись(user_id)
  • идентификатором типа лог-записи (type_id: под типом подразумевает объект логирования. Например: пользователь, денежные средства, записи и так далее. 
    Правила именования алиаса: _LOG_TYPE_{тип лога}
  • идентификатором типа операции лог-записи (operation_id, зависит от type_id)
    Правила именования алиаса: _LOG_OPERATION_{тип операции}
  • идентификатором кода выполнения (code_id: зависит от type_id. Для каждого типа лог-записи, свой код. Например для типа user(пользователь) могут быть коды: ошибка авторизации, успешная авторизация, пользователь забанен и так далее...
    Правила именования алиаса: _LOG_CODE_{тип операции}
    Коды с 1 до 10 зарезервированы, и являются общедоступными
     
    Код Алиас Значение
    1 LOG_CODE_OK Успешное выполнение
    2 LOG_CODE_ERROR Ошибка выполнения
    3   Зарезервировано
    4   Зарезервировано
    5   Зарезервировано
    6   Зарезервировано
    7   Зарезервировано
    8   Зарезервировано
    9   Зарезервировано
    10   Зарезервировано
  • самим сообщением(text)
  • идентификатором записи (data_id) таблицы (log_type.table), которая связана с типом лог-записи. Связаная таблица может быть как дополнительная лог-таблица, так и рабочая таблица. Например: для типа auth существует лог-таблица log_auth, в которую вноситься дата, логин и ip-адрес всех попыток авторизации; для типа money существует таблица money (которая кстати не является лог-таблицой) в которую заносятся все финансовые движения (зачисление, списание денежных средств и так далее)
  • асоциативным масивом дополнительных данных (data),  структура которого зависит от типа лог-записи, значения которого будут добавлены в связную таблицу типа, id записи будет присвоен автоматически параметру data_id. Параметр data_id имеет преимущество перед data (если заданы два параметра одновременно, используется data_id

Логер существует в виде отдельного класса, документация тут

Документация по теме тут,тут

Создание лог-записи

Пример

$log = new Log();

$log_array_data=array('user_id'=>$user->getIdByLogin(),'ip'=>'192.168.0.10');

$log_array=array('text'=>'Успешная авторизация',
                                 'user_id'=>$user->getIdByLogin(),
                                 'create_by'=>-2,
                                 'level'=>'info',
                                 'type_id'=>_LOG_USER,
                                 'operation_id'=>_LOG_AUTH,
                                 'cody_id=>_LOG_OK',
                                 'data'=>$log_array_data);

$log->log($log_array);

В даном примере создается лог-запись (типа пользователь), для операции авторизации с успешным кодом выполнения(_LOG_OK). В параметр data передается массив дополнительной информации , в даном случае   ip-адресс и идентификатор пользователя. 

Дополнительная информация

Если в метод log передан параметр data (при этом параметр data_id отсутствует), то необходимо сохранить дополнительную информацию. Если присутствует метод сохранения дополнительно информации по типу лога и типу операции лога setLog{type}{operation} (в нашем примере setLogUserAuth), то передаем туда масив с данными. Если метода по типу нету, используется метод сохранения дополнительной информации по умолчанию setLog. Алгоритм его работы прост - сохранить переданый масив в связную таблицу (log_type.table) , и вернуть id-записи. Если связной таблицы нет, тогда на этом все.

Получение лог-записей

 


Читать далее

Form - автодополнение

Комментарии ()

Автодополнение очень полезная и удобная фича. Дабы не плодить каждый раз рутинны по роботе с ней, в модуль Form добавлен функционал, поддерживающий ajax autocomplete на базе jQuery.

Каждое автодополнение характеризируется именем, и заранее описывается в form_get_autocomplete_ajax_post.php. Cам елемент ввода должен принадледать к классу autocomplete и иметь data-атрибут autocomplete-name который содержит имя автодополнения..

html

<input type="text" name="login" id="login" value=""   width="" style="" class="autocomplete" placeholder="введите Логин" data-autocomplete-name="users_login">

Требования к елементу ввода:

  • елемент ввода должен принадлежать к классу autocomplete ( class="... autocomplete ...")
  • Наличие атрибута  data-autocomplete-name c именем автодополнения

Пример использования

#elementInputText
$element = array(
    'attr' => array(
        'name' => null,
        'type' => 'text',
        'alias' => null,
        'value' => false,
        'disabled' => false,
        'placeholder' => null,
        'value' => null,
        'class' => 'autocomplete',
        'data' => array('autocomplete-name'=>'users_login')
    ),
    'group' => array(
        'help' => null,
        'help_type' => 'block',
        'label' => null
    )
);
$tpl->setVariable('elementName', $form->getElement($element));

Алгоритм работы

  • При вводе текста в елементе выполняется функция $(".autocomplete").autocomplete(файл system.js), которая выполняент ajax-запрос form_get_autocomplete_ajax.  Если ajax-запрос прошел успешно - мы видим варианты автодополнения. Передаються на сервер в запросе также все data атрибуты, в которых можно передать дополнительные параметры и использовать их
  • form_get_autocomplete_post.php - в целях безопасности, для каждого autocomplete описывается алгоритм выборки данных.

Читать далее

Form - сортировка

Комментарии ()

 

При выводе информации, кроме постраничной навигации и фильтрации информации, есть необходимость в сортировке данных, для удобного поиска записей. 

Как и фильтр, сортировка  характеризуется названием формы (для каждой формы своя сортировка $_SESSION['form_sort']['{name}']). Данные сортировки хранятся в сессии ($_SESSION['form_sort']['{name}']=array(key=>value), где key - название поля в таблице БД по которому необходимо сортировать,  value - принимает значение up или down, тем самым указывая порядок сортировки.), что дает возможность сохранять работоспособность сортировки, даже при перезагрузке страницы. 


Читать далее

Form - фильтр

Комментарии ()

Як показала практика, скрипт-модуля повинен сам строїти потрібний sql-запрос, на основі отриманих даних від фільтра. Оскільки варіант із like'ами не підходить

При выводе информации, кроме постраничной навигации очень часто возникает необходимость отфильтровать даные по определенным признакам.

Фильтр характеризуется названием формы (для каждой формы свой фильтр $_SESSION['form_filter'][$name]). Заданые критерии хранятся в сессии ($_SESSION['form_filter'][$name]=array(key=>value), где key - название поля в таблице БД, а value соотвественно его значение.), что дает возможность сохранять работоспособность фильтра, даже при перезагрузке страницы. Елементы ввода фильтра работают в режима автодополнения.


Читать далее

Coding CMS Dvizhok

Комментарии ()

Необходимый базовый функционал

Базовые модули

  • Записи
  • Категории
  • Пользователи

Читать далее

Шаблоны модулей

Комментарии ()

Основнымы движущими силами CMS "Движок" есть старые добрые модули, которые щас модно трансформировались в контроллеры и тому подобное. У нас же данный рычаг управления будет называться по старинке: модуль. И так, в процессе написания модулей я заметил, что основной склет функциональных файлов практически не изменяется. Возможно у вас вопрос, зачем плодить файлы которые практически идентичны? На мой взгляд намного это припятствует возникновению проблем, когда нужно заточить тот или иной модуль под свои специфичные нужды, при этом сосед по парте не потсрадает.


Читать далее

Webit.in.ua 2013