<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
			<channel>
			<title>Alto CMS/Блог разработки Alto CMS</title>
			<link>http://79.174.14.219/blog/dev/</link>
			<description><![CDATA[Инфрмация о релизах Alto CMS]]></description>
			<language>ru</language>
			<managingEditor>vladimir.o.yuriev@gmail.com</managingEditor>
			<webMaster>noreply@altocms.ru</webMaster>
			<generator>Alto CMS v.1.5.0b1</generator>
							<item>
					<title>Еще немного о ближайших планах по развитию движка</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1868/</guid>
					<link>http://79.174.14.219/1868.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[Мне пишут в личку и спрашивают о подробностях. Понимаю, люди хотят бОльшей определенности. Решил вот написать чуть больше о своих планах. Уж не знаю, прибавит это определенности или нет, но, возможно, кому-то это будет интересно.<br>
<h5>Конфигурация движка</h5>
Громадное число настроек вынесено во внешний файл. Это и хорошо, и плохо одновременно. Хорошо, потому что конфиг-файлы — это php-массивы, синтаксис которых нетрудно усвоить новичку-непрограммисту, даже совсем «чайнику». Плохо, потому что в таком количестве настроек бывает сложно разобраться и не запутаться. И иногда бывает, конечно, что какие-то настройки уже теряют смысл и не используются, но конфиг-файл засоряют. Но, как бы там ни было, я считаю такой способ настроек наиболее оптимальным.<br>
<br>
Манифест-файлы плагинов и шаблонов сейчас в XML-формате. Есть желание перенести их в JSON, но я еще не решил, будет ли это в ближайшей версии или позже.<br>
<br>
<h5>Расширение функционала</h5>
Функционал движка расширяется с помощью плагинов. Основным механизмом расширения является «динамическое автонаследование» — механизм, который я придумал и обкатал еще на базе ЛС, и который позволяет задействовать принципы ООП по максимуму.<br>
<br>
Второй механизм — хуки. Причем, в Alto CMS вызов хуков оптимизирован так, что обработка каждого хука вызывается только в том случае, если есть зарегистрированный обработчик. Обработчики хуков могут задаваться как в виде самостоятельных классов, так и прямо в коде. В новой версии планируется еще один способ задания хуков — в конфигурационных файлах.<br>
<br>
И в новой версии будет добавлен еще один механизм: замещение классов. Например, при вызове модуля User, файл класса ModuleUser.php сначала будет проверяться в папке <strong>/protected/app/classes/modules/user/</strong>, потом в <strong>/protected/common/classes/modules/user/</strong> Т.е. для того, чтобы расширить модуль User, достаточно будет положить соответствующий файл в нужную подпапку в папку приложения, причем класс из <strong>/protected/app/</strong> может быть расширением класса из <strong>/protected/common/</strong>. Такой вариант задумал давно, но только в новой версии возможна его реализация, т.к. есть поддержка неймспейсов.<br>
<br>
<h5>Шаблонизация и ассеты</h5>
В свое время шаблонизатор Smarty подвергался критике из-за своей медлительности. Но третья версия Smarty вполне себе шустрая и гибкая. Сказать по правде, мне больше нравится шаблонизатор Fenom, но менять один шаблонизатор в обозримом будущем я не собираюсь.<br>
<br>
В одном шаблоне сейчас весьма приличное число файлов. Но тут получается так: либо мы дробим шаблоны на мелкие составляющие и получаем бОльшую гибкость и функциональность, либо делаем файлы шаблонов более монолитными, но это будет в ущерб гибкости и простоте. Недавно подкинули идею — а не собирать ли из мелких кусочков более крупные шаблоны? Пока не могу сказать, будет это или нет.<br>
<br>
Шаблоны из коробки в обозримом будущем останутся на базе Bootstrap 3 (я пока не нашел убедительных доводов для перехода на четвертый бутстрап)<br>
<br>
Ассеты — css- и js-файлы в новой версии могут группироваться и размещаться в разных местах генерируемого HTML-кода. Например, часть файлов можно разместить в тегах head, а другую часть — в сам низу страницы.<br>
<br>
Честно говоря, css- и js-файлы в том виде, как сейчас — это моя боль. Им однозначно требуется глубкий рефакторинг, но нет сейчас на это ресурсов. Если есть желающие серьезно заняться фронтендом в движке — пишите.<br>
<br>
<h5>Роутинг</h5>
Роутинг в Альто не просто гибкий, а очень гибкий. И он настраивается на двух уровнях — в конфиге задаются настройки до класса контроллера (или экшена, если в терминологии ЛС). И второй уровень — это настройки в самом контроллере. В ветке 1.х.х роутинг внутри контроллеров хоть и переделывался несколько раз, но подходы оставались те, что пришли из ЛС. В ветке 2.х.х будет реализован современный подход — роутинг с поддержкой стандарта PSR-7, и планируется это делать на Aura.Router, но с несколько измененным синтаксисом. В принципе, очень уж жесткой привязки к Ауре нет, так что это можно реализовать с помощью любой другой подобной библиотеки.<br>
<br>
<h5>Работа с базами данных и кеширование</h5>
Из коробки декларируется поддержка MySQL, PostgreSQL и MS SQL. Но это, скажем честно, декларации. Знаю, что есть проекты на Альто, использующие Постгресс, но чтоб нормально так завести, нужно иметь прямые руки и некоторый набор знаний. Есть очень серьезные намерения добиться действительно нормальной поддержки Постгресса прям из коробки, чтоб раз — и завел. Я даже этот сайт сам хочу перенести в будущем на Постгресс.<br>
<br>
ORM — еще один мой головняк. У меня есть пара собственных реализаций ORM, которые работают в разных проектах, но каждая имеет свои недостатки. В то же время, я убедился, что 80% запросов можно писать на ORM, очень экономя время разработки, а остальные 20% можно делать на голом SQL. В ближайшей версии планирую расшить самые узкие места в мапперах, а вопрос о внедрении полноценной ORM-системы откладываю на потом.<br>
<br>
<h5>Собственно, сам функционал</h5>
Alto CMS — это многопользовательский мультиблоговый движок с элементами соцсетей, и он таким, в общем-то, остается (хотя для меня это — очень удобный инструмент для разработки сайтов очень разной направленности). Каких-то новых супервозможностей в обозримом будущем не планируется, но в планах остаются фичи, которые давно хотелось сделать:<br>
* Базовая поддержка мультиязычности<br>
* Полный уход от легаси-кода при работе с изображениями<br>
* Доп.поля ко всем сущностям<br>
* Универсальные теги, которые можно цеплять не только к топикам, а вообще к любым сущностям<br>
* Категории — есть наработки, но не решил, как лучше с ними поступить — то ли прям в движок, то ли отдельным плагином<br>
* Ну и всякие плюшки по мелочам<br>
<br>
Чот хотел кратенько совсем, а получилось довольно много букв]]></description>
					<pubDate>Sun, 03 Dec 2017 16:53:21 +0300</pubDate>
									</item>
							<item>
					<title>Выложен в публичный доступ репозитарий Альто 2.0</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1867/</guid>
					<link>http://79.174.14.219/1867.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[Кому это интересно — выложил в паблик репо второй версии: <a href="https://github.com/altocms/altocms2" rel="nofollow">https://github.com/altocms/altocms2</a><br>
