Покупка: sales@goorucms.ru

Поддержка: support@goorucms.ru

8 (499) 394 72 90

    Общие сведения и начало работы

    Параметры подключения к БД

    Файл open:/conf_db.php

    Константы и настройки PHP

    Файл open:/conf.php

    Подключение возможностей

    В своём файле первой строкой подключите файл /prepend.php :

    
    

    Этот файл подключается ко всем встроенным php-файлам Gooru.cms и не меняется при апдейте. Можно дописывать туда свой код.

    Директории /gooru и /custom

    Ядро и встроенные модули находятся в папке /gooru. При обновлении все содержимое директории /gooru будет перезаписано.
    Крайне не рекомендуется вносить туда какие-либо изменения — они будут потеряны.

    Для корректного внесения любых изменений в работу Gooru.cms существует директория /custom . Путь к ней и её поддиректориям Gooru.cms помещает в самое начало include_path.

    Файлы, имена которых начинаются с подчеркивания из /custom удалять нельзя.

    Свои классы

    Заменить любой встроенный класс на свой исключительно просто и быстро!

    Для этого существует всего один файл open:/custom/_binds.php, где замена выполняется в одну простую строку:

    
    

    Всё! Никаких "хуков", "событий", "регистраций обработчиков". Создайте свой класс, наследуйте встроенный, и переопределяйте, что требуется, расширяйте. Gooru.cms всегда будет обращаться только к нему, его методам и свойствам, и на сайте, и в админ-панели.

    Теперь создаём само тело класса /custom/CustomUser.php, и переопределяем любые встроенные методы и свойства, или создаём свои:

    
    

    Теперь изменим товар

    
    

    Массив всех привязок классов к интерфейсам находится в open:/gooru/general/base_binds.php
    Список всех интерфейсов находится в open:/gooru/general/base_interfaces.php

    В системе не используются private, final и self. Gooru.cms использует protected и static. Интерфейсы не содержат прототипов методов - только полиморфизм и встраивание. Свобода изменений.

    Наследуйте и переопределяйте абсолютно всё! Вклинивайтесь в любую логику, в любой метод, любой файл.

    Чтобы полностью переписать встроенный класс, просто скопируйте его из /gooru в /custom или её поддиректории. Gooru.cms больше не притронется к своему.

    Своя логика и index.php

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

    Скопируйте нужный файл из /gooru в /custom . Всё.
    При этом не нужно создавать внутри /custom тот же путь, что имел файл внутри /gooru.

    Подключить родной файл из /custom можно просто по абсолютному пути.

    Например, клиент попросил в правой части сайта на главной странице написать и подключить мини-калькулятор на десктопной версии.
    Создаём /custom/index_desktop_right.php вместо родного open:/gooru/general/index_desktop_right.php и пишем:

    
    

    Основной файл декстопной версии: open:/gooru/general/index_desktop.php

    Основной файл мобильной версии: open:/gooru/general/index_mobile.php

    На практике при всей стройности шаблонов, MVC и проч, ничего не требуется так часто, как просто "влезсть" в index.php. Именно поэтому, файлы "точек входа" вынесены из шаблонов в PHP и разделены на секции верхняя полоска, шапка, левая, правая, центральная часть, подвал и др. Вы всегда можете заменить как, например, /gooru/general/index_desktop.php, так и его части без написания сложных контроллеров.

    Работа с CSS

    В Gooru.cms работа со стилями является исключительно простой: их не требуется объявлять в HEAD, Gooru.cms делает это сама.

    Встроенные стили

    Все стили Gooru.cms расположены в /gooru/css . Также подключаются стили некоторых внешних jquery-библиотек из /lib .

    Свои стили для проекта

    Все свои стили должны располагаться в /custom/css . Их количество не ограничено.

    Для того, чтобы стиль автоматически подключался в HEAD, имя файла должно начинаться с:

    1. "styles_desktop" для десктопной версии
    2. "styles_mobile" для мобильной.
    3. "styles_all" для обеих версий. Подключаются перед desktop и mobile

    Например, styles_desktop_my.css, styles_desktop_columns.css, styles_mobile.css, styles_mobile_footer.css, styles_all_layout.css.

    Свои стили подключаются после встроенных стилей. Также они собираются в кэш-файл (см. ниже). Однако, стили, названия которых начинаются со "styles_fonts" подлючаются перед встроенными, их количество не ограничено. В /custom/css уже создан один пустой файл styles_fonts.css .

    Можно создавать директории внутри /custom/css и помещать туда css-файлы, например, если их слишком много, и есть потребность разбить их логически.

    По содержимому файлов, названия которых содержат "_theme", проходит парсер, и выводит замененное содержимое в тэгах <style> после всех тэгов <link/>, когда кэширование отключено. В случае включенного кэширования заменное содержимое просто добавляется в конец кэш-файла. Такие файлы используются для небольших стилевых правил, содержащих настройки из админ-панели: цвета, фона, размеры.

    Стили, имена которых не удовлетворяют указанные выше условиям, проигнорируются. Их можно будет добавить в HEAD лишь вручную (см. нише).

    Стили модулей

    Если в директории модуля существует поддиректория "css", то её стили также обрабатываются по тому же принципу что и выше, и подключаются перед стилями /custom/css .

    В директориях встроенных модулей папок css нет (для простоты). Как уже говорилось выше, все они вынесены в одну директорию /gooru/css .

    Но если Вы работаете не под конкретный проект, а пишете переносной модуль, то удобно будет его стили хранить именно в /custom/YourModuleName/css

    Подробнее о стилях модулей см. раздел {link:CSS модулей}

    Замена встроенных стилей

    Для того, чтобы заменить любой встроенный стиль своим, достаточно создать в /custom/css (или её поддиректориях) файл с тем же именем. Например, для отключения встроенного файла /gooru/css/fonts.css создайте файл /custom/css/fonts.css . Будет использоваться именно он.

    Однако, на практике чаще требуется лишь переопределять некоторые встроенные css-правила, а не отказываться от них полностью.

    Кэширование стилей

    Когда {link_cf:cache_config кэширование css} отключено, каждый стиль выводится через <link/>:

    ...
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/fonts.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/custom/css/styles_fonts.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/lib/jquery.qtip/jquery.qtip.min.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/styles_core.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/styles_core_editor.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/styles_layout.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/jquery.ui/ui+lightness/jquery.ui.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/fancybox/jquery.fancybox.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/fancybox/jquery.fancybox-buttons.css" />
    <link rel="stylesheet" type="text/css" media="all" href="/gooru/css/fancybox/jquery.fancybox-thumbs.css" />
    ...
    

    Когда кэширование включено — выводится один аггрегаторный стиль.

    Для десктопной версии:

    <link rel="stylesheet" type="text/css" media="all" href="/css/styles_desktop.cache.v1457621451.css" />

    Для мобильной версии:

    <link rel="stylesheet" type="text/css" media="all" href="/css/styles_mobile.cache.v1457621451.css" />

    При обновлении кэша в URL изменяется цифровая часть, а сами файлы обновляются. Физическое расположение кэш-файлов: /cache/styles_desktop.css и /cache/styles_mobile.css.

    При разработке кэширование должно быть выключено. Страницы будут выдаваться немного дольше.

    В продакшн кэширование CSS следует обязательно включить!

    Объявление стилей вручную в HEAD

    Для того, чтобы объявить вручную внешний стиль (например, из cdn), в goorucms существует {link_cf:head_config специальный раздел}, где можно подключить внешние стили как перед основными, так и после них. Содержимое этих полей помещается в HEAD "как оно есть". Соответственно, и тэги <link/> и <style> должны там присутствовать.

    Эти стили никак не обрабатываются, и тем более не собираются в кэш-файл. Как правило, это либо стили внешних URL, либо стили для особых "media".

    Для того, чтобы подключить стили локальных библиотек, расположенных вне /custom/css в этом разделе существует поле "Локальные стили". Эти стили подключаются в кэш-файле, и находятся перед стилями из /custom/css. Таким образом, Вы можете в /custom/css переопределять стили своих библиотек, зная, что библитечные стили находятся перед Вашими. И всё это при включенном кэшировании соберется в один файл.

    Динамическое добавление стилей в PHP-коде

    Так как Gooru.cms использует задержку и парсинг буффера, стили можно объявлять в любом месте Вашего PHP-кода, в том числе после HEAD. Используйте синглтон интерфейса iCSS:

    
    

    Эти стили в HEAD выводятся самыми последними, никак не обрабатываются, а существование файлов не проверяется.

    Специальные файлы

    Если существует файл /custom/css/styles_tablet.css, он подключается только для планшетов автоматически после остальных файлов.

    Если существует файл /custom/css/styles_android.css, он подключается для встроенного браузера OS Android после остальных файлов.

    Если существует файл /custom/css/styles_en.css, он подключается только в английской языковой версии после остальных файлов. То же справедливо для других языковых версий.

    Стили тем

    См. раздел Работа с темами

    Работа с Javascript

    В Gooru.cms работа с javascript является исключительно простой: их не требуется объявлять в HEAD, Gooru.cms делает это сама.

    Встроенные скрипты

    Основные скрипты Gooru.cms расположены в /gooru/js, а также в директориях встроенных модулей /gooru/modules .
    Также подключаются скрипты некоторых внешних jquery-библиотек (включая саму jquery) из /lib.

    Важно! Файл /gooru/js/global.js подключается в админ-панели тоже.

    Свои скрипты для проекта

    Все свои скрипты должны располагаться в /custom/js . Их количество не ограничено.

    Для того, чтобы скрипт автоматически подключался в HEAD, имя файла должно начинаться с:

    1. "scripts_desktop" для десктопной версии
    2. "scripts_mobile" для мобильной.
    3. "scripts_all" для обеих версий. Подключаются перед desktop и mobile

    Например, scripts_desktop_my.js, scripts_mobile.js, scripts_mobile_footer.js, scripts_all_preload.js .

    Свои скрипты подключаются после встроенных скриптов. Также они собираются в кэш-файл (см. ниже).

    Можно создавать директории внутри /custom/js и помещать туда javascript-файлы, например, если их слишком много, и есть потребность разбить их логически.

    Скрипты, имена которых не удовлетворяют указанные выше условиям, проигнорируются. Их можно будет добавить в HEAD лишь вручную (см. нише).

    Скрипты модулей

    Если в директории модуля существует поддиректория "js", то её скрипты также обрабатываются по тому же принципу что и выше, и подключаются после скриптов /custom/js .

    В директориях встроенных модулей папок js нет (для простоты). Все скрипты вынесены в директорию самого модуля.

    Но если Вы работаете не под конкретный проект, а пишете переносной модуль, то удобно будет его javascript хранить именно в /custom/YourModuleName/js.

    Замена встроенных скриптов

    Для того, чтобы заменить встроенный скрипт своим, достаточно создать в /custom/js (или её поддиректориях) файл с тем же именем.
    Например, для отключения встроенного файла /gooru/modules/Catalog/Catalog.js создайте файл /custom/js/Catalog.js . Будет использоваться именно он.

    Однако, на практике чаще требуется лишь переопределять/дополнять/отключать некоторые встроенные js, а не отказываться от них полностью.
    Подавляющее большинство привязок в Gooru.cms содержат ключ после точки в первом параметре метода "on" бибиотеки jquery

    Например, отключить следующий код из файла /gooru/js/common.js

    ...
    $('a[class*=toggle], :input[class*=toggle]', context).on('click.toggler', function(){
    	//...
    });
    ...

    можно с помощью следующего кода:

    ...
    $('a[class*=toggle], :input[class*=toggle]', context).off('click.toggler');
    ...

    Кэширование javascript

    Когда {link_cf:cache_config кэширование javascript} отключено, каждый скрипт выводится через <script src="...">:

    ...
    <script src="/lib/jquery.qtip/jquery.qtip.min.js"></script>
    <script src="/lib/jquery.doubleScroll/jquery.doubleScroll.js"></script>
    <script src="/lib/social-likes/social-likes.min.js"></script>
    <script src="/lib/video-js/video.js"></script>
    <script src="/gooru/js/global.js"></script>
    <script src="/gooru/js/common.js"></script>
    <script src="/gooru/modules/Catalog/Catalog.js"></script>
    <script src="/gooru/modules/Web20/Web20.js"></script>
    ...
    

    Когда кэширование включено — выводится один аггрегаторный скрипт.

    Для десктопной версии:

    <script src="/scripts_desktop.cache.v1458052945.js"></script>

    Для мобильной версии:

    <script src="/scripts_mobile.cache.v1458052945.js"></script>

    При обновлении кэша в URL изменяется цифровая часть, а сами файлы обновляются. Физическое расположение кэш-файлов: /cache/scripts_desktop.js и /cache/scripts_mobile.js.

    При разработке кэширование должно быть выключено. Страницы будут выдаваться немного дольше.

    В продакшн кэширование JS следует обязательно включить!

    Объявление скриптов вручную в HEAD

    Для того, чтобы объявить вручную внешний скрипт (например, из cdn), в goorucms существует {link_cf:head_config специальный раздел}, где можно подключить внешние скрипты в поле "Внешние javascript". Содержимое этих полей помещается в HEAD "как оно есть". Соответственно, тэги <script> должны там присутствовать.

    Эти скрипты никак не обрабатываются, и тем более не собираются в кэш-файл. Как правило, это скрипты из внешних URL.

    Для того, чтобы подключить скрипты локальных библиотек в этом разделе существует поле "Локальные javascript". Эти скрипты подключаются перед скриптами из /custom/js и /gooru/js. Таким образом, Вы можете в /custom/js использовать возможности своих библиотек, зная, что библиотеки уже подключены. И всё это при включенном кэшировании соберется в один файл.

    Динамическое добавление скриптов в PHP-коде

    Так как Gooru.cms использует задержку и парсинг буффера, скрипты можно объявлять в любом месте Вашего PHP-кода, в том числе после HEAD. Используйте синглтон интерфейса iJS:

    
    

    Эти скрипты в HEAD выводятся самыми последними, никак не обрабатываются, а существование файлов не проверяется.

    Привязка событий к элементам в случае AJAX

    Часто элементы, к которым обращается Ваш javascript-код появляются на странице не при загрузке её HTML, а через AJAX.
    Возникает задача не заботиться об этом, и писать код только используя селектор своих элементов один раз.

    В Gooru.cms это делается следующим образом. Например, создаётся файл /custom/js/scripts_all_test.js со следующим содержанием:

    
    

    Этот код выполнится как при $(document).ready, так при при открытии фэнсибоксов и любого другого ajax-контента в Gooru.cms

    В случае AJAX код вызывается в контексте обрамляющего полученный контент контейнера. В случае $(document).ready переменная context будет пустой

    Вызов всех init-функций (в том числе встроенных в Gooru.cms) в своем коде для AJAX:

    
    
    

    Скрипты тем

    См. раздел Работа с темами

    Работа с шаблонами

    Встроенные шаблоны

    В Gooru все встроенные шаблоны расположены в /gooru/templates. Имя каждого шаблона уникально (и должно быть таким), и имеет вид ИмяШаблона.tpl.

    Gooru использует свой XML-подобный синтаксис в них. Представление о нем легко получить, открыв, например, шаблон CatalogTable, выводящий список товаров в "табличном виде": open:/gooru/templates/CatalogTable.tpl

    Свои шаблоны для проекта

    Чтобы переопределить встроенный шаблон, просто скопируйте его из /gooru/templates в /custom/templates.

    Там же в /custom/templates создаются свои шаблоны. Их имена должны быть уникальными по отношению к встроенным.

    Можно создавать директории внутри /custom/templates, и размещать шаблоны там. Но уникальность имен должна сохраняться.

    Обратиться к родному шаблону из /custom/templates можно с помощью конструкции <require>.

    Например, поместим содержимое карточки товара в свой обрамляющий контейнер. Копируем /gooru/templates/CatalogModel.tpl в /custom/templates/CatalogModel.tpl, стираем всё и пишем:

    
    

    Шаблонизатор

    Создание шаблона

    Шаблон - объект интерфейса iTemplate. По умолчанию это класс Template (расположен в /gooru/class/Template.php). example:templates1.php

    Если Вы желаете дополнить класс Template своими методами или переопределить существующие, просто расширьте Template своим классом

    Замена метки

    Замена конкретной метки выполняется методом replace() шаблона, куда передается имя метки и строка, на которую требуется заменить метку. Второй параметр всегда приводится к строке example:templates2.php

    Замена тэга

    Выполняется методом replace_tag() шаблона. Редко используется. example:templates3.php

    Замена массива

    Если в replace() передан только один параметр - массив, то замена происходит проходом по массиву, используя как его ключи, так и значения. Если значение элемента массива - строка, то происходит простая заметки метки, ключ - имя метки. example:templates4.php

    Парсинг объектом

    Чаще всего в Gooru.cms происходит замена объектов. Чтобы пропарсить шаблон объектом, его нужно просто передать в метод replace() шаблона. Если объект имеет метод facade(iTemplate $tpl), он вызывается с этим шаблоном, и возвращает массив замены (см. подразделы ниже). В основном объекте данных GooruCls уже определен метод facade, возвращающий основной массив замены. iTemplate $tpl в этот мотод передается для того, чтобы проанализировать, есть ли в нём нужные метки и тэги. Если метка и тэг отсутствуют, в массиве замены их быть не должно, иначе потеряется много ресурсов на пустую работу функций str_replace, preg_replace и т.д. Дочерние объекты часто содержат свой facade() расширяющий родительский. example:templates5.php

    Замена объекта только внутри тэга

    Наиболее просто заменить объект только внутри определенного тэга можно с помощью метода replace_into. Если объект - пустой (id не существует в БД), тэг просто вырежется. example:templates6.php

    Однако на практике, обычно, это делается в массиве замены с помощью мини-объекта TemplateCharged example:templates7.php

    В TemplateCharged можно передавать не только объект, но и переменные других типов. Прм этом если переменная приводится к false, тэг переданный вторым параметром просто вырежется.

    Метод facade()

    Как хорошо видно, в массиве все TemplateCharged должны стоять выше элементов со строковым значением, так как замены внутри конкретных тэгов должны производиться раньше. А в конце массива располагаются простые метки, которые заменяются после того, как все тэги уже обработаны. Соответственно при расширении метода facade() от GooruCls или от других родительских объектов следует поступать таким образом: example:templates8.php

    Замена списков

    Замена списка элементов производится с помощью метода replace_list() шаблона. Переданный параметр может быть как массивом, так и коллекцией. В начале рассмотрим пример замены массивом-списком: example:templates9.php

    Для того, чтобы указать какой из элементов массива является "текущим", можно передать его ключ вторым параметром. В этом случае, в тэге element можно использовать тэг is_selected, который заменится на своё содержимое у текущего элемента массива, и вырежется полностью у остальных. Если текущих элементов несколько (например, при выводе option мультиселектов, где несколько option имеют аттрибут selected), передайте вторым параметром список их ключей. example:templates10.php

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

    Замена коллекций

    Чтобы пропарсить коллекцией (объект интерфейса iCollection), нужно вызвать с коллекцией метод replace_list() шаблона. example:templates11.php

    Для того, чтобы указать текущий эламент коллекции, удобно это делать непосредствено в коллекции с помощью метода set_current() класса Collection: example:templates12.php

    Шаблоны тем

    См. раздел Работа с темами

    Работа с темами

    В Gooru.cms темы представляют собой директории внутри /custom/themes. Создайте в ней любую поддиректорию, и она будет {link_cf:site_config:tab5 доступна для выбора} в поле "Тема".

    Внутри Вашей директории можно создавать директории css, js, templates. Они обрабатываются так же, как описано выше для /custom/css, /custom/js, /custom/templates, но имеют более высокий приоритет. Например, если шаблон положить и в /custom/templates и в /custom/themes/my_theme/templates, Gooru.cms использует именно последний.

    Соответственно, для использования уже готовой темы, просто скопируйте её в /custom/themes и выберете в соответствующей настройке.

    Работа с таблицами в админке

    В Gooru.cms легко и удобно создавать свои таблицы для управления ими из админки.

    Два вида таблиц

    Есть два вида таблиц: обычные и настроечные.

    1. Обычные таблицы представляют собой таблицы из БД. Их URL имеет вид "/gooru/admin/?TABLE=имя_таблицы_в_БД". Например, таблица Страницы.

    2. Настроечные таблицы являются псевдотаблицами. Их данные хранятся в одной таблице config и разделены на секции. Их URL имеет вид "/gooru/admin/?TABLE=config&section=имя_таблицы". Например, {link_cf:catalog_config Настройки каталога}. Так как они конфигурируются так же, как и обычные таблицы, их удобно тоже называть таблицами.

    Конфиг-файлы таблиц

    У каждой таблицы, доступной для редактирования в админке, есть свой конфиг-файл. Все конфиг-файлы встроенных таблиц находятся в /gooru/tables и имеют вид имя_таблицы_в_БД.php.

    Например, конфиг таблицы pages есть open:/gooru/tables/pages.php . Он состоит из ассоциативного массива параметров $cfg и массива полей $fields.

    Поддерживаемые ключи массива $cfg:

    • type — указывается только для настроечных таблиц (!), и должен быть равен 'config'.
      Например, настроечная таблица {link_cf:catalog_config Настройки каталога}. Её конфиг-файл: open:/gooru/tables/catalog_config.php.

    • name — переопределяет название таблицы из меню на её странице вверху. По умолчанию не установлено.
      Например, настроечная таблица {link_cf:catalog_config Настройки} модуля "Каталог" имеет заголовок "Настройки каталога" на своей странице. Её конфиг-файл: open:/gooru/tables/catalog_config.php.

    • show — количество записей на одной странице (для обычных таблиц). По умолчанию не установлено, и используется настройка из таблицы {link_cf:system_cp_config Настройки панели управления}
    • sortfield — поле таблицы для сортировки записей по умолчанию. Если не указано, то ID.
    • sorttype — направление сортировки по умолчанию. Если не указано, то ASC.
    • interface — интерфейс, привязанный к "обычной" таблице. Его должен реализовывать подкласс класса {link:GooruCls}. Почти ко всем обычным таблицам в Gooru.cms привязаны интерфейсы.

    • cls — если привязанный к таблице класс не имеет интерфейса, но наследует класс {link:GooruCls} , его следует указать в этом параметре.

    • css — список css-файлов, которые следует подключить при просмотре таблицы. Либо массив путей, либо строка, в которой пути отделяются запятой. По умолчанию пустое.
    • js — список javascript-файлов, которые следует подключить при просмотре таблицы. Либо массив путей, либо строка, в которой пути отделяются запятой. По умолчанию пустое.
    • tabs — исли true, то при добавлении/редактировании записи поля будут делиться на вкладки. Например, здесь 3 вкладки: Основное, Публикация и SEO. По умолчанию false для обычных таблиц и true для настрочных таблиц.
    • no_tabs — используется, чтобы отменить деление на вкладки у настроечных таблиц, и заменить его делением на строчные подзаголовки. Для этого установите в true.
    • subheader_field — имя поля таблицы, по изменению значения которого записи объединяются в tbody одним цветом для удобства просмотра. Например, здесь $cfg['subheader_field'] = 'SessionID'; поэтому записи с одним SessionID имеют одинаковый цвет, который меняется при смене значения SessionID. По умолчанию не установлено.
    • show_page — используется для обычных таблиц, чтобы вывести у каждой записи слева иконку синего глобуса, при нажатии на который открывается "карточка" записи. Работает только для тех таблиц, для которых указан $cfg['interface'] или $cfg['сls'] (см. выше). URL ссылки возвращает метод get_href() привязанного класса. По умолчанию false. Пример, таблица Страницы
    • record_operations — сallable, возвращающий произвольный html-код, добавляемый справа от основных операций записи. По умолчанию не установлен. Например,
      $cfg['record_operations'] = function(iTB $tb, $i){ return 'smth'; }; //передаётся объект интерфейса iTB (таблица) и порядковый номер строки $i (начиная от нуля).
    • buttons — массив кнопок, которые будут добавляться справа от встроенных кнопок внизу на странице редактирования/добавления записи в обычных таблицах, и в настроечных таблицам там же. Ключи массива - "name" тэгов <button>, элементы массива - массивы с ключами 'value' - название кнопки, и 'handler' - callable, вызываемый при отправлении формы нажатием на кнопку перед выводом на страницу. Пример настроечной таблицы с buttons: open:/gooru/tables/cache_config.php

    • action_handlers — ассоциативный массив файловых путей. При POST-запросе страницы будет подключен (require) соответствующий ключу файл, если передана переменная $_POST['ключ'].
      Используется в тех случаях, когда отправка POST-запроса производится не через $cfg['buttons'].
      Например, open:/gooru/tables/catalog_cats.php - обработчик переноса товаров в другую категорию и проставление цен.

    • handler — callable, всегда вызываемый при POST-запросе страницы таблицы. Во встроенных модулях не используется.

    • cp_main_title — заголовок таблицы на главной странице админки, переписывает на ней обычный заголовок таблицы. На главной странице перед ним добавляется слово "последние". Например, заголовок таблицы "уведомить о наличии" на главной странице админки выглядит как "последние просьбы уведомить о наличии": open:/gooru/tables/shop_notifies.php

    • toptext — текст, выводимый вверху на светло-желтом фоне. Обычно, используется для предупреждающих сообщений.
      Например, настроечная таблица {link_cf:system_config Сессии и cookie}. Её конфиг-файл: open:/gooru/tables/system_config.php.

    • bottomtext — html, выводимый внизу на светло-сером фоне. Обычно, используется для пояснений к таблице.
      Например, настроечная таблица {link_cf:shop_import_config Интеграция с 1C}. Её конфиг-файл: open:/gooru/tables/shop_import_config.php.

    • top_table_info — html, выводимый справа от заголовка таблицы на её странице.

    • disable_multiple_add — boolean. Если true, не будет выводиться слева от кнопки добавления записи поле для одновременного добавления нескольких записей. По умолчанию false.

    • disable_multiple_delete — boolean. Если true, не будет вверху в блоке для работы с записями, отмеченными чекбоксами, выводиться кнопка удаления. По умолчанию false.

    • excel — boolean. Если true, вверху будут выведены кнопки для экспорта в/импорта из MS Excel. У многих встроенных таблиц экспорт включен. По умолчанию - false.
      Например, таблица Категории товаров. Её конфиг-файл: open:/gooru/tables/catalog_cats.php.

    • operations — html, выводимый справа от основных кнопок операций с несколькими записями вверху.
      Например, кнопка "Установить из файла" в таблице Модули. Её конфиг-файл: open:/gooru/tables/modules.php.

    • related_classes — строка элементов вида <класс>|поле через запятую. Определяет классы, относящиеся к привязанному классу таблицы, и поля, по которым происходит связь. Используется при операциях удаления и копирования записей (связанные с удалением операции, обычно указываются в методе delete() привязанного класса, но в случае копирования записей это не так). Например, open:/gooru/tables/catalog_models.php.

      Действует аналогично параметру related в $fields (см. ниже), но в отличие от него не выводится диалоговые окна и подтверждением удаления или копирования связанных объектов.

    • related_classes_copy — аналогично параметру выше, но действует только при операции копирования записей.

    • fixed — ID через запятую тех записей, которые нельзя удалить.
      Например, таблица {link_table:shop_orders_status Статусы заказов}. Её конфиг-файл: open:/gooru/tables/shop_orders_status.php.

    • name_field — имя поля в "обычной" таблице с "названием" записи. Если не установлено, то Name. Обычно, указывается в тех таблицах, где нет поля Name.
      Например, таблица Статичные тексты. Её конфиг-файл: open:/gooru/tables/static_texts.php.

    • update_css — boolean. Если true, при любом изменении/добавлении записей в таблице будет обновлен кэш CSS. По умолчанию - false.
      Например, таблица Статусы и кнопки в Каталоге. Её конфиг-файл: open:/gooru/tables/catalog_statuses.php.

    • a — {link:массив выборки} таблицы. По умолчанию не установлен. Удобно использовать в тех случаях, когда требуется показать в списке не все записи. Например, в таблице Продажи товаров показаны товары заказов, имеющих статус "завершен". См. конфиг таблицы open:/gooru/tables/shop_orders_models.php

    Поддерживаемые ключи элементов массива $fields в алфавитном порядке:

    • a — {link:массив выборки} записей. По умолчанию не указан. Аналогичен $cfg['a'] и собирается у всех полей по порядку их следования в таблице перед запросом.

    • add_to_href — только для поля FieldResource. Строка, которую следует добавить к URL ресурса. Распознается метка #ID# - ID ресурса. Например, таблица {link_table:comments Комментарии} (конфиг: open:/gooru/tables/comments.php). Поле "Страница". К всем URL добавлена строка #comment##ID#.

    • allow_text_param — только для поля FieldSelectText. Строка ключей значений через "|", при выборе которых в селекте появляется текстовое поле справа. По умолчанию не установлен, и в этом случае текстовое поле доступно у всех элементов селекта. Например, таблица {link_table:catalog_groups Группы товаров} (конфиг: open:/gooru/tables/catalog_groups.php). В поле "Тип" текстовый параметр появляется только у значений last-accepted и bestsellers.

    • cf_name — имя параметра настройки. Поле должно обязательно присутствовать у каждого поля в ЛЮБОЙ настроечной таблице, кроме первого, обознающего ID. По этому имени происходит чтение настройки. См. например, конфиг-файл таблицы {link_cf:pages_config Настройки страниц}: open:/gooru/tables/pages_config.php

    • choose — если true, то в режиме редактирования/добавления записи справа от поля выводится кнопка "выбрать", где можно выбрать URL страниц, загрузить сразу файл, и его URL вставится в поле. См. напрммер, редактирование страниц и поле "Код". Конфиг-файл таблицы: open:/gooru/tables/pages.php

    • class — css-класс, добавляемый к полю.

    • cls — соответствующий полю класс-сущность. Если указан, слева от таблицы будут выведены фильтры по полю (помимо автоматических, которые выводятся, если класс, привязанный к таблице является подклассом GooruCatItem). Например, таблица {link_table:catalog_models Товары}: поля "Бренд" и "Группа". Конфиг-файл: open:/gooru/tables/catalog_models.php. Слева есть фильтр по бренду, группе и статусу, помимо автоматического по категории.

    • custom — только для селекторных полей (FieldSelect и подтипы/подклассы). Если установлен, то справа от селекта будет выведено текстовое поле для указания "другого значения", не присутствующего в списке. Если строка, она будет плейсхолдером поля. Если true, в качестве placeholder будет слово "Другое". Например, таблица Способы доставки (конфиг: open:/gooru/tables/shop_deliveries.php).

    • default — значение поля по умолчанию при добавлении записи (и для текстовых полей, и для списков и др.). Например, таблица Статусы и кнопки. Её конфиг-файл: open:/gooru/tables/catalog_statuses.php. Поле "Действие кнопки".

    • default_field — только в совокупности с параметром 'table' (см. ниже). Поле в 'table', установленное значение которого определяет 'default' динамически. Например, таблица Страницы. Её конфиг-файл: open:/gooru/tables/pages.php. Поле "Меню". При добавлении уже отмечены те чекбоксы, где отмечено "По умолчанию" в таблице "меню".

    • dir — только для поля FieldSelectMultipleDirs: родительская директория. Если не указана, то используется корневая директория сайта.

    • disabled — только при добавлении записи. Если true, при добавлении поле будет неактивно (html-аттрибут disabled). Например, таблица Рекламные объекты. Её конфиг-файл: open:/gooru/tables/adv_objects.php. Поля "Показов" и "Кликов".

    • disabled_edit — аналогично 'disabled', но работает для режима редактирования записи. Например, таблица Языки. Её конфиг-файл: open:/gooru/tables/langs.php. Поле "Код".

    • display — если false, то поле не будет показываться в режиме редактирования и добавления записи. По умолчанию true. Для того, чтобы скрыть поле в режиме просмотра записей, см. параметр show ниже.

    • edit — только для полей textarea (FieldTextarea и FieldLangvaluearea). Если true - то поле уже со включенным ckeditor. Если 0 - есть кнопка для редактора, но сам он по умолчанию выключен. Если false - нет редактора и кнопки. По умолчанию - false. Например, таблица Список статей. Её конфиг-файл: open:/gooru/tables/news.php. Поле "Текст" с уже включенным редактором, так как параметр edit установлено для него в true.

    • empty_option — если установлено, то значение, которое выводится в поле при просмотре записей, когда оно не установлено. Оно же добавляется первым параметром в селекты с value="". Используется очень широко. Например, в поле "Max" в таблице {link_table:adv_groups Рекламные группы} (конфиг-файл: open:/gooru/tables/adv_groups.php) выводится слово "все", когда его значение не установлено, либо равно 0.

    • exclude — список значений через запятую для полей с параметром 'table' (см. ниже), которые следует исключить из селектов, радио-кнопок и др. по каким-либо причинам.

    • field — поле "название" для полей с параметром 'table' из таблицы 'table', которое выводится в селектах между <option></option>, при просмотре записей, по нему производится поиск, и т.п. По умолчанию Name.

    • filter — если true, то в режиме просмотра записей значение поля выводится ссылкой при нажатии на которую устанавливается фильтр по значению поля. По умолчанию false. Например, в поле "Группа" в таблице {link_table:adv_objects Рекламные объекты} (конфиг-файл: open:/gooru/tables/adv_objects.php) выводится ссылкой.

    • form_id — только для поля FieldFormFields, которое выводит список формы с указанным form_id.

    • form_type — только для поля FieldFormFields, которое выводит список формы с указанным типом. Например, таблица Способы оплаты. Её конфиг-файл: open:/gooru/tables/payment_systems.php - в двух полях выводятся поля формы заказа (form_type = order).

    • generate — если true, справа от поля появляется кнопка, генерирующая случайную строку. Например, таблица {link_cf:security_config Настройки безопасности}, её конфиг файл open:/gooru/tables/security_config.php

    • header — название блока полей записи.
      Если $cfg['tabs'] = true, то является названием вкладки, как, например, в таблице Список статей (конфиг-файл open:/gooru/tables/news.php)
      Если false, или $cfg['tabs'] не установлено, то выводится строка на черном фоне, как в таблице Вопрос-ответ. Для таблиц с небольшим количеством полей деление на вкладки не рекомендуется.

    • header-width — устанавливает ширину левого столбца в режиме редактирования/добавления записи. Такая необходимость возникает в случае очень широкого второго столбца. Например, поле "Комплекты" в таблице Товары (конфиг-файл open:/gooru/tables/catalog_models.php) имеет header-width = 10, чтобы вместить на экране большую таблицу комплектов справа, не занимая место левым столбцом с названием.

    • height — только для полей textarea (FieldTextarea и FieldLangvaluearea). Значение аттрибута rows.

    • id — поле "значение" для полей с параметром 'table' из таблицы 'table'. Значение выводится в селектах и подобных полях как аттрибут value. По умолчанию ID. Однако, иногда требуется вместо ID таблицы 'table' в значениях использовать другое поле. Например, см. таблицу Страницы, где в поле "Меню" в качестве value используется не ID, а поле Code из таблицы "меню". Конфиг-файл таблицы: open:/gooru/tables/pages.php

    • ignore_mask — только для поля FieldTemplate. Если указано, в селекте шаблонов не будут выводиться те из них, названия которых содержат указанную строку. Можно перечислять несколько масок через запятую. Работает только при установленном параметре mask (см. ниже) Например, см. таблицу Формы, 3 поля типа FieldTemplate. Конфиг-файл таблицы: open:/gooru/tables/forms.php

    • mask — только для поля FieldTemplate. Если указано, в селекте шаблонов будут выводиться только те из них, названия которых начинаются с указанной строки. Например, см. таблицу Формы, 3 поля типа FieldTemplate. Конфиг-файл таблицы: open:/gooru/tables/forms.php

    • names — только для поля FieldSimpleParams. Два названия для полей, разделенных символом "|". По умолчанию равно "name|content". См. таблицу {link_cf:shop_config:tab9 Настройки магазина}, конфиг файл open:/gooru/tables/shop_config.php. В поле "Начисление баллов" значение параметра равно "Процент|Максимальная сумма"

    • no_preview — только для поля FieldUpload. Если true, в поле будет скрыт блок с загрузкой превью. По умолчанию false. Например, таблица Рекламные объекты. Её конфиг-файл: open:/gooru/tables/adv_objects.php. Поле "Изображение".

    • no_xls — если true, поле не будет экспортироваться в Excel (xls, xlsx, csv). По умолчанию false. Например, таблица {link_table:shop_orders Заказы}, конфиг-файл open:/gooru/tables/shop_orders.php, поля "Изменен пользователем" и "Изменено" не экспортируются.

    • nowrap — если true, содержимое ячейки с полем будет обрамлено <div class="nowrap">. По умолчанию false, но в некоторых типах полей установлено в true в конструкторе.

    • only_interfaces — только для поля FieldPagebinder. Массив интерфейсов, по которому строятся мультиселекты. Если не указан, выведутся все зарегистрированные интерфейсы для поля. Например, таблица Группы товаров, поле "Место показа". Конфиг-файл: open:/gooru/tables/catalog_groups.php. Выводится только бренд и категория, так как значение параметра array('iCatalogCategory', 'iCatalogBrand').

    • only_positive — только для поля FieldPagebinder. Если true, не выводится переключатель "показывать на" и "на всех кроме". По умолчанию false. Например, таблица Список статей, поле "Место показа". Конфиг-файл: open:/gooru/tables/news.php.

    • options — массив или строка (через "|") названий значений для полей типа FieldSelect, FieldRadio, FieldCheckboxes и т.п. Выводится как содержимое тэгов option, как название radio-полей и т.п. Для того, чтобы задать аттрибут value у этих тэгов, используйте параметр 'values' (см. ниже). Например, таблица Группы товаров, поле "Сортировать товары по". Конфиг-файл: open:/gooru/tables/catalog_groups.php.

    • placeholder — только для полей типа FieldText, FieldTextarea и некоторых других, содержащих тэги input type="text" и textarea.

    • related — используется для тех типов полей, где указан 'table' (см. ниже). Если true, то при удалении и копировании записей, будут удаляться и копироваться записи привязанной таблицы 'table', при этом в диалоговом окне будет предложено не удалять записи с 'table' иди не копировать их. По умолчанию false. Например, таблица {link_table:news_cats Категории статей}, конфиг-файл open:/gooru/tables/news_cats.php. При удалении категории статей будут удалены и её статьи (если не снять галочку в диалоговом окне).

    • replace_st — если true, в режиме просмотра записей в ячейке поля будут заменены статичные тексты. Соответственно, используется в тех полях, где возможны значения со статичными текстами. По умолчанию false.

    • required — если true, поле обязательно для заполнения. См. таблицу {link_table:modules Модули}, конфиг-файл open:/gooru/tables/modules.php

    • resize_height — только для FieldUpload и FieldImages. Натуральное число - высота в пикселах. Если указана, то поле для ресайзинга высоты при загрузке уже будет заполнено этим значением. Обычно используется там, где не требуется хранить большие оригиналы изображений, и нужно при загрузке изображение уменьшить. Например, настроечная таблица {link_cf:site_config:tab0 Дизайн и контакты}, поле "Логотип в верхней полоске". Конфиг-файл open:/gooru/tables/site_config.php

    • resize_width — только для FieldUpload и FieldImages. Натуральное число - ширина в пикселах. Если указана, то поле для ресайзинга ширины при загрузке уже будет заполнено этим значением. Обычно используется там, где не требуется хранить большие оригиналы изображений, и нужно при загрузке изображение уменьшить. Например, настроечная таблица {link_cf:site_config:tab0 Дизайн и контакты}, поле "Логотип в подвале". Конфиг-файл open:/gooru/tables/site_config.php

    • resource — только для поля FieldSomeToCats и его дочерних классов. Интерфейс, по которому строится селект. Обязательный параметр для этих полей. Например, таблица {link_table:catalog_props_groups Группы свойств}, конфиг-файл open:/gooru/tables/catalog_props_groups.php, поле "Категории", где параметр равен iCatalogCategory

    • show — если false, то поле не будет показываться в режиме просмотра записей таблицы. По умолчанию true. Используется очень широко, так как по умолчанию показываются только самые важные поля таблицы. Для примера см. таблицу {link_table:catalog_cats Категории товаров}, конфиг-файл open:/gooru/tables/catalog_cats.php, где в режиме просмотра показываются всего 9 полей.

    • size — для однострочных текстовых полей (FieldText, его подклассы, и др). Значение аттрибута size для тэгов input. Используется очень широко. Напрммер, таблица Рекламные объекты, конфиг-файл open:/gooru/tables/adv_objects.php, поле "Ограничение на число показов".

    • sort — для полей, где указан параметр 'table' (см. ниже). Выражение ORDER BY для сортировки записей из 'table'. Используется очень часто. По умолчанию равно Name ASC для таблиц с полем Name, и ID ASC для всех остальных. См. например, таблицу Именные фильтры, конфиг-файл open:/gooru/tables/catalog_named_filters.php, поле "Категория"

    • sortindex — - параметр позволяет выводить поля в админке в произвольном порядке, а не том, в котором они объявлены в конфиг-файле в соответствии со структурой таблицы в БД. Для примера см. таблицу {link_table:catalog_cats Категории товаров}, конфиг-файл open:/gooru/tables/catalog_cats.php, где поля выводятся немного в другом порядке, отличном от таблицы catalog_cats БД.

    • sub — пояснение для поля. Выводится под его названием в левом столбце при редактировании/добавлении записи, а также при наведении на иконку с вопросиком справа от названия поля при режиме просмотра записей. У многих полей 'sub' объявлен в конструкторе. Например, таблица Категории товаров, конфиг-файл open:/gooru/tables/catalog_cats.php

    • sub2 — аналогично 'sub', но выводится непосредственно под самим полем при редактировании/добавлении записей в правом столбце. Например, таблица Категории товаров, конфиг-файл open:/gooru/tables/catalog_cats.php, поле "Тип описания предложений"

    • subheader — аналогично 'header' (выше), но используется, когда требуется разделить поля и по вкладкам, и внутри вкладок черными подзаголовками. Например, настроечная таблица {link_cf:shop_config:tab7 Настройки магазина}, конфиг-файл open:/gooru/tables/shop_config.php

    • table — используется в тех полях, где есть работа с другой таблицей, "привязанной". Например, в поле FieldSelectTable, FieldCount и др. Имя привязанной таблицы в БД. Параметр обязателен для таких полей. Например, таблица Список статей, конфиг-файл open:/gooru/tables/news.php, поле "Категория" (FieldCheckboxesTable) c уканным table = news_cats. Значения берутся из таблицы news_cats

    • title — название поля, указывается почти всегда. Для некоторых типов полей установлен в конструкторе, но может быть переопределен. Если для поля он не указан, и не установлен в конструкторе, то в качестве 'title' будет использовано имя поля в БД. Для примера см. таблицу {link_table:catalog_cats Категории товаров}, конфиг-файл open:/gooru/tables/catalog_cats.php.

    • trim — натуральное число. Позволяет переопределить количество оставляемых после обрезания символов в поле в режиме просмотра. По умолчанию оно задано в Настройках панели управления сайтом. Например, см. таблицу {link_table:faq Вопрос-ответ}, конфиг-файл open:/gooru/tables/faq.php, поле "Вопрос".

    • type — тип поля. Самый важный важный параметр из всех! В нём указывается php-класс поля, но без слова Field в начале, причем допускается первая буква как строчная. Например, для для того, чтобы указать класс FieldTextarea, следует установить параметр как "Textarea" или "textarea". Если type не указан, будет использован FieldText (однострочный input type=text). Для примера см. таблицу {link_table:catalog_cats Категории товаров}, конфиг-файл open:/gooru/tables/catalog_cats.php.

    • values — массив или строка (через "|") значений для полей типа FieldSelect, FieldRadio, FieldCheckboxes и т.п. Выводится как значение аттрибута value у тэгов option, radio, checkbox и т.п. Если является массивом, то его ключи будут значениями, а элементы - названиями тэгов. Если строка, то параметр должен использоваться совместно с 'options' (см. выше). Например, таблица Группы товаров, поле "Сортировать товары по". Конфиг-файл: open:/gooru/tables/catalog_groups.php.

    • xls — если true, в форме экспорта в EXCEL по этому полю возможен фильтр (чтобы не все записи таблицы экспортировались). Например, таблица {link_table:shop_orders Заказы}, конфиг-файл open:/gooru/tables/shop_orders.php, поле "Дата".

    • yml_type — только для поля FieldYml. Подкласс класса YML, выдающий URL экспорта в YML, и пусть к файлу. См. настроечную таблицу {link_cf:shop_yml_config:tab4 Яндекс-Маркет}, конфиг-файл open:/gooru/tables/shop_yml_config.php

    Изменение конфига встроенных таблиц

    Чтобы изменить конфиг встроенной таблицы, просто скопируйте её конфиг-файл в /custom/tables. Как правило, не требуется менять его полностью, а лишь изменить значения некоторых параметров.

    Например, Вы хотите изменить сортировку по умолчанию таблицы Товары. Копируем /gooru/tables/catalog_models.php в /custom/tables/catalog_models.php, стираем и пишем:

    
    
    

    Свои таблицы

    Для администрирования своей таблицы my_table просто создайте конфиг-файл /custom/tables/my_table.php. Если конфиг-файла не будет, таблицу всё равно можно будет администрировать. В этом случае в качестве названий полей таблицы будут использованы названия полей из БД, а в качестве полей формы будут использованы <input type="text"/>.

    Любая таблица в Gooru.cms должна удовлетворять двум условиям:

    1. Первое поле должно называться ID и быть автоинкрементом
    2. Если таблица многоуровневая, второе поле должно обязательно называться Parent и желательно того же типа, что и ID.

    Классы и объекты. Интерфейсы.

    Интерфейсы

    В Gooru.cms интерфейсы не имеют объявлений методов, а служат для быстрой замены одного класса на другой. Они же используются для хранения в БД (см. например, таблицу catalog_prices), для указания типа аргументов методов, для операций instanceOf и пр.

    Все имена интерфейсов начинаются со строчной буквы "i". Например, iCatalogCategory, iNewsCategory.

    Все встроенные интерфейсы объявлены в файле open:/gooru/general/base_interfaces.php.

    Все встроенные привязки классов к интерфейсам по умолчанию open:/gooru/general/base_binds.php.

    Файлы классов

    Файл класса подключается автоматически через autoload, если объявлен в файле ИмяКласса.php в директории /custom или её поддиректориях.

    В Gooru.cms используются заглавные буквы в словах имени класса. Примеры: CatalogCategory, CatalogGroup, Model, User.

    Синглтоны

    В Gooru.cms есть 4 типа синглтонов.

    1. Классические синглтоны действительно создаются в одном экземпляре. Все они наследуют класс open:/gooru/class/Singleton.php
    Примерами синглтонов являются классы Seo, Request, Http, Cache, Session и пр.

    2. Неклассические ID-синглтоны создаются в одном экземпляре для определенного ID. Это объекты классов, привязанных к определенной таблице в БД. Все они наследуют класс open:/gooru/class/GooruCls.php, который уже содержит в себе набор типовых методов для работы с таблицей и её записями, выводом на сайте, манипуляциями с данными.
    Таким образом для каждой конкретной записи в таблице объект её класса будет создан только один раз. Например, класс open:/gooru/modules/Catalog/CatalogModParam.php, отвечающий за работу с параметрами модификаций (таблица catalog_mods_params), является примером неклассического ID-синглтона. В нем лишь расширены некоторые методы GooruCls, и добавлено несколько своих.

    3. Неклассические строковые синглтоны аналогичны ID-синглтонам, но не относятся к таблице в БД. Они создаются один раз для уникальной строки. Эти классы наследуют класс open:/gooru/class/SingletonsRaw.php, обеспечивающий одноразовое создание по строке.
    Примером такого класса является класс для хлебных крошек Route. Его объект для хлебных крошек страницы получается с ключом-строкой main. Но не выведен в отдельный классический синглтон потому, что на странице результатов поиска может быть несколько уникальных Route, относящихся уже к каждому результату поиска. См. примеры ниже.

    4. Полуклассические ID-синглтоны могут быть как с ID, так и без. Во втором случае они возвращают "текущий объект" (возвращается статическим методом get_null_instance). Примерами такого рода являются классы Page, Lang и User. Без передачи ID они вычисляют "текущие" страницу, язык и пользователя. С передачей ID можно получить конкретного пользователя, страницу или язык. См. примеры ниже.

    Locator. Обращение по интерфейсу

    В Gooru.cms обращение к классам напрямую по их имени происходит лишь в немногих случаях.

    В основном же используется статический класс Locator:

    
    

    Благодаря этой архитектуре достаточно привязать к интерфейсу в open:/custom/_binds.php свой класс. И система будет использовать только его в том числе и в статических методах.

    Выборка объектов

    В Gooru.cms записи из БД выбираются крайне редко. В основном вся работа происходит с их объектами (подклассами базового класса GooruCls) и коллекциями этих объектов.

    Для выборки объектов вместо выборки их записей из БД существует набор статических методов в одном из основных классов Gooru.cms - class:/gooru/class/GooruCls.php

    Выборка объектов осуществляется с помощью массива выборки (см, {link:Массив выборки}). См. также раздел {link:Коллекции}

    Работа с базой данных

    Подключение и выполнение запросов

    Параметры подключения к БД находятся в файле open:/conf_db.php

    Для подключения к БД, выполнения и разбора запросов в Gooru.cms существует встроенный синглтон class:/gooru/class/DB.php интерфейса iDB, получить который можно, как и любой другой синглтон, в любой части кода c помощью Locator: example:db.php

    Конструктор запросов

    Класс class:/gooru/class/SqlCreator.php конструирует SQL-запросы, а также может их выполнять. На практике он используется редко вследствие того, что, обычно, требуется получить из БД выборку уже готовых объектов (товары, категории, пользователи и т.д.), а не непосредственно данные таблиц. "Думать" над списком получаемых полей делегируется классам-сущностям, наследующим основной класс {link:GooruCls}. Через классы-сущности производится и выборка. Но так как в конечном итоге запросы для выборки всё равно конструируются с помощью SqlCreator (внутри методов GooruCls), её синтаксис будет описан именно в этом разделе.

    Сам конструктор всегда вызывается через Locator по его интерфейсу, поэтому Вы можете переопределять его методы в своём классе, расширяющим SqlCreator

    Массив выборки

    Как правило, параметры передаются всего в одном массиве в метод build_from_array() для SELECT/DELETE запросов или в метод build_from_array_extended() для INSERT/UPDATE запросов. Не приходится запоминать и использовать много разных методов для разных условий. См. также, примеры кода ниже.

    Распознаваемые ключи массива выборки:

    • имя_поля

      Если значение — скаляр, то означает равенство поля значению в условии WHERE, при этом значение будет передано как параметр, как в примере выше с array('Parent' => 0). Также в качестве ключа используется и "название_таблицы.имя_поля", особенно в join-запросах.

      Если значение — список из одного элемента, то в условии WHERE элемент будет вставлен без изменений, как в примере выше с array('ID' => array("ID BETWEEN 10 AND 20")). Всё, что не является просто условием равенства полю какому-то значению, должно передаваться именно так.

      Если значение — список из двух элементов, то в условии WHERE первый элемент будет вставлен без изменений, а второй параметр должен быть списком параметров. Например,

      array
      (
      	'Name' => array
      	(
      		"(Name LIKE ? OR Name LIKE ?)",
      		array('К%', 'М%')
      	)
      );
      

    • limit — без изменений добавляется справа от LIMIT. Например, array('limit' => '10, 20') означает LIMIT 10, 20
    • num — натуральное число, означающее количество выбранных записей. Параметр используется очень широко для переключателей страниц. Например, array('num' => 20) для начальной страницы будет означать LIMIT 0,20; но, если в URL передано /page2/, то в запросе будет LIMIT 20,20; если /page3/, то LIMIT 40,20
    • what

      Если значение — строка, то она добавляется к expression по умолчанию (имя_таблицы.*). Например, array('what' => 'IF(Name = '', 1, 0) as empty_name') даст в итоговом запросе:
      SELECT mytable.*, IF(Name = '', 1, 0) as empty_name FROM mytable....

      Если значение — список из одного элемента, то он и будет являться expression запроса. Например, array('what' => array("ID, Name")) будет означать
      SELECT ID, Name FROM mytable....

    • group_by — без изменений добавляется справа от GROUP BY. Например, array('group_by' => 'Name')
    • having — без изменений добавляется справа от HAVING. Например, array('having' => 'Parent != 0')
    • order — без изменений добавляется справа от ORDER BY. Например, array('order' => 'Name ASC, ID ASC')
    • distinct — если true, то после SELECT будет добавлено DISTINCT. Например, array('distinct' => true)
    • ignore — если true, то после INSERT будет добавлено IGNORE. Например, array('ignore' => true)
    • use_index — если указан, то значение элемента будет в скобках конструкции USE INDEX (). Например, array('use_index' => 'ID2') даст USE INDEX (ID2)
    • force_index — если указан, то значение элемента будет в скобках конструкции FORCE INDEX (). Например, array('use_index' => 'ID2') даст FORCE INDEX (ID2)
    • straight_join — если true, то в SELECT-запросе будет указано STRAIGHT_JOIN. Например, array('straight_join' => true)
    • sort — если true, то конструктор автоматически добавит в начало ORDER BY условие, полученное из get-переменной $_GET['sort'] вида &sort=Name-asc. Это удобно при выводе html-таблиц.
    • join_... — если указан ключ массива, имя которого начинается с "join_", то его значение будет использовано в JOIN-условии в соответствующем месте запроса. При этом сами ключевые слова INNER JOIN, LEFT JOIN и прочие - необходимо тоже указывать. Например,
      $a = array(
      		'join_catalog_cats' => "INNER JOIN catalog_cats ON catalog_cats.ID = catalog_models.CatID",
      		'join_catalog_brands' => "LEFT JOIN catalog_brands ON catalog_brands.ID = catalog_models.TopBrandID",
      	);

      Рекомендуется после join_ указывать именно имя привязываемой таблицы, как сделано в примере выше. Так делается в Gooru.cms и позволяет в случае его обратиться и отменить join нужной таблицы по ключу..

    • union_... — если указан ключ массива, имя которого начинается с "union_", то его значение должно быть массивом выборке, которое сконструировано и добавлено в условие UNION. Иными словами, union_ тоже является массивом выборки.
    • global_order — используется аналогично 'order', но в случае UNION как общее условии сортировки после всех union.

    Распознаваемые значения ключей, используемые для полей типа datetime (в Gooru.cms datetime хранятся в UTC):

    • today — означает с today 00:00:00 по today 23:59:59 (конвертация в UTC автоматичски). Например, array('Created' => 'today');
    • yesterday — означает с yesterday 00:00:00 по yesterday 23:59:59 (конвертация в UTC автоматичски)
    • week — означает с today -7 days 00:00:00 по today 23:59:59 (конвертация в UTC автоматичски)
    • month — означает с today -30 days 00:00:00 по today 23:59:59 (конвертация в UTC автоматичски)

    Если массив выборки передается в метод build_from_array_extended() с параметром $is_add = true (то есть при INSERT), то

    • Если в нем не задан ключ Created, а в таблице присутствует поле Created — в SET вставляется Created = NOW()
    • Если в нем не задан ключ UserID, а в таблице присутствует поле UserID — ключ создаётся со значением ID текущего пользователя (если пользователь не авторизован, то 0)
    • Если в нем не задан ключ SessionID, а в таблице присутствует поле SessionID — ключ создаётся со значением идентификатора текущей сессии (создаётся, если не создана)
    • Если в нем не задан ключ Lang, а в таблице присутствует поле Lang — ключ создаётся со значением кода текущего языка (по умолчанию - ru)
    • Если в нем не задан ключ IP, а в таблице присутствует поле IP — ключ создаётся со значением IP из Locator::getst('iUser')->get_ip_long()

    Если массив выборки передается в метод build_from_array_extended() с параметром $is_add = false (то есть при UPDATE), то

    • Если в нем не задан ключ ModifiedDate, а в таблице присутствует поле ModifiedDate — в SET вставляется ModifiedDate = NOW()
    • Если в нем не задан ключ ModifiedBy, а в таблице присутствует поле ModifiedBy — ключ создаётся со значением ID текущего пользователя (если пользователь не авторизован, то 0)

    Пример использования конструктора запросов: example:sql_creator.php

    Работа с модулями

    Расположение

    В Gooru.cms модуль является директорией, обязательно содержащий файл имя_папкиModule.php . Встроенные модули расположены в /gooru/modules/, пользовательские модули должны располагаться в директории /custom.

    Управление из админки

    Управление модулями, установка новых модулей, удаление модулей производится в таблице Настройки / Модули.

    • Название используется в админке
    • Код должен соответствовать имени директории модуля и быть уникальным
    • Приоритет - целое число, по убыванию которого производится сортировка модулей при выборке из БД.
    • Сортировка в меню - целое число, по возрастанию которого модули выводятся в меню админ-панели.
    • Скрыть (глазик слева) - временно деактивировать модуль

    Встроенные модули не могут быть удалены, только деактивированы.

    Добавление модуля

    Чтобы добавить модуль в Вашу копию Gooru.cms:

    1. Создайте директорию модуля в /custom например, /custom/Test.

    2. Создайте в ней файл имя_директорииModule.php, содержащей класс Вашего модуля (см. ниже), например, /custom/TestModule.php.

    3. В админке в Настройки / Модули нажмите добавить запись, впишите код модуля "Test" в поле Код, придумайте название в поле Название, и нажмите ОК.

    Установка модуля из zip-архива

    Чтобы установить модуль из zip-архива, просто нажмите кнопку "Установить из файла" в Настройки / Модули

    Zip-архив представляет собой архив содержимого директории модуля без самой директории, и должен называться код_модуля.zip (например, CustomModule.zip). При установке в /custom будет создана директория (в примере, директория /custom/CustomModule), а в неё разархивировано содержимое архива. Если в директории модуля существует файлы с расширением .sql, они будут выполнены, и удалены.

    Пример zip-архива CustomModule

    CSS модулей

    Стили встроенных модулей в Gooru.cms вынесены в одну директорию /gooru/css.

    Стилевые файлы пользовательских модулей должны быть размещены в поддиректории /css директории Вашего модуля (пример, /custom/CustomModule/css)

    Для того, чтобы стили Вашего модуля автоматически подключались в HEAD, имя каждого css-файла должно начинаться с:

    • "styles_desktop" для десктопной версии
    • "styles_mobile" для мобильной.
    • "styles_all" для обеих версий. Подключаются перед desktop и mobile

    Например, в демострационном zip-архиве (выше) модуля CustomModule присутствует директория css с тремя файлами внутри: styles_desktop_CustomModule.css, styles_desktop_CustomModule_some.css, styles_mobile_CustomModule.css

    Подробнее о стилях в Gooru.cms см. раздел {link:Работа с CSS}

    Javascript модулей

    Javascript встроенных модулей в Gooru.cms вынесены непосредственно в директории модулей (для удобства разработчиков).

    js-файлы пользовательских модулей должны быть размещены в поддиректории /js директории Вашего модуля (например, /custom/CustomModule/js)

    Для того, чтобы js-файл автоматически подключался в HEAD, имя файла должно начинаться с:

    • "scripts_desktop" для десктопной версии
    • "scripts_mobile" для мобильной.
    • "scripts_all" для обеих версий. Подключаются перед desktop и mobile

    Например, в демострационном zip-архиве (выше) модуля CustomModule присутствует директория js с файлом scripts_all_CustomModule.js внутри.

    Подробнее о стилях в Gooru.cms см. раздел {link:Работа с Javascript}

    Справочник типов полей таблиц

    Справочник классов

    GooruCls

    Самый важный класс Gooru.cms, являющийся базовым классом, представляющим "сущности" (например, "сущность" таблицы catalog_models - товар, сущность таблицы pages - страница).

    Практически для всех встроенных "обычных" таблиц в Gooru.cms созданы классы-сущности, расширяющие GooruCls. Например, класс /gooru/modules/Page/Page.php представляет таблицу БД pages, и расширяет GooruCls, добавляя некоторые свойства и методы.

    GooruCls->facade

    Контроллеры

    Gooru.cms исключительно проста в обработке url: uri разбивается по слэшам, и, начиная с левого элемента ищется страница в таблице {link_table:pages Страницы} с кодом этого элемента. Если найдена, то её подстраница. И так далее, пока либо не кончится uri, либо код не найден.

    Например, для uri /about/branch/ будет найдена страница {link_table:pages&parent=3 Наши филиалы}. А для /catalog/audio-video-foto/c336/ только страница {link_table:pages Каталог (вверху)}, потому что у этой страницы нет подстраниц.

    Если у найденной страницы указан "тип страницы" как "текстовая" (=пустая строка в поле БД), то контроллера нет. Выведется её заголовок, подразделы (если есть), текст и т.д. Как на странице {url:/about/branch/ Наши филиалы}

    Если указан "тип страницы", то подключаются еще 3 файла-"контроллера", если такие файлы вообще существуют:

    1. модуль_тип_init.php перед итоговым HTML-кодом страницы
    2. модуль_тип_prepend.php перед "текстом страницы"
    3. модуль_тип_content.php после "текста страницы"

    Последний используется реже, так как заполняемый в "текст страницы" текст, обычно, является seo-шным и выводится в самом низу, после полезного контента. Например, полезное центральное содержимое страницы {url:/payment-systems/ Оплата} между H1 и подвалом выводит файл open:/gooru/modules/Pay/Pay_payment_systems_content.php, так как тип её страницы "payment_systems", и он объявлен именно в модуле оплаты open:/gooru/modules/Pay/PayModule.php в методе get_page_types(), возвращающий массив, где ключи - типы страниц, а значения - названия типов (для вывода в селект в админке).

    модуль_тип_init.php , обычно, используется для обработки POST-запросов, или некоторых специфических задач. Ибо часто приходится делать self-redirect, при котором совершенно не нужно идти дальше, до кода, формирующего контент. Это экономит ресурсы.

    Помимо "контроллеров" типов страниц, подключаются общие контроллеры модулей. Например, файлы: open:/gooru/modules/Catalog/Catalog_init.php и open:/gooru/modules/Catalog/Catalog_prepend.php подключаются на всех типах страниц, объявленных в модуле Catalog: open:/gooru/modules/Catalog/CatalogModule.php

    Если в модуле объявлено свойство always, то контроллеры модуля будут подключаться вообще на всех страницах сайта. Например, если protected $always = 'init,content,prepend';, то подключатся все три на всех страницах. А, например, в модуле Catalog always = 'init', поэтому на всех страницах сайта будет подключен только Catalog_init.php

    Если на странице должны быть вызваны сразу несколько файлов (например, у нескольких модулей стоит $always), то они вызываются в порядке убывания поля "приоритет" из таблицы {link_table:modules Модули}

    Также, существуют глобальные файлы-контроллеры, вызываемые всегда, и не относящиеся к определенному модулю:

    1. /gooru/general/init.php подключается перед всеми init модулей
    2. /gooru/general/init_after.php подключается после всех init модулей
    3. /gooru/general/prepend.php подключается после всех prepend модулей
    4. /gooru/general/content.php подключается после всех content модулей

    Если какой-либо из этих файлов Вы желаете отредактировать, просто скопируйте его в /custom и редактируйте.

    Если Вам нужно написать несколько несложных операций, удобно это делать без создания своих модулей, без типов страниц, и без переопределения контроллеров существующих. Для этого воспользуйтесь общими контроллерами в папке /custom : /custom/_init.php, /custom/_prepend.php и /custom/_content.php

    Например, написав в файле /custom/_content.php

    
    на всех url Вашего сайта, заканчивающихся на /somecode/ будет выведена строка hello после полезного контента.
    
    

    Данный механизм очень удобен для небольших изменений конкретного сайта. Фактически, в этом случае нет ни модулей, ни типов страниц. С помощью "if" и uri вы быстро пишете, что надо выполнить в одном, а не нескольких, файлах. Для серьезной разработки и крупных операций следует уже создавать свои модули, и отдельные типы страниц.

    Метод request()

    Перед вызовом всех init, у каждого модуля вызывается метод request(), если он в этом модуле объявлен. Данный механизм используется в тех случаях, когда вывода "страницы сайта" не должно произойти вообще, и в принципе никакие контроллеры не нужны. Например, на странице {url:/export/yml/ выдачи yml} выводится просто xml-код. Это определяется в модуле open:/gooru/modules/Shop/ShopModule.php, в методе request(), который сам должен проанализировать uri, выполнить нужные операции (например подключить нужные файлы), после чего завершиться как exit; Это очень экономит ресурсы, и сильно сократит время выдачи контента.