<br>
<strong>ВНИМАНИЕ</strong>: <strong>это НЕ релиз, НЕ выход новой версии, это вообще НЕ рабочая версия, это репозитарий, в котором в настоящее время ведется разработка</strong>. Это только начало обновления движка, много чего еще нужно доделать там. Как я уже говорил, есть наработки, которые сейчас выполнены в виде плагинов и просто хардкодных хаков, и я постепенно их внедряю в движок. Я б, конечно, не стал в таком виде выкладывать, поковырялся бы еще, но раз публика просит...<br>
<br>
Что можно сейчас увидеть в репо:<br>
1) Изменена структура папок. В первую очередь это сделано в целях повышения безопасности. Почти весь движок убран в папку <strong>/protected</strong> — это папка, к которой нет доступа снаружи. Если сайт работает под Apache, то нет необходимости раскидывать запрещающие файлы .htaccess по разным папкам, достаточно положить его в <strong>/protected</strong>. Если у вас все крутится под Nginx, то в конфиге закрываете доступ извне только к этой папке. При желании ее вообще можно вынести за пределы корневой папки сайта.<br>
<br>
2) Добавлена поддержка Composer. В движке пока еще осталось несколько библиотек, у которых нет по-человечески оформленных пакетов, и лежат они по прежнему в <strong>/protected/engine/libs</strong>, но все остальные сторонние библиотеки вынесены в <strong>/protected/vendor</strong> и могут обновляться композером. Обратите внимание, что общий пакет зависимостей собирается из нескольких файлов:<br>
/protected/engine/composer.engine.json<br>
/protected/common/composer.common.json<br>
/protected/app/composer.app.json<br>
/protected/app/plugins/composer.plugins.json<br>
<br>
При этом два первых файла являются обязательными, а два других — опциональными (т.е. их может не быть). При установке плагинов их зависимости должны прописываться в файл <strong>composer.plugins.json</strong>. А если вам при разработке сайта потребовались какие-то свои зависимости, то вы можете их прописать в <strong>composer.app.json</strong>. Что это дает:<br>
а) легко можно обновлять все зависимости одной командой<br>
б) исключается дублирование, когда, например, разным плагинам нужна одна и та же библиотека<br>
в) если вдруг возникает конфликт версий, то Composer это обнаружит при обновлении<br>
<br>
3) Классы ядра переведены на неймспейсы. В перспективе, конечно, надо все классы на неймспейсы переводить<br>
<br>
Что еще из более-менее крупного:<br>
* Удалены костыли «совместимости», возможно, где-то следы еще остались, будут подчищаться по мере обнаружения.<br>
* В конфиге можно задать несколько баз данных и в запросах указывать, к какой базе идет обращение. Причем, фактически база может быть и одна, но разные наборы таблиц с разными префиксами<br>
* Теги — универсальная сущность, а не только для топиков<br>
* Хеширование паролей — через password_hash()<br>
* Меню и виджеты из основного конфига убраны, теперь это исключительно в настройках шаблона задается<br>
<br>
В планах так же роутинг сделать на базе <a href="https://github.com/auraphp/Aura.Router/tree/3.x" rel="nofollow">https://github.com/auraphp/Aura.Router/tree/3.x</a><br>
А кеширование на базе <a href="http://www.phpfastcache.com/" rel="nofollow">http://www.phpfastcache.com/</a>]]></description>
					<pubDate>Thu, 30 Nov 2017 01:13:32 +0300</pubDate>
									</item>
							<item>
					<title>Ну, и что дальше? — спросите вы. А дальше — Alto CMS v.2.0</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1865/</guid>
					<link>http://79.174.14.219/1865.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[Конечно, очень хотелось бы в новой версии сразу запилить много крутых и интересных фич. Но немного разочарую тех, кто этого ждет прямо сейчас. Дело в том, что приходится выбирать — пилить новые фичи на том же коде, что есть сейчас, или сначала обновить кодовую базу, и на ней уже реализовывать новый функционал.<br>
<br>
Я выбираю второй подход. Ключевые изменения в новой версии будут такие:<br>
<ul><li>Отказ от поддержки совместимости со старым Лайвстритом (на всякий случай отмечу — поддержки с новым ЛС даже и не намечается, его никогда не будет), удаление кучи старого кода, который станет не нужным из-за этого.</li><li>Новая организация папок, конфигурационных файлов, одновременная работа с несколькими базами</li><li>Поддержка Composer и обновление всех используемых библиотек, как на бекенде, так и на фронтенде</li><li>С точки зрения фронтенда — поддержка «плиточного» размещения контента в «коробочных» шаблонах</li></ul>
Совместимость со старыми плагинами, в большинстве своем, тоже сломается. Но пытаться как-то ускориться с гирями на ногах — это невозможно в принципе.<br>
<br>
Вот, как-то так обстоит дело, если очень крупными мазками обрисовать.]]></description>
					<pubDate>Sun, 19 Nov 2017 20:44:40 +0300</pubDate>
									</item>
							<item>
					<title>И снова здравствуйте!</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1859/</guid>
					<link>http://79.174.14.219/1859.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[<img src="https://altocms.ru/uploads/images/00/00/02/2017/11/08/0u787c3963-25503957-67874711.jpg"><br>
В последнее время прямо какой-то шквал запросов по разным каналам относительно судьбы движка. Такое впечатление, что народ сначала разбредшись кто куда, попробовал найти альтернативу, и кто-то, возможно, и нашел, но нашли ее точно не все, и некоторые вернулись к Альто. И это не удивительно — я сам за последние полгода уже три проекта начинал на чем-то другом, но потом переделывал под Альто. Меня многое, очень многое не устраивает в этой CMS, но вот факт — в других движках меня не устраивает еще больше.<br>
<br>
Поэтому отвечаю на самый главный вопрос: AltoCMS — все? Нет, не дождетесь! Во всяком случае, не сейчас. Другое дело, что в последнее время больше точил его для себя, много экспериментировал, не выкладывая результатов экспериментов. Но если есть тут люди, которые действительно хотят развития движка, готовы в этом как-то участвовать — что ж, давайте вдохнем свежую струю!<br>
<br>
Предлагаю всем, кто чего-то хочет и может предложить — от идей и советов до дизайна, от исправления багов и написания плагинов до работы над самим движком — в общем, все, чем можете помочь, пишите в комментах. А там разберемся, что да как.<br>
<br>
ЗЫ. И прошу прощения у всех, кто писал в личку и не получил ответа. Постараюсь разгрести в ближайшие дни.]]></description>
					<pubDate>Wed, 08 Nov 2017 17:20:17 +0300</pubDate>
									</item>
							<item>
					<title>Версия 1.1.29 — багфиксы и небольшие доработки</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1828/</guid>
					<link>http://79.174.14.219/1828.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[Ничего революционного версия эта не несет, но помимо мелких багфиксов, есть пара небольших, но полезных доработок:<br>
<br>
1) В когфиг добавлены опции для настройки пнели вставки изображений в топик (особенно актуально для тех, кто перешел на HTTPS)<br>
2) Так же в конфиги движка и шаблонов добавлены дополнительные опция для отображения фотосета<br>
<h5>Загрузка изображений в топик</h5>
В связи с переходом на сайтов HTTPS во весь рост встала проблема вставки изображений в топик. Если ваш ресурс уже переехал на HTTPS, но в топик вставляются изображения с ресурсов без HTTPS, то страница в целом будет считаться незащищенной. Для того, чтоб эту проблему решить, в конфиг движка добавлена новая опция:<br>
<pre class="prettyprint"><code>$config[&#39;module&#39;][&#39;topic&#39;][&#39;img_panel&#39;][&#39;external&#39;] = 1;</code></pre><br>
По умолчанию значение 1 — разрешается вставлять изображения с внешних ресурсов (т.е. все будет работать так, как сейчас). Вы можете так же задать значения:<br>
0 — вставка с внешних ресурсов запрещена, изображения можно только с компьютера загружать<br>
2 — можно указать внешний ресурс, но изображение будет загружаться на ваш сайт, а не внешней ссылкой вставляться<br>
<br>
Плюс добавлена еще одна опция конфига — <strong>module.topic.img_panel.show_params</strong>, если задать так:<br>
<pre class="prettyprint"><code>$config[&#39;module&#39;][&#39;topic&#39;][&#39;img_panel&#39;][&#39;show_params&#39;] = 1;</code></pre>То в окне загрузке изображений блок, где задается размер и можно задать подпись к загружаемому изображению, этот блок по умолчанию будет открыт.<br>
<br>
<h5>Настройки фотосета</h5>
Во-первых, добавлена опция в конфиг дфижка <strong>module.topic.photoset.always_append</strong>. Если вы хотите, чтобы не было у пользователей такой «галки» как «Отображать фотосет», и чтобы фотосет всегда добавлялся в конец топика, то надо этой опции задать значение <strong>true</strong>:<br>
<pre class="prettyprint"><code>$config[&#39;module&#39;][&#39;topic&#39;][&#39;photoset&#39;][&#39;always_append&#39;] = true;</code></pre><br>
Во-вторых, для можно задать максимальную высоты миниатюры фотосета в пикселя:<br>
<pre class="prettyprint"><code>$config[&#39;module&#39;][&#39;topic&#39;][&#39;photoset&#39;][&#39;thumb&#39;][&#39;height&#39;] = 200;</code></pre><br>
Наконец, можно более тонко настроить отображение фотосета, но это задается уже в конфиге шаблона:<br>
<pre class="prettyprint"><code>$config[&#39;view&#39;][&#39;cfg&#39;][&#39;set&#39;] = array(
    &#39;photoset&#39; =&#62; array(
        &#39;gallery&#39; =&#62; array(
            &#39;fillLastRow&#39; =&#62; false, // заполнение последней строки изображений
            &#39;minHeight&#39; =&#62; 100,  // минимальная высота изображений
            &#39;maxHeight&#39; =&#62; 200, // максимальная высота изображений
            &#39;fixedHeight&#39; =&#62; null, //
            &#39;minWidth&#39; =&#62; 70, // Минимальная ширина, которая должна быть у изображения
            &#39;margin&#39; =&#62; 1, // отступ вокруг миниатюры
        ),
    ),
);</code></pre>По комментариям, полагаю, все понятно. Поясню только с высотой: можно задать диапазон — <strong>minHeight</strong> и <strong>maxHeight</strong> (тогда высота миниатюр будт высчитываться, чтоб, по возможности, оптимально заполнить пространство. А можно задать фиксированную высоту <strong>fixedHeight</strong>.]]></description>
					<pubDate>Sun, 23 Apr 2017 18:57:14 +0300</pubDate>
									</item>
							<item>
					<title>ВАЖНО: Критическое обновление</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1763/</guid>
					<link>http://79.174.14.219/1763.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[В AltoCMS используется библиотека PHPMailer, в которой была обнаружена критическая уязвимость. В версии Альто 1.1.27 эта библиотека обновлена.<br>
<br>
Настоятельно рекомендуется обновить движок до версии 1.1.27! Или обновить хотя бы саму библиотеку, которая находится в директории <strong>/engine/libs/phpMailer</strong>]]></description>
					<pubDate>Wed, 28 Dec 2016 18:51:11 +0300</pubDate>
									</item>
							<item>
					<title>Версия 1.1.23 — небольшие исправления и чуть-чуть новенького</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1729/</guid>
					<link>http://79.174.14.219/1729.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[Таки вышел релиз Alto CMS 1.1.23. Каких-то «прорывных» фишек в ней нет, она, главным образом, исправляет ряд обнаруженных ошибок и чуть-чуть добавляет некоторых новых возможностей для разработчиков.<br>
<br>
Вот список основных изменений:<br>
<br>
Исправлены ошибки:<br>
<ul><li>несовместимость с php 5.3</li><li>установка в конфиге экшена/ивента по умолчанию</li><li>иногда нарушался порядок подключения js-файлов</li><li>не работал ресайз в методе <strong>getPhotosetMainPhotoUrl()</strong> топика</li><li>в некоторых случаях ломалась цветопередача для загружаемых jpeg-файлов с CMYK-профилем (очень старая ошибка, но никак не могли ее выловить)</li><li>исправлен еще ряд мелких, но неприятных ошибок в коде и шаблонах</li></ul>
<br>
Обновлены сторонние библиотеки:<br>
<ul><li>CSSTidy до 1.5.5</li><li>JShrink до 1.1.0</li><li>jQuery до 1.12.4</li></ul>
<br>
Добавлено:<br>
<ul><li>местоположение директории для для загрузки и хранения изображений</li><li>для js-файлов можно указывать атрибуты <strong>defer</strong> и <strong>async</strong></li><li>выбор изображений топика по параметрам</li><li>методы AppendAsset() и PrependAsset() модуля Viewer</li><li>вызов E::Module(&#39;Name&#39;) теперь кеширует экземпляр модуля, что увеличивает быстродействие</li><li>ну и кое-что еще по мелочи</li></ul>
<br>
Кому интересны подробности про добавленные «плюшки», то добро пожаловать под кат <h5>Местоположение директории для загрузки и хранения изображений</h5>
По умолчанию изображения загружаются в директорию <strong>/uploads</strong>, находящуюся в корневой директории сайта. Но иногда возникает желание загружать и хранить изображения в куда-то в другое место, возможно, на отдельный хост, специально создаваемый для статических файлов. Для этого в конфиге появились новые параметры:<br>
<pre class="prettyprint"><code>$config[&#39;module&#39;][&#39;uploader&#39;][&#39;drives&#39;] = array(
    &#39;local&#39; =&#62; array(
        &#39;dir&#39; =&#62; &#39;___path.root.dir___&#39;,
        &#39;url&#39; =&#62; &#39;___path.root.url___&#39;,
    ),
);</code></pre><br>
Нетрудно догадаться, что здесь задается полный путь на локальном диске до места расположения директории <strong>/uploads</strong> и URL к этой директории извне. Если изображение в базе сохраняется в виде <strong>&#39;@uploads/path/to/image.jpg&#39;</strong>, то символ <strong>&#39;@&#39;</strong> заменяется на пути, указанные в конфиге, как показано выше.<br>
<br>
<h5>Атрибуты defer и async для js-файлов</h5>
Если вы в курсе, зачем нужны атрибуты <strong>defer</strong> и <strong>async</strong> для загружаемых скриптов, то теперь вы можете их задавать в наборах js-файлов в конфигурации:<br>
<pre class="prettyprint"><code>$config[&#39;assets&#39;][&#39;default&#39;][&#39;js&#39;] = array(
    &#39;___path.skin.dir___/assets/js/script1.js&#39; =&#62; array(&#39;defer&#39; =&#62; true),
    &#39;___path.skin.dir___/assets/js/script2.js&#39; =&#62; array(&#39;async&#39; =&#62; true),
);</code></pre><br>
Если в настройках задано слияние js-файлов, то файлы с заданными атрибутами будут группироваться, конечно же, отдельно. Грамотное использование этих атрибутов может значительно ускорить отображение загружаемых страницы сайта.<br>
<br>
<h5>Новые методы получения изображений топика</h5>
В сущность топика добавлены новые методы, которые можно вызывать так (считаем, что в <strong>$oTopic</strong> у нас экземпляр конкретного топика):<br>
<ul><li><strong>$oTopic-&#62;getImages()</strong> — возвращает все изображения топика (и включенные в текст, и в фотосет)</li><li><strong>$oTopic-&#62;getLoadedImages($aFilter = [])</strong> — возвращает загруженные изображения топика (т.е. изображения включенные в текст по ссылке, включены не будут); в метод может быть передан массив с набором фильтров для выборки нужных изображений (описание фильтра см. ниже), если фильтр не задан, то возвращаются все загруженные изображения.</li><li><strong>$oTopic-&#62;selectImage($aFilter = [])</strong> — возвращает первое из загруженные изображения топика (т.е. изображения включенные в текст по ссылке, включены не будут); фактически вызывает метод <strong>getLoadedImages()</strong> и берет первое значение из возвращенного массива.</li></ul>
<br>
Параметры фильтра методов <strong>getLoadedImages()</strong> и <strong>selectImage()</strong>:<br>
<ul><li>&#39;width-more&#39; =&#62; N — получить изображения с шириное более N пикселей</li><li>&#39;width-less&#39; =&#62; N — получить изображения с шириное менее N пикселей</li><li>&#39;height-more&#39; =&#62; N — получить изображения с высотой более N пикселей</li><li>&#39;height-less&#39; =&#62; N — получить изображения с высотой менее N пикселей</li><li>&#39;width-max&#39; =&#62; true — получить изображения с максимальной шириной</li><li>&#39;width-min&#39; =&#62; true — получить изображения с минимальной шириной</li><li>&#39;height-max&#39; =&#62; true — получить изображения с максимальной высотой</li><li>&#39;height-min&#39; =&#62; true — получить изображения с минимальной высотой</li></ul>
<br>
Параметры фильтров могут быть заданы в любой комбинации. При этом имеет значение порядок задания фильтров:<br>
<pre class="prettyprint"><code>$aFilter = [&#39;width-more&#39; =&#62; 799, &#39;height-max&#39; =&#62; true];
// Сначала будут выбраны все изображения с шириной более 799px, а потом из них будет выбрано с максимальной высотой 
$oImage = $oTopic-&#62;selectImage($aFilter);

// Сначала будут выбраны изображения с максимальной высотой, а из них - с шириной более 799px
$aFilter = [&#39;width-more&#39; =&#62; 799, &#39;height-max&#39; =&#62; true];
$oImage = $oTopic-&#62;selectImage($aFilter);
</code></pre><br>
Разумеется, эти методы могут быть использованы в шаблонах. Например, так:<br>
<pre class="prettyprint"><code>&#60;!-- выберем изображение с максимальными размерами, но не менее 800х600 --&#62;
{$aFilter = [&#39;width-more&#39; =&#62; 799, &#39;height-more&#39; =&#62; 599, &#39;height-max&#39; =&#62; true, &#39;width-max&#39; =&#62; true]}
{$oImage = $oTopic-&#62;selectImage($aFilter)}
{if $oImage}
    &#60;img src=&#34;{$oImage-&#62;getImageUrl(&#39;800х600crop&#39;)}&#34;&#62;
{else}
    &#60;img src=&#34;default-image.jpg&#34;&#62;
{/if}
</code></pre><br>
<h5>Методы AppendAsset() и PrependAsset() модуля Viewer</h5>
Это лишь «синтаксический сахар»: методы в зависимости от расширения подключаемого файла вызывают <strong>AppendStyle()/AppendScript()</strong> или <strong>PrependStyle()/PrependScript()</strong> соответственно]]></description>
					<pubDate>Sat, 29 Oct 2016 22:39:24 +0300</pubDate>
									</item>
							<item>
					<title>Что с Alto CMS? Да все нормально! Просто жара</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1694/</guid>
					<link>http://79.174.14.219/1694.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[<img src="https://altocms.ru/uploads/images/00/00/02/2016/07/27/0u3b0edb47-15a1514a-262066cc.jpg" align="right">На дворе лето, жара, деловая активность затихает, делать ничего не хочется... И, видя затянувшееся затишье, кто-то может подумать, что действительно все встало и ничего не делается. Но это обманчивое затишье! Сейчас я расскажу о делах текущих.<br>
<br>
Во-первых, надо, наконец, озвучить, что релиз версии 1.2 перенесен на осень. Жаль, конечно, но пришлось. Поэтому в августе выйдет очередная версия ветки 1.1.х с фиксами и небольшими улучшениями.<br>
<br>
Во-вторых, планируется выпуск трех серьезных плагинов: <strong>Компании</strong>, <strong>Афиша</strong> и — та-дам! — <strong>Магазин</strong>! Примечательно то, эти плагины создаются для реальных рабочих проектов. Плагины «Компании» и «Афиша» уже обкатываются на одном из сайтов (называть адрес сайта не буду, если его владелец посчитает нужным — озвучит). Плагин Магазин сейчас активно допиливается и вскоре тоже будет запущен в работу сразу на двух сайтах.<br>
<br>
И в-третьих, если кому-то не хватает динамики, живого общения, интерактива — для тех на сайте теперь работает чат! Посмотрите в нижний правый угол экрана: вот самая нижняя кнопка — это чат. Правда, для общения там нужно зарегистрироваться через аккаунт на гитхабе или на твитере. Но это ведь не препятствие для общения, правда?<br>
<br>
<h5>Несколько слов о плагине магазина.</h5>
<br>
В свое время юзер <a href="https://altocms.ru/profile/nikto/" data-alto-role="popover" data-api="user/282/info">nikto</a> начал разработку плагина NovaBuild (первоначальное название miniMarket). Почитать о плагине вы можете по ссылкам: <a href="https://altocms.ru/tag/miniMarket/">https://altocms.ru/tag/miniMarket/</a> и <a href="https://altocms.ru/tag/NovaBuild/">https://altocms.ru/tag/NovaBuild/</a>. <br>
<br>
Но через какое-то время разработка плагина была приостановлена. Некоторое время назад автор обратился ко мне с предложением выложить все наработки по плагину на гитхаб в открытый доступ, т.к. у него нет возможности дальше им заниматься, но чтоб наработки не пропали, он решил ими поделиться с сообществом. Даром. Т.е. безвозмездно.<br>
<br>
Каюсь, я до сих пор не выложил исходники, но сделаю это обязательно в ближайшее время. Но зато я взялся за активную доработку плагина (в чем мне очень помог <a href="https://altocms.ru/profile/andreyv/" data-alto-role="popover" data-api="user/220/info">andreyv</a>), и скоро он выйдет в свет.<br>
<br>
Наверняка у кого-то будет вопрос «а нафига, если полно вокруг полноценных магазинов?» Да, вокруг полно движков настоящих полноценных магазинов, в т.ч. оупенсорсных и бесплатных, обкатанных и вылизанных, с кучей шаблонов и дополнений. И, наверное, можно было бы сделать сквозную авторизацию Alto и, например, OpenCart или Magento. Но мы не ищем легких путей и идем своей дорогой.<br>
<br>
Альто — это, в первую очередь, контентный движок, т.е. он заточен на сайты, где контент — первичен. И магазин на таком сайте — это, с одной стороны, функционал, врезанный глубоко в сам движок, с другой — он вторичен.<br>
<br>
Говоря проще, если вы изначально хотите сделать хороший крутой магазин — берите движок магазина. Если же вы хотите сделать контентный ресурс (особенно, если делаете ставку на UGC — User Generated Content), а потом добавить к нему магазин — то берите движок Альто ставьте на него плагин магазина.]]></description>
					<pubDate>Thu, 28 Jul 2016 01:30:38 +0300</pubDate>
									</item>
							<item>
					<title>[dev] ActiveRecord в Alto CMS v.1.2. Часть 1</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1595/</guid>
					<link>http://79.174.14.219/1595.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[По сложившейся традиции пишу о наиболее интересных и важных нововведениях в движке еще до официального релиза. <br>
<br>
Не помню, возможно, писал уже о том, что я несколько раз подступал к реализации <strong>ActiveRecord</strong> в Альто. Причем, было большое желание не писать все с нуля, а подобрать уже готовую библиотеку и адаптировать ее к своим нуждам. Но, в силу разных причин, так и не получилось это сделать. Лайвстритовскую реализацию ORM в части задания критериев для выборки данных я считаю просто ужасной.<br>
<br>
В общем, все закончилось тем, что в Альто была выполнена своя реализация <strong>ActiveRecord</strong>, о которой сейчас и пойдет речь. <h5>Создание сущности-записи</h5>
Для работы с <strong>ActiveRecord</strong> создан специальный набор классов, который расположен в пространстве имен <strong>\<a href="https://altocms.ru/871.html" title="<strong>Alto&nbsp;</strong><br>Если вы собираетесь создавать сайт и выбираете для этой цели CMS (или «движок», как еще говорят), то наверняка у вас возникает вопрос: «А чем же Alto лучше других CMS? И годится ли для моих задач?»&lt;br/&gt;
&lt;br/&gt;
Выбирая Alto CMS, вы получаете «из коробки» функционал, который в других движках достигается установкой множества плагинов:" class="term">alto</a>\engine\ar</strong> (да-да, в Альто тихой сапой начинают использоваться пространства имен), и <a href="https://altocms.ru/1585.html" title="<strong>Сущность&nbsp;</strong><br>Сущность – это некий набор данных, которые называют «свойствами» (property). Например, сущность «Пользователь» (User) имеет такие свойства, как идентификатор, логин, адрес электронной почты, и т.д." class="term">сущность</a>, модуль и маппер в этом случае должны наследоваться соответственно от классов EntityRecord, ArModule и ArMapper, например:<br>
<pre class="prettyprint"><code>use <a href="https://altocms.ru/871.html" title="<strong>Alto&nbsp;</strong><br>Если вы собираетесь создавать сайт и выбираете для этой цели CMS (или «движок», как еще говорят), то наверняка у вас возникает вопрос: «А чем же Alto лучше других CMS? И годится ли для моих задач?»&lt;br/&gt;
&lt;br/&gt;
Выбирая Alto CMS, вы получаете «из коробки» функционал, который в других движках достигается установкой множества плагинов:" class="term">alto</a>\engine\ar\EntityRecord;

class PluginCompany_ModuleCompany_EntityCompany extends EntityRecord {
    // ...
}</code></pre><br>
<pre class="prettyprint"><code>use <a href="https://altocms.ru/871.html" title="<strong>Alto&nbsp;</strong><br>Если вы собираетесь создавать сайт и выбираете для этой цели CMS (или «движок», как еще говорят), то наверняка у вас возникает вопрос: «А чем же Alto лучше других CMS? И годится ли для моих задач?»&lt;br/&gt;
&lt;br/&gt;
Выбирая Alto CMS, вы получаете «из коробки» функционал, который в других движках достигается установкой множества плагинов:" class="term">alto</a>\engine\ar\ArModule;

class PluginCompany_ModuleCompany extends ArModule {
    // ...
}</code></pre><br>
<pre class="prettyprint"><code>use <a href="https://altocms.ru/871.html" title="<strong>Alto&nbsp;</strong><br>Если вы собираетесь создавать сайт и выбираете для этой цели CMS (или «движок», как еще говорят), то наверняка у вас возникает вопрос: «А чем же Alto лучше других CMS? И годится ли для моих задач?»&lt;br/&gt;
&lt;br/&gt;
Выбирая Alto CMS, вы получаете «из коробки» функционал, который в других движках достигается установкой множества плагинов:" class="term">alto</a>\engine\ar\ArMapper;

class PluginCompany_ModuleCompany_EntityCompany extends ArMapper {
    // ...
}
</code></pre><br>
Как правило, имя сущности проецируется на имя таблицы базы данных. Например, в примере выше для работы с сущностью _EntityCompany будет использоваться таблица «?_company» (подстрока «?_» в начале имени таблицы будет заменена на префикс таблиц по умолчанию, который задается в конфиге). А если <a href="https://altocms.ru/1585.html" title="<strong>Сущность&nbsp;</strong><br>Сущность – это некий набор данных, которые называют «свойствами» (property). Например, сущность «Пользователь» (User) имеет такие свойства, как идентификатор, логин, адрес электронной почты, и т.д." class="term">сущность</a> называется, скажем, _EntityCompanyEmployee, то будет использована таблица «?_company_employee».<br>
<br>
В качестве первичного ключа по умолчанию используется поле таблицы «id».<br>
<br>
Но, при желании, можно задать любую таблицу и любое поле для первичного ключа, это делается в методе инициализации:<br>
<pre class="prettyprint"><code>class PluginCompany_ModuleCompany_EntityEmployee extends EntityRecord {

    public function init() {
        // По умолчанию таблица для этой сущности была бы просто &#34;?_employee&#34;,
        // но мы хотим, чтобы использовалась &#34;?_company_employee&#34;
        $this-&#62;setTable(&#39;?_company_employee&#39;);
        // А первичный ключ будет &#34;company_employee_id&#34;
        $this-&#62;setPrimaryKey(&#39;company_employee_id&#39;);
    }
}</code></pre><br>
Теперь для создания новой сущности и сохранения ее в базе данных нам понадобится минимум кода:<br>
<pre class="prettyprint"><code>$oCompany = E::ModuleCompamy()-&#62;make();
$oCompany-&#62;setName(&#39;Google&#39;);
$oCompany-&#62;setEmail(&#39;info@google.com&#39;);
$oCompany-&#62;setCountryCode(&#39;US&#39;);
$oCompany-&#62;save();</code></pre><br>
А можно и еще короче:<br>
<pre class="prettyprint"><code>E::ModuleCompamy()
  -&#62;make()
  -&#62;setName(&#39;Google&#39;)
  -&#62;setEmail(&#39;info@google.com&#39;)
  -&#62;setCountryCode(&#39;US&#39;)
  -&#62;save();</code></pre><br>
<br>
По-моему, чего делается в этом коде, понятно без всяких дополнительных пояснений. Если же мы хотим создать <a href="https://altocms.ru/1585.html" title="<strong>Сущность&nbsp;</strong><br>Сущность – это некий набор данных, которые называют «свойствами» (property). Например, сущность «Пользователь» (User) имеет такие свойства, как идентификатор, логин, адрес электронной почты, и т.д." class="term">сущность</a>, имя которой отличается от имени модуля, то это надо явно указать:<br>
<pre class="prettyprint"><code>E::ModuleCompamy()
  -&#62;make(&#39;Employee&#39;)
  -&#62;setFirstName(&#39;Jhon&#39;)
  -&#62;setLastName(&#39;Smith&#39;)
  -&#62;save();</code></pre><br>
<h5>Чтение сущностей из базы данных</h5>
Чтобы найти компанию по ее названию используется следующий синтаксис:<br>
<pre class="prettyprint"><code>$oCompany = E::ModuleCompamy()
  -&#62;find()
  -&#62;where([&#39;name&#39; =&#62; &#39;Google&#39;])
  -&#62;one();</code></pre><br>
И никаких тебе SQL-запросов и прочей рутины! А вот так мы найдем все компании у которых указан код страны «US»:<br>
<pre class="prettyprint"><code>$aCompanies = E::ModuleCompamy()
  -&#62;find()
  -&#62;where([&#39;country_code&#39; =&#62; &#39;US&#39;])
  -&#62;all();</code></pre><br>
А вот так можно получить список всех сотрудников, которых зовут Jhon Smith:<br>
<pre class="prettyprint"><code>$aCompanies = E::ModuleCompamy()
  -&#62;find(&#39;Employee&#39;)
  -&#62;where([&#39;first_name&#39; =&#62; &#39;Jhon&#39;, &#39;last_name&#39; =&#62; &#39;Smith&#39;])
  -&#62;all();</code></pre><br>
А вот так можно получить сущности по первичным ключам:<br>
<pre class="prettyprint"><code>// Получить компанию с ID 1231
$oCompany = E::ModuleCompamy()
  -&#62;find()
  -&#62;one(1231);
// или более короткая форма
$oCompany = E::ModuleCompamy()-&#62;findOne(1231);

// Получить список компаний с ID 1231, 3724, 5930
$aCompanies = E::ModuleCompamy()
  -&#62;find()
  -&#62;all([1231, 3724, 5930]);
// или более короткая форма
$aCompanies = E::ModuleCompamy()-&#62;findAll([1231, 3724, 5930]);</code></pre><br>
Значения для задания фильтров в методе where можно задавать явно, как указано выше, а можно и через параметры, например, так:<br>
<pre class="prettyprint"><code>$oQuery-&#62;where([&#39;name&#39; =&#62; &#39;:name&#39;])-&#62;bind(&#39;:name&#39; =&#62; &#39;Google&#39;);
$oQuery-&#62;where([&#39;country_code&#39; =&#62; &#39;:cc&#39;])-&#62;bind(&#39;:name&#39; =&#62; $sCountryCode);</code></pre><br>
Условия where могут задаваться разными способами:<br>
<pre class="prettyprint"><code>// field = :value
$oQuery-&#62;where([&#39;field&#39; =&#62; &#39;:value&#39;]); 

// field = :value (условие задается, как массив в массиве)
$oQuery-&#62;where([[&#39;field&#39;, &#39;=&#39;, &#39;:value&#39;]]); 

// field &#60; :value
$oQuery-&#62;where([[&#39;field&#39;, &#39;&#60;&#39;, &#39;:value&#39;]]); 

// (field1 &#60; :value1) AND (field2 &#60; :value2)
$oQuery-&#62;where([[&#39;field1&#39;, &#39;&#60;&#39;, &#39;:value1&#39;], [&#39;field2&#39;, &#39;!=&#39;, &#39;:value2&#39;]]); 

// (field1 &#60; :value1) OR (field2 &#60; :value2)
$oQuery-&#62;where([[&#39;field1&#39;, &#39;&#60;&#39;, &#39;:value1&#39;])-&#62;orWhere([&#39;field2&#39;, &#39;!=&#39;, &#39;:value2&#39;]]); 

// Зададим сложное вложенное условие:
// (a in (1, 2, 3)) OR (a in (10, 20, 30)) AND (b &#62; 100 OR (c = 1 OR c &#62; 8))
$oQuery
  -&#62;whereBegin()
    -&#62;where([[&#39;a&#39;, &#39;in&#39;, &#39;?a:param1&#39;]])
    -&#62;orWhere([[&#39;a&#39;, &#39;in&#39;, &#39;?a:param2&#39;]])
  -&#62;whereEnd()
  -&#62;andWhereBegin()
    -&#62;where([[&#39;b&#39;, &#39;&#62;&#39;, &#39;?d:param3&#39;]])
	-&#62;orWhereBegin()
	  -&#62;where([&#39;c&#39; =&#62; &#39;:param4&#39;])
	  -&#62;orWhere([[&#39;c&#39;, &#39;&#62;&#39;, &#39;:param5&#39;]])
	-&#62;whereEnd()
  -&#62;whereEnd()
  -&#62;bind([
    &#39;:param1&#39; =&#62; [1, 2, 3],
    &#39;:param2&#39; =&#62; [10, 20, 30],
    &#39;:param3&#39; =&#62; 100,
    &#39;:param4&#39; =&#62; 1,
    &#39;:param5&#39; =&#62; 1,
  ]);</code></pre><br>
Выглядит последнее выражение, на мой взгляд, не очень красиво и удобочитаемостью похвастаться не может, но добавлен такой синтаксис, скорее, для полноты функционала. Впрочем, можно все то же самое сделать и с помощью обычного SQL-выражения:<br>
<pre class="prettyprint"><code>$oQuery-&#62;whereSQL(&#39;(a in (?a:param1)) OR (a in (a:param2)) AND (b &#62; ?d:param3 OR (c = :param4 OR c &#62; :param5))&#39;);  
  -&#62;bind([
    &#39;:param1&#39; =&#62; [1, 2, 3],
    &#39;:param2&#39; =&#62; [10, 20, 30],
    &#39;:param3&#39; =&#62; 100,
    &#39;:param4&#39; =&#62; 1,
    &#39;:param5&#39; =&#62; 1,
  ]);</code></pre><br>
Наконец, можно задать сортировку возвращаемых записей:<br>
<pre class="prettyprint"><code>// обычная (прямая) сортировка
$aCompanies = E::ModuleCompamy()
  -&#62;find()
  -&#62;orderBy(&#39;country_code&#39;)
  -&#62;all();
  
// обратная сортировка
$aCompanies = E::ModuleCompamy()
  -&#62;find()
  -&#62;orderBy(&#39;country_code&#39; =&#62; &#39;desc&#39;)
  -&#62;all();
  
// сортировка по нескольким полям
$aCompanies = E::ModuleCompamy()
  -&#62;find()
  -&#62;orderBy(&#39;country_code&#39; =&#62; &#39;desc&#39;, &#39;update_date&#39;)
  -&#62;all();</code></pre><br>
<br>
<h5><a href="https://altocms.ru/.html" title="<strong>обновление&nbsp;</strong><br>&lt;h5&gt;Подготовка к обновлению&lt;/h5&gt;
&lt;br&gt;
Этот шаг не обязательный, но желательный, если вы его еще не делали — скопировать файлы конфигурации сайта и все файлы конфигурации всех плагинов и скинов в папку /app вашего сайта.&lt;br&gt;
&lt;br&gt;
Если вы что-то меняли в файле &lt;strong&gt;/common/config/config.php&lt;/strong&gt;, то перенесите эти изменения в файл &lt;strong&gt;/app/config/config.local.php&lt;/strong&gt;, и в дальнейшем менять нужно только его. То же касается файлов &lt;strong&gt;menu.php&lt;/strong&gt;, &lt;strong&gt;widgets.php&lt;/strong&gt; и прочих из &lt;strong&gt;/common/config/&lt;/strong&gt; — не нужно их трогать, делайте копию в &lt;strong&gt;/app/config/&lt;/strong&gt; и там уже меняйте, все, что нужно.&lt;br&gt;
&lt;br&gt;
То же касается и конфигурации плагинов и скинов: например, конфигурацию плагина &lt;strong&gt;Topicintro&lt;/strong&gt;, который вы настраиваете для себя, можно держать в файле &lt;strong&gt;/app/plugins/topicintro/config/config.php&lt;/strong&gt;. А измененную под себя конфигурацию скина &lt;strong&gt;Experience&lt;/strong&gt; — в файле &lt;strong&gt;/app/templates/skin/experience/settings/config/config.php&lt;/strong&gt;. И т.д., и т.п.&lt;br&gt;
&lt;br&gt;
Конечно, это не обязательное условие, просто имея копии конфиг-фалов в папке &lt;strong&gt;/app/&lt;/strong&gt; вы исключаете вероятность того, что однажды случайно их затрете во время очередного обновления движка, плагинов или шаблонов.&lt;br&gt;
&lt;br&gt;
&lt;h5&gt;Само обновление&lt;/h5&gt;
&lt;br&gt;
1) Скачиваем свежую версию Alto CMS и распаковываем ее.&lt;br&gt;
2) Копируем папки &lt;strong&gt;/engine/&lt;/strong&gt; и &lt;strong&gt;/common/&lt;/strong&gt; прямо поверх старых&lt;br&gt;
3) Удаляем содержимое папок &lt;strong&gt;/_run/&lt;/strong&gt; и &lt;strong&gt;/_tmp/&lt;/strong&gt;&lt;br&gt;
4) И... это все! А вы ждали чего-то большего? ;)" class="term">Обновление</a> и удаление</h5>
Метод <strong>save()</strong> используется и при записи новой сущности, и при изменении существующей сущности:<br>
<pre class="prettyprint"><code>$oCompany = E::ModuleCompamy()-&#62;findOne(1231);
$oCompany-&#62;setName(&#39;Apple&#39;);
$oCompany-&#62;save();</code></pre><br>
А код для удаления еще проще:<br>
<pre class="prettyprint"><code>E::ModuleCompamy()-&#62;findOne(1231)-&#62;delete();</code></pre><br>
<br>
В следующей части я расскажу о связях и об одной интересной фиче, которую я назвал «связанные ленивые коллекции».]]></description>
					<pubDate>Tue, 05 Apr 2016 14:56:37 +0300</pubDate>
									</item>
							<item>
					<title>Релиз 1.1.19 и новые подробности про версию 1.2</title>
					<guid isPermaLink="true">http://79.174.14.219/t/1537/</guid>
					<link>http://79.174.14.219/1537.html</link>
					<author>vshemarov@gmail.com</author>
					<description><![CDATA[<h5>Вышел релиз движка 1.1.19</h5>
Чего-то особенного он не принес, это, в основном, множественные багфиксы. За исключением одной детали — в качестве парсера текстов по умолчанию теперь используется Qevix. Поэтому если вы хотите обновиться, но использовать Jevix, то это надо указать в конфигурации явно, добавив в <strong>app/config/config.local.php</strong> строку<br>
<pre class="prettyprint"><code>$config[&#39;module&#39;][&#39;text&#39;][&#39;parser&#39;] = &#39;Jevix&#39;;</code></pre><br>
И нужно помнить, что каждый из парсеров использует свой файл конфигурации — jevix.php или qevix.php<br>
<br>
В версии 1.1.19 возможны еще некоторые багфиксы, но какого-то нового функционала в ней уже точно больше не будет. Основные усилия сейчас направлены на версию 1.2<br>
<br>
<h5>И немного про версию 1.2</h5>
На гитхабе создана отдельная ветка для 1.2: <a href="https://github.com/altocms/altocms/tree/1.2.x" rel="nofollow">https://github.com/altocms/altocms/tree/1.2.x</a>, кому интересно, могут за ней наблюдать.<br>
<br>
О планах относительно этой версии я уже писал: <a href="https://altocms.ru/1477.html">https://altocms.ru/1477.html</a><br>
<br>
Но могу добавить, что в ней будут добавлены еще, как минимум, две фичи: это <strong>ActiveRecord</strong> и <strong>планировщик</strong>.<br>
<br>
Да, уже в этой версии Альто будет реализация ORM в виде <strong>ActiveRecord</strong> в стилистике yii. Т.е. можно будет написать так:<br>
<pre class="prettyprint"><code>$oUser = E::ModuleUser()-&#62;find()-&#62;one(11);</code></pre>И будет получен юзер с ID равным 11. Или так:<br>
<pre class="prettyprint"><code>$aUsers = E::ModuleUser()
    -&#62;find(&#39;User&#39;)
    -&#62;where([&#39;user_skill&#39; =&#62; &#39;?:skill&#39;])
    -&#62;where(&#39;user_profile_sex&#39;, &#39;&#62;&#39;, &#39;?:sex&#39;)
    -&#62;whereSql(&#39;substr(user_mail, 8, 5) = &#34;@test&#34;&#39;)
    -&#62;bind([&#39;:skill&#39; =&#62; 0, &#39;:sex&#39; =&#62; &#39;other&#39;])
    -&#62;limit(10)
    -&#62;all()
;</code></pre>По-моему, код вполне прозрачен и не нужно объяснять, какие данные он получает.<br>
<br>
Разумеется, будут поддерживаться и связи: «один-к-одному», «один-ко-многим» и связь через промежуточную таблицу.<br>
<br>
Все это позволит значительно ускорить разработку и сделать работу с различными базами данных (MySQL/PostgreSQL) более простой и прозрачной.<br>
<br>
Еще одна фича, которая будет реализована в 1.2 — это <strong>планировщик</strong>. Можно будет программно задавать отложенные действия (отправку почты, публикация опиков и т.д.) и будет единый механизм для выполнения этих действий. Все, что потребуется будет сделать — это настроить системный крон, чтоб он периодически «дергал» движок в нужном месте.<br>
<br>
И еще одна новость, даже не знаю, хорошая или плохая: это будет, пожалуй, последняя версия, где будет «в коробке» плагин совместимости. Отличий от старого доброго LS становится все больше и обеспечивать совместимость становится все сложнее. Поэтому, скорее всего, в следующей версии мы уже откажемся от этой политики.<br>
<br>
<strong>UPD</strong> И совсем забыл отметить: для версии 1.2 требуется <strong>PHP не ниже 5.4</strong>. Долго колебался насчет этого, но, в конце концов, решил — пора!]]></description>
					<pubDate>Sun, 31 Jan 2016 11:04:15 +0300</pubDate>
									</item>
					</channel>
	</rss>
