<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss version="2.0">
	<channel>
		<title>Записки</title>
		<link>http://filimonov.com.ua/</link>
		<description>Записки</description>
		<pubDate>Tue, 20 Mar 2012 17:10:51 +0400</pubDate>
		<language>en-ru</language>
		<generator>MaxSite CMS (http://max-3000.com/)</generator>
		<copyright>Copyright 2012, http://filimonov.com.ua/</copyright>
				<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/filimonov" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="filimonov" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
			<title><![CDATA[Перелинковка сообщений форума Dialog ответами и цитатами.]]></title>
			<link>http://filimonov.com.ua/page/perelinkovka</link>
			<guid>http://filimonov.com.ua/page/perelinkovka</guid>
			<pubDate>Tue, 20 Mar 2012 17:10:51 +0400</pubDate>
			<category><![CDATA[MaxSite CMS плагины, MaxSite CMS шаблоны]]></category>
			<description><![CDATA[<p>Во всех форумах можно цитировать в своих сообщениях сообщения других пользователей. </p>
<p>В некоторых форумах, на новых движках, осуществляется связь цитаты с сообщением, откуда она взята.</p>
<p>Постарался максимально развить этот функционал в своем скрипте форума для MaxSite CMS.</p>
<a id="cut"></a>
<h2>Перелинковка сообщений цитированиями.</h2>
<p>При нажатии кнопки <strong><em>"цитировать выделенное"</em></strong>, выделенный в сообщении текст, будет добавлен в новое сообщение. Если не выделено ничего, то будет добавлен весь текст.</p>
<p>Цитата будет добавлена не просто в тегах blockquote, а этот тег будет иметь id для связи с сообщением, откуда цитата взята.</p>
Это позволит затем, при выводе сообщений, цитаты оформить с заголовком, содержащим ссылку на цитируемое сообщение.
<div class="gallery"><a href="http://filimonov.com.ua/uploads/post_picture/perelinkovka.jpg"><img src="http://filimonov.com.ua/uploads/post_picture/mini/perelinkovka.jpg" alt="Перелинковка сообщений форума цитатами" title="Перелинковка сообщений форума цитатами"></a></div>
<p>Заголовок цитаты содержит информацию об авторе цитируемого сообщения, и о том, сколько времени назад, от текущего сообщения, сделано цитируемое сообщение.</p>
<p>Кроме того, в конце заголовка будет стоять стрелочка вверх или назад.</p>
<p>Если цитируемое сообщение находится на этой же странице в рамках текущей пагинации, то будет стрелочка вверх, а ссылка будет на якорь.</p>
<p>Если цитируемое сообщение на предыдущей странице пагинации, то стрелочка будет назад, а ссылка на сообщение в его странице.</p>
<p>Формат заголовка можно задать в опциях (об этом позже).</p>
<p>Кроме того, при сохранении сообщения, оно будет обработано на предмет цитирования с указанием сообщения-источника цитаты. При обнаружении элемента-цитаты с указанием id цитируемого сообщения, будет добавлена соответствующая запись в таблицу Dperelinks.</p>
<p>Запись таблицы Dperelinksсодержит такие поля:</p>
<p><strong>perelinks_parent_id</strong> - id цитируемого сообщния;</p>
<p><strong>perelinks_child_id</strong> - id сообщения, в котором цитируется;</p>
<p><strong>perelinks_date</strong> - дата цитирования.</p>
<p>Это позволит при выводе сообщения указать что его цитировали и сформировать соответствующие ссылки на сообщения, в которых цитировали.</p>
<p>Внизу сообщения будет информация, что сообщение цитировали и сколько раз. Можно развернуть список сообщений, где использовались цитаты (см. скриншот выше).</p>
<p>Вил стрелочки так же будет зависеть от того: на этой или следующих странице пагинации находится сообщение, в котором цитата.</p>
<h2>Ответы на сообщения.</h2>
<p>Кроме кнопки "Цитировать выделенное", можно просто ответить на сообщение, нажав кнопку "Ответить". В этом случае, при добавлении сообщения, в поле <em><strong>comment_parent_id</strong></em> будет добавлен номер сообщения, ответом на которое является данное сообщение.</p>
<p>Тогда, при выводе сообщения, если имеется родительское сообщение, будет выведен соответствующий заголовок и кнопка, при нажатии на которую, сообщение-родитель будет развернуто или свернуто.</p>
<p>Можно и перейти к сообщению-родителю, нажав на ссылку в заголовке. В зависимости от того, на этой или нет странице находится сообщение - ссылка будет якорем или ссылкой на страницу.</p>
<p>Но это еще не все.</p>
<p>Если на сообщение были даны ответы, то при его выводе, после контента, будет добавлена кнопка "Показать ответы (N)", где N - кол-во ответов.</p>
<p>При нажатии кнопки ответы можно развернуть/скрыть.</p>
<div class="gallery"><a href="http://filimonov.com.ua/uploads/post_picture/perelinkovka2.jpg"><img src="http://filimonov.com.ua/uploads/post_picture/mini/perelinkovka2.jpg" alt="Перелинковка сообщений форума цитатами" title="Перелинковка сообщений форума ответами"></a></div>
<p>Перед каждым ответом, в развернутом под кнопкой блоке ответов, будет заголовок, подобный предыдущим случаям.</p>
<h2>Задание формата заголовков перелинковки.</h2>
<p>Заголовок формируется функцией <strong>dialog_perelink_title</strong>, которой можно передать формат и массив с видом стрелочек, по умолчанию: "v","^","<",">".</p>
<p>Имеем 4 варианта заголовков перелинковки, формат которых задается в соответствующих опциях.</p>
<p><strong>perelink_title_mask</strong> - формат информации в блоке "Коммент цитировали" о случаях, когда сообщение цитировали.</p>
<p>По умолчанию: </p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;&lt;p class="comment_perelink"&gt;##AUTOR#<span class="php-comment"># </span>в сообщении &lt;a href="##COMMENT_URL##" title ="Перейти к сообщению"&gt;##TIMEAGO#<span class="php-comment"># </span>##ARROW##&lt;/a&gt;</li></ol></div>
</div>
<p><strong>quotes_title_mask</strong> - формат заголовка цитаты.</p>
<p>По умолчанию:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;&lt;p class="comment_perelink"&gt;##AUTOR#<span class="php-comment"># </span>сказал(а) (&lt;a href="##COMMENT_URL##" title ="Перейти к сообщению"&gt;##TIMEAGO#<span class="php-comment"># </span>##ARROW##&lt;/a&gt;) :</li></ol></div>
</div>
<p><strong>question_title_mask</strong> - формат заголовка родительского сообщения.</p>
<p>По умолчанию:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;&lt;p class="comment_perelink"&gt;##AUTOR#<span class="php-comment"># </span>сказал(а) (&lt;a href="##COMMENT_URL##" title ="Перейти к сообщению"&gt;##TIMEAGO#<span class="php-comment"># </span>##ARROW##&lt;/a&gt;)</li></ol></div>
</div>
<p><strong>answer_title_mask</strong> - формат заголовка ответа.</p>
<p>По умолчанию:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;&lt;p class="comment_perelink"&gt;##AUTOR#<span class="php-comment"># </span>ответил(а) (&lt;a href="##COMMENT_URL##" title ="Перейти к сообщению"&gt;##TIMEAGO#<span class="php-comment"># </span>##ARROW##&lt;/a&gt;)</li></ol></div>
</div>
<p>Где можно применить:</p>
<strong>##AUTOR##</strong> - Ник-ссылка на профайл автора сообщения.
<strong>##COMMENT_URL##</strong> - ссылка на якорь/страницу сообщения.
<strong>##TIMEAGO##</strong> - время между перелинкуемыми сообщениями, формируется функцией <strong>_dialog_time_ago()</strong>.
<strong>##ARROW##</strong> - стрелочка, вид которой зависит от располодения сообщений относительно друг друга.
<strong>##DATE##</strong> - дата сообщения
<p>Оповещение пользователей о цитировании или ответе на их сообщение.</p>
<p>Если сообщение пользователя цитируют ил на него отвечают, то пользователь-автор сообщения будет (если не запретил отсылать себе инфо-сообщения с форума) получать письмо с информацией о этом событии: текст сообщения - ответа или цитаты и текст своего сообщения, которое породило ответ или цитату.</p>
<p>Функционирование.</p>
<p>Весь этот функционал требует большого количества запросов к БД при выводе дискуссии, что решает кеширование.</p>
<p>Перелинковки вызывает функция d<strong>ialog_get_comments</strong>, которая, коме прочего, подготавливает информацию о всех перелинковках к выводу.</p>
<p>Сами перелинковки же осуществляют вспомогательные функции, что делает не сложным, при надобности, отключить функционал перелинковок.
Функция <strong>dialog_get_comments</strong> кеширует свои результаты.</p><a href="http://filimonov.com.ua/page/perelinkovka#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Плагин Личный Кабинет + События сайта для MaxSite CMS.]]></title>
			<link>http://filimonov.com.ua/page/maxsite-profile12</link>
			<guid>http://filimonov.com.ua/page/maxsite-profile12</guid>
			<pubDate>Wed, 22 Feb 2012 17:43:52 +0400</pubDate>
			<category><![CDATA[MaxSite CMS плагины, Личный кабинет]]></category>
			<description><![CDATA[<p>Новая версия плагина содержит нововведения:</p>
<p>Настройка главного меню публичных страниц пользователей.</p>
<p>Страница всех событий пользователя и подстраницы конкретных событий.</p>
<p>Страницы всех событий сайта и подтраницы конкретного вида событий всех пользователей.</p>
<div class="stb-download_box stb_box" >Плагин: <a title="profile1_2.zip" href="http://filimonov.com.ua/files/profile1_2.zip">profile1_2.zip</a></div>
<a id="cut"></a>
<h2>Главное меню публичных страниц.</h2>
<p>В предыдущей версии главная страница, доступная по адресу<strong> siteurl/profiles/</strong>, содержала список пользователей. Все остальные страницы уже касались конкретных пользователей.</p>
<p>Но, что если нужно еще добавить страницы, не касающиеся конкретных пользователей, а содержащих совокупную информацию.</p>
<p>Для этого добавил опцию <strong>"Пункты меню главных страниц всех профайлов"</strong>. В частности, при помощи этой опции добавил при помощи строчки <strong>forum | Пользователи форума</strong> страницу <a title="Пользователи форума" href="http://filimonov.com.ua/profiles/forum">siteurl/profiles/forum</a> и, строчкой <strong>all | Все действия</strong> <a title="Все события" href="http://filimonov.com.ua/profiles/all">siteurl/profiles/all</a> - все события сайта.</p>
<h2>События сайта</h2>
<p>Реализовал страницу всех событий сайта: <a title="Все события" href="http://filimonov.com.ua/profiles/all">filimonov.com.ua/profiles/all</a>/.</p>
<p>Эта страница является совокупной для всех событий всех пользователей. События в ленту событий могут добавляться другими плагинами. Плагин profile добавляет только события вида "comments".</p>
<p>События выводятся без пагинации, но получаются AJAXом порциями по n штук (как в Твиттере).</p>
<p>Кроме того, имеются подстраницы, содержащие все события сайта одного вида.</p>
<h2>События пользователя</h2>
<p>По аналогии с <strong>Событиями сайта</strong> работают <strong>события пользователя</strong>, доступные по адресу <a title="Все действия" href="http://filimonov.com.ua/profiles/7/all">filimonov.com.ua/profiles/7/all</a>.</p>
<p>Для того, чтобы такая страница появилась в меню публичных страниц пользователя, нужно прописать в опции <strong>Пункты меню Публичных Страниц Профиля</strong> строчку <strong>all | Все действия</strong>.</p>
<p>Также имеются подстраницы.</p>
<h2>Каким образом плагины кидают свои события в ленты событий?</h2>
<p>Напишу в следующей статье.</p>
<a href="http://filimonov.com.ua/page/maxsite-profile12#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Плагин Личный Кабинет + Публичные Страницы комюзера для MaxSite CMS.]]></title>
			<link>http://filimonov.com.ua/page/maxsite-profile11</link>
			<guid>http://filimonov.com.ua/page/maxsite-profile11</guid>
			<pubDate>Thu, 16 Feb 2012 13:59:03 +0400</pubDate>
			<category><![CDATA[MaxSite CMS плагины, Личный кабинет]]></category>
			<description><![CDATA[<p>Предыдущая версия плагина создавала Личный кабинет пользователя - страницы, на которых пользователь мог редактировать свою информацию.</p>
<p>Теперь логическое продолжение - новая версия плагина, формирующая публичные страницы пользователя. Сам плагин profiles формирует две страницы: Информация о пользователе и комментарии пользователя. Остальные страницы предполагаются к добавлению другими плагинами.</p>
<div class="stb-download_box stb_box" >Плагин: <a title="profile1_1.zip" href="http://filimonov.com.ua/files/profile1_1.zip">profile1_1.zip</a></div>
<a id="cut"></a>
<h3>Функционирование можете наблюдать здесь: </h3>
<p><a title="Пользователи" href="http://filimonov.com.ua/profiles">http://filimonov.com.ua/profiles</a>.</p>
<h3>Особенности использования.</h3>
<p>Задание публичных страниц такое же, как и страниц личного кабинета.</p>
<p>Кроме того, в поле "Плагины подключения элементов" админки указываем список плагинов, которые могут добавлять сводную информацию о действии пользователя в своих рамках.</p>
<p>Для того, чтобы плагин добавил блок с информацией, в его корневой папке должен лежать файл с именем <strong>profile_block.php</strong>, который добавит в переменную <strong>$profiles_blocks</strong> нужную информацию на основе $comusers_id.</p>
<p>Результирующая переменная <strong>$profiles_blocks</strong> со всеми блоками кешируется.</p>
<h2>Что нужно сделать</h2>
<p>Сейчас делаю ленту событий сайта вообще, которая должна быть доступна по адресу <strong>siteurl/profiles/all</strong>. Смысл в том, что плагины могут кидать в нее свои события.</p>
<p>И, все события, только для комюзера, которые доступны по <strong>siteurl/profile/8/all</strong>.</p>
<p>Почти социальная сеть.</p><a href="http://filimonov.com.ua/page/maxsite-profile11#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Плагин Личный Кабинет комюзера для MaxSite CMS.]]></title>
			<link>http://filimonov.com.ua/page/maxsite-profile</link>
			<guid>http://filimonov.com.ua/page/maxsite-profile</guid>
			<pubDate>Sun, 12 Feb 2012 17:19:33 +0400</pubDate>
			<category><![CDATA[MaxSite CMS плагины, Личный кабинет]]></category>
			<description><![CDATA[<p>В MaxSite CMS имеется страница, где комюзер может отредактировать свои персональные данные.</p>
<p>Вид этой страницы: siteurl/users/user_id/edit.</p>
<p>Если на сайте активность посетителей (комюзерам) предусматривается только в виде комментирования, этого может и достаточно.</p>
<p>А если функционал расширяется, например при помощи плагинов, и требуется комюзерам еще что-то делать?</p>
<p>Понятно, страницы для действия комюзеров может создавать плагин. </p>
<p>Но, хотелось бы видеть все страницы для действия комюзеров однообразно.</p>
<p>А то получается, что персональные настройки и настройки оповещений мы видим в одном месте, настройки одного плагина - по другому, а еще один плагин может сформировать еще  как-то.</p>
<p>Для комюзера же ваш сайт целостен (а не состоит из шаблонов и плагинов), и он ожидает что вся информация, которую он может редактировать, сосредоточена в одном месте.</p>
<p>В общем, вступление и так слишком длинное (...Я классицизму отдал честь...): теперь коротко и по делу.</p>
<div class="stb-download_box stb_box" >Вот сам плагин: <a title="profile1_0.zip" href="http://filimonov.com.ua/files/profile1_0.zip">profile1_0.zip</a></div>
<a id="cut"></a>
<p>Плагин представляет собой Личный Кабинет, доступный по настраиваемому адресу siteurl/profile, и состоящий из страниц:</p>
<ul><li><strong>siteurl/profile/</strong> - оснвные настройка;</li>
<li><strong>siteurl/profile/avata</strong>r - настройка аватара с возможностью загрузки;</li>
<li><strong>siteurl/profile/commenting</strong> - список страниц, в которых комюзер оставил комментарии.</li></ul>
<p>Плагины могут добавлять страницы в личный кабинет, но не автоматически.</p>
<p>Плагин (добавляющий страницы в личный кабинет) должен взять хук 404 и, если <strong>mso_segment(1) == 'profile'</strong>, проверить: есть ли страницы для вывода в личном кабинете, заданные <strong>mso_segment(1)</strong>.</p>
<p>Если страницы к выводу нет - вернуть<strong> return $args;</strong>.</p>
<p>Для того, чтобы меню Личного Кабинета работало синхронно, в настройках есть поле для задания в каждой строчке страницы в виде:</p>
<p><strong>slug | title</strong></p>
<p>Как пример добавления в личный кабинет страниц другим плагином - плагин форума диалог.</p>
<h3>Функционирование можете наблюдать здесь: </h3>
<p><a title="Личный кабинет" href="http://filimonov.com.ua/profile">http://filimonov.com.ua/profile</a>.</p>
<H2>Страница редактирования и загрузки аватара комюзером.</H2>
<p>Если ваш сайт по теме IT - это не очень актуально, поскольку все посетители умеют пользоваться сервисом gravatar, но для далеких от этого пользователей, установка аватара должна выглядить как в социальных сетях.</p>
<p>То-есть, в виде кнопки "Загрузить".</p>
<p>Что и реализовано на этой странице: <a title="Личный кабинет >> Аватар" href="http://filimonov.com.ua/profile/avatar">http://filimonov.com.ua/profile/avatar</a></p>
<H2>Форма регистрации на сайте комюзеров.</H2>
<p>О том, как добавить к себе на сайт возможность регистрироваться без комментирования? было рассказано в статье: <a title="Страница-форма регистрации для MaxSite CMS " href="http://filimonov.com.ua/page/maxsite-register">Страница-форма регистрации для MaxSite CMS </a>.</p>
<p>Файл формы регистрации теперь имеется в этом плагине и его не нужно размещать в шаблоне.</p><a href="http://filimonov.com.ua/page/maxsite-profile#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Загрузка файлов комюзерами для MaxSite CMS]]></title>
			<link>http://filimonov.com.ua/page/comusers_uploader</link>
			<guid>http://filimonov.com.ua/page/comusers_uploader</guid>
			<pubDate>Thu, 02 Feb 2012 23:33:05 +0400</pubDate>
			<category><![CDATA[MaxSite CMS плагины, Разные плагины]]></category>
			<description><![CDATA[<p>Для <a title="Форум Садовника" href="http://filsadovnik.ru/forum">Форум Садовника</a> мне понадобилось, чтобы пользователи могли загружать свои фото и вставлять их в сообщения.
Какой же форум о цветоводстве, в котором нельзя публиковать фотографии.</p>
<p>Пользователи в MaxSite CMS являются Комюзерами и не имеют доступ к админке сайта в целях безопасности.</p>
<p>И, понятно, не должны иметь доступ к каталогу /uploads/.</p>
<a id="cut"></a>
<h2>Решил сделать загрузку фотографий комюзерами таким путем.</h2>
<p>В каталоге загрузок uploads/ делаем директорий /userfiles, и в этом директории каждый комюзер будет иметь каталог с именем =comusers_id, в который будуn загружаться добавленные им фотографии.</p>
<p>Решение сделал на базе <a title="Плагин Файловый менеджер" href="http://forum.max-3000.com/viewtopic.php?f=6&t=3054&start=60">файлового менеджера </a>.</p>
<p>Добавил в этот плагин функцию <strong>file_manager_comuser()</strong>, которая возвращает редактор в переменной. Таким образом, этот редактор можно вывести куда угодно.</p>
<p>Редактор позволяет открывать блок, где отображать миниатюры фоток, которые находятся в каталоге залогиненного комюзера.</p>
<p>При клике на миниатюру она будет добавлена в поле редактора с <strong>id="comments_content"</strong>.</p>
<p>Ниже можно открыть загрузчик для загрузки новых файлов.</p>
<p>Все функционирует без перезагрузки страницы.</p>
<p>Пример на этом форуме: <a title="Форум Садовника" href="http://filsadovnik.ru/forum">Форум Садовника</a></p>
<div class="stb-download_box stb_box" >Скачать: <a title="file_manager000.zip" href="http://filsadovnik.ru/files/file_manager000.zip">file_manager000.zip</a></div>
<h2>Структура загрузчика файлов.</h2>
<p>Часть плагина file_manager в архиве, которая отвечает за блок загрузки файлов комюзерами находится в файлах (<em>сам скрипт загрузчика берется тот же что и в плагине из директорий плагина</em>):</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;manager-comuser.php</li>
<li>&nbsp;comuser-require-maxsite.php</li>
<li class="odd">&nbsp;comuser-require-maxsite.php</li>
<li>&nbsp;comuser-fm.js</li>
<li class="odd">&nbsp;comuser-style.css</li>
<li>&nbsp;comuser-ajax.php</li></ol></div>
</div>
<p>В индексном файле плагина за вывод загрузчика после поля редактирования комментария отвечает строчка</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> mso_hook_add( &#039;comments_content_end&#039;, &#039;file_manager_comments&#039;);</li></ol></div>
</div>
<div class="stb-info_box stb_box" >Строчка закомментированна в целях безопасности - раскомментируйте</div>
<p>Ну и функция хука:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<b>function</b> file_manager_comments($args = <b>array</b>()) </li>
<li>&nbsp;{</li>
<li class="odd">&nbsp;  <span class="php-comment">//</span>загрузка изображений пользователями</li>
<li>&nbsp;  require(getinfo(&#039;plugins_dir&#039;) . &#039;file_manager/manager-comuser.php&#039;);</li>
<li class="odd">&nbsp;  <b>echo</b> file_manager_comuser();</li>
<li>&nbsp;  <b>return</b> $args;</li>
<li class="odd">&nbsp;}</li></ol></div>
</div>
Лучше, конечно, сделать чтобы по хуку подключалась file_manager_comuser(), которая бы сразу выводила echo() без создания переменной $out.
<h2>Надо еще сделать.</h2>
<p>Файлы комюзера никак не структурируются, но для этих целей уже предусмотрено окошко - типа дерева каталогов.</p>
<p>Пользователь будет иметь возможность создавать разделы/альбомы. Массив всех созданных разделов будет хранится в файле типа vso_descriptions.dat в виде cat_id=>cat_title. Информация о привязке файла к альбому, наверное, будет хранится в файле _cat_id.dat.</p><a href="http://filimonov.com.ua/page/comusers_uploader#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Организуем циклы статей на MaxSite CMS]]></title>
			<link>http://filimonov.com.ua/page/cikly-statej-maxsite-cms</link>
			<guid>http://filimonov.com.ua/page/cikly-statej-maxsite-cms</guid>
			<pubDate>Tue, 10 Jan 2012 19:10:21 +0400</pubDate>
			<category><![CDATA[MaxSite CMS практика]]></category>
			<description><![CDATA[<p>Циклы статей – один из способов дополнительной навигации для сайта. Статьи могут быть из разных рубрик, иметь разные метки, да и вообще – быть разного типа. И эти разношерстные статьи можно объединить в цикл статей.</p>
<p>Цикл статей подразумевает, что в каждой статье из цикла будет ссылка на предыдущую и следующую (по времени публикации) статьи.</p>
<p>Кроме того, будет заголовок цикла и ссылка на содержание цикла статей.</p>
<p>На мой взгляд, идеально для объединения статей в цикл будет связь дочерние-родительская страницы.</p>
<a id="cut"></a>
<p>Все статьи цикла будут объединяться общей родительской статьей. Родительская статья будет заголовком цикла, и содержать аннотацию цикла и содержание.</p>
<p>Рекомендую придумать свой тип страниц для статей – заголовков циклов (например, navi).</p>
<h2>Исключение статей с отложенной публикацией.</h2>
<p>Для получения статей рекомендуется использовате функцию <a title="mso_get_pages и типы данных в MaxSite CMS: что это и как эти штуки связанны" href="http://filimonov.com.ua/page/maxsite-mso_get_pages">mso_get_pages</a>.</p>
<p>Но здесь будем получать статьи из БД своими SQL запросами.</p>
<p>В этом случае нам необходимо самостоятельно позаботиться о том, что лежит на плечах mso_get_pages. </p>
<p>Например, исключить статьи с отложенной публикацией. Кто не знает - это статьи с датами публикации большими, чем текущая дата.</p>
<p>Рассмотрим получение ID отложенных статей (если отложенная публикация не используется – этот код можно удалить).</p>
<h3>Разберемся со временем.</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> смещение времени</li>
<li>&nbsp;$time_zone = getinfo(&#039;time_zone&#039;);</li>
<li class="odd">&nbsp;<b>if</b> ($time_zone &lt; 10 and $time_zone &gt; 0) $time_zone = &#039;0&#039; . $time_zone;</li>
<li>&nbsp;<b>else</b><b>if</b> ($time_zone &gt; -10 and $time_zone &lt; 0) </li>
<li class="odd">&nbsp;{ </li>
<li>&nbsp;   $time_zone = &#039;0&#039; . $time_zone; </li>
<li class="odd">&nbsp;   $time_zone = <b>str_replace</b>(&#039;0-&#039;, &#039;-0&#039;, $time_zone); </li>
<li>&nbsp;}</li>
<li class="odd">&nbsp;<b>else</b> $time_zone = &#039;00.00&#039;;</li>
<li>&nbsp;$time_zone = <b>str_replace</b>(&#039;.&#039;, &#039;:&#039;, $time_zone);</li></ol></div>
</div>
<h3>Получим массив ID отложенных статей.</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span>получаем неопубликованные записи</li>
<li>&nbsp;$CI = & get_instance();</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;select(&#039;SQL_BUFFER_RESULT `page_id`&#039;, <b>false</b>);</li>
<li>&nbsp;<b>if</b> ($page_id_date_now) $CI-&gt;db-&gt;where_not_in(&#039;page_id&#039;, $page_id_date_now);</li>
<li class="odd">&nbsp;$query = $CI-&gt;db-&gt;get(&#039;page&#039;);</li>
<li>&nbsp;<b>if</b> ($query and $query-&gt;num_rows() &gt; 0) </li>
<li class="odd">&nbsp;{</li>
<li>&nbsp;  $result = $query-&gt;result_<b>array</b>();</li>
<li class="odd">&nbsp;  $page_id_date_now = <b>array</b>();</li>
<li>&nbsp;  <b>foreach</b> ($result <b>as </b>$key=&gt;$val)</li>
<li class="odd">&nbsp;  {</li>
<li>&nbsp;      $page_id_date_now&#91;&#93; = $val&#91;&#039;page_id&#039;&#93;;</li>
<li class="odd">&nbsp;  }</li>
<li>&nbsp;}</li>
<li class="odd">&nbsp;<b>else</b> $page_id_date_now = <b>false</b>; <span class="php-comment">//</span> нет отложенных записей</li></ol></div>
</div>
<h2>Получение ссылок на статьи цикла: родительскую, предыдущую и последующую.</h2>
<h3>Получим родительскую страницу и сформируем на нее ссылку.</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;$CI-&gt;db-&gt;select(&#039;page_id, page_title, page_slug&#039;);</li>
<li>&nbsp;$CI-&gt;db-&gt;where(&#039;page_id&#039;, $page_id_parent);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;where(&#039;page_status&#039;, &#039;publish&#039;);</li>
<li>&nbsp;<b>if</b> ($page_id_date_now) $CI-&gt;db-&gt;where_not_in(&#039;page_id&#039;, $page_id_date_now);</li>
<li class="odd">&nbsp;$query = $CI-&gt;db-&gt;get(&#039;page&#039;);</li>
<li>&nbsp;$result = $query-&gt;result_<b>array</b>(); <span class="php-comment">//</span> здесь родительская страница</li>
<li class="odd">&nbsp;</li>
<li>&nbsp;<b>if</b> ($result)</li>
<li class="odd">&nbsp;    <b>foreach</b> ($result <b>as </b>$key=&gt;$row)</li>
<li>&nbsp;    {</li>
<li class="odd">&nbsp;        $url = getinfo(&#039;siteurl&#039;) . &#039;page/&#039; . $row&#91;&#039;page_slug&#039;&#93;;</li>
<li>&nbsp;           $parent_page_link = &#039;&lt;a href="&#039; . $url . &#039;" title="&#039; . mso_strip($row&#91;&#039;page_title&#039;&#93;) . &#039;"&gt;&#039; . mso_strip($row&#91;&#039;page_title&#039;&#93;) . &#039;&lt;/a&gt;&#039;;        </li>
<li class="odd">&nbsp;    }</li></ol></div>
</div>
<h3>Получим все страницы цикла (сестры текущей).</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> получим все страницы цикла</li>
<li>&nbsp;$CI-&gt;db-&gt;select(&#039;page_id, page_id_parent, page_title, page_slug&#039;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;where(&#039;page_id_parent&#039;, $pages&#91;0&#93;&#91;&#039;page_id_parent&#039;&#93;);</li>
<li>&nbsp;$CI-&gt;db-&gt;where(&#039;page_status&#039;, &#039;publish&#039;);</li>
<li class="odd">&nbsp;<b>if</b> ($page_id_date_now) $CI-&gt;db-&gt;where_not_in(&#039;page_id&#039;, $page_id_date_now); <span class="php-comment">//</span> исключим отложенные</li>
<li>&nbsp;$CI-&gt;db-&gt;order_by(&#039;page_date_publish&#039;);</li>
<li class="odd">&nbsp;$query = $CI-&gt;db-&gt;get(&#039;page&#039;);</li>
<li>&nbsp;$result = $query-&gt;result_<b>array</b>(); <span class="php-comment">//</span> здесь все дочерние страницы</li></ol></div>
</div>
<h3>Выберем из статей цикла предыдущую и следующую для текущей.</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<b>if</b> ($result) <span class="php-comment">//</span> имеются страницы - сестры</li>
<li>&nbsp;{</li>
<li class="odd">&nbsp;    <span class="php-comment">//</span> ищем текущую</li>
<li>&nbsp;    reset($result);</li>
<li class="odd">&nbsp;    <b>while</b> (each($result))</li>
<li>&nbsp;    {</li>
<li class="odd">&nbsp;       $key = key($result);</li>
<li>&nbsp;       <b>if</b> ($page_id == $result&#91;$key&#93;&#91;&#039;page_id&#039;&#93;) break;</li>
<li class="odd">&nbsp;     } </li>
<li>&nbsp;        </li>
<li class="odd">&nbsp;     <span class="php-comment">//</span> берем  предыдущую</li>
<li>&nbsp;     <b>if</b> ( ($key-1)&gt;=0 ) <span class="php-comment">//</span>  если есть предыдущая</li>
<li class="odd">&nbsp;     {</li>
<li>&nbsp;    $url = getinfo(&#039;siteurl&#039;) . &#039;page/&#039; . $result&#91;$key-1&#93;&#91;&#039;page_slug&#039;&#93;;</li>
<li class="odd">&nbsp;    $prev_page_link = &#039;&lt;a href="&#039; . $url . &#039;" title="&#039; . mso_strip($result&#91;$key-1&#93;&#91;&#039;page_title&#039;&#93;) . &#039;"&gt;&#039; . mso_strip($result&#91;$key-1&#93;&#91;&#039;page_title&#039;&#93;) . &#039;&lt;/a&gt;&#039;;        </li>
<li>&nbsp;     }</li>
<li class="odd">&nbsp;    </li>
<li>&nbsp;<span class="php-comment">//</span> берем следующую</li>
<li class="odd">&nbsp;     <b>if</b> (<b>isset</b>($result&#91;$key+1&#93;))</li>
<li>&nbsp;     {</li>
<li class="odd">&nbsp;       $url = getinfo(&#039;siteurl&#039;) . &#039;page/&#039; . $result&#91;$key+1&#93;&#91;&#039;page_slug&#039;&#93;;</li>
<li>&nbsp;       $next_page_link = &#039;&lt;a href="&#039; . $url . &#039;" title="&#039; . mso_strip($result&#91;$key+1&#93;&#91;&#039;page_title&#039;&#93;) . &#039;"&gt;&#039; . mso_strip($result&#91;$key+1&#93;&#91;&#039;page_title&#039;&#93;) . &#039;&lt;/a&gt;&#039;;        </li>
<li class="odd">&nbsp;     }    </li>
<li>&nbsp;   } <span class="php-comment">//</span> <b>if</b> ($result)</li>
<li class="odd">&nbsp; } <span class="php-comment">//</span> <b>if</b> ($page_id_parent)</li></ol></div>
</div>
<h3>Выведем полученное.</h3>
<p>Можно организовать примерно такой вывод:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;$out = &#039;&#039;;</li>
<li>&nbsp;<b>if</b> ($parent_page_link) $out .= &#039;Статья из цикла статей: "&#039; . $parent_page_link . &#039;".&#039; . &#039;&lt;/br&gt;&#039;;</li>
<li class="odd">&nbsp;<b>if</b> ($prev_page_link) $out .= &#039;Предыдущая: &#039; . $prev_page_link . &#039;&lt;/br&gt;&#039;;</li>
<li>&nbsp;<b>if</b> ($next_page_link) $out .= &#039;Следующая: &#039; . $next_page_link . &#039;&lt;/br&gt;&#039;;</li>
<li class="odd">&nbsp;<b>echo</b> $out;</li></ol></div>
</div>
<p>Или такой:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> выводим теперь полученное</li>
<li>&nbsp;$out = &#039;&lt;div class="navi"&gt;&#039;;</li>
<li class="odd">&nbsp;$out .= $parent_page_link;</li>
<li>&nbsp;$out .= &#039;&lt;table&gt;&lt;tr&gt;&#039;;</li>
<li class="odd">&nbsp;$out .= &#039;&lt;td width="50%"&gt;&lt;span class="left"&gt;&lt;&lt;&lt;/span&gt;&#039; . $prev_page_link . &#039;&lt;/td&gt;&#039;;</li>
<li>&nbsp;$out .= &#039;&lt;td width="50%"&gt;&#039; . $next_page_link . &#039;&lt;span class="right"&gt;&gt;&gt;&lt;/span&gt;&lt;/td&gt;&#039;;</li>
<li class="odd">&nbsp;$out .= &#039;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&#039;;</li>
<li>&nbsp; <b>echo</b> $out;</li></ol></div>
</div>
<h2>Вывод навигации «Циклы статей», даже если статья не в цикле.</h2>
<p>Если у статьи есть родительская и есть сестры, то будет выведена дополнительная навигация, которую реализовали выше.</p>
<p>А что если текущая статья не состоит в цикле (не имеет родительской) или не можем получить предыдущую и последующую статьи по другой причине?</p>
<p>Как альтернатива "ничего не выводить" можно вывести ссылку на предыдущую и следующую статью глобально по сайту.</p>
<p>Более того, вместо ссылки на главную страницу цикла можно вывести ссылку на ленту статей (home), а именно - на страницу пагинации n (siteurl/home/next/n), содержащую текущую статью. </p>
<h3>Получение предыдущей (по времени публикации  на блоге) статьи.</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> получем предыдущую статью</li>
<li>&nbsp;$CI-&gt;db-&gt;select(&#039;page_id, page_title, page_slug&#039;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;where(&#039;page_status&#039;, &#039;publish&#039;);</li>
<li>&nbsp;$CI-&gt;db-&gt;where(&#039;page_date_publish &lt;&#039;, $pages&#91;0&#93;&#91;&#039;page_date_publish&#039;&#93;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;limit(1);</li>
<li>&nbsp;$CI-&gt;db-&gt;order_by(&#039;page_date_publish&#039;, &#039;desc&#039;);</li>
<li class="odd">&nbsp;$query = $CI-&gt;db-&gt;get(&#039;page&#039;);</li>
<li>&nbsp;<b>if</b> ($query-&gt;num_rows() &gt; 0)</li>
<li class="odd">&nbsp;{ </li>
<li>&nbsp;  $row = $query-&gt;row_<b>array</b>(1);</li>
<li class="odd">&nbsp;  $url = getinfo(&#039;siteurl&#039;) . &#039;page/&#039; . $row&#91;&#039;page_slug&#039;&#93;;</li>
<li>&nbsp;  $prev_page_link = &#039;&lt;a href="&#039; . $url . &#039;" title="&#039; . mso_strip($row&#91;&#039;page_title&#039;&#93;) . &#039;"&gt;&#039; . mso_strip($row&#91;&#039;page_title&#039;&#93;) . &#039;&lt;/a&gt;&#039;;              </li>
<li class="odd">&nbsp;}</li></ol></div>
</div>
<h3>Получение следующей (по времени публикации  на блоге) статьи.</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> получем следующую статью</li>
<li>&nbsp;$CI-&gt;db-&gt;select(&#039;page_id, page_title, page_slug&#039;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;where(&#039;page_status&#039;, &#039;publish&#039;);</li>
<li>&nbsp;$CI-&gt;db-&gt;where(&#039;page_date_publish &gt;&#039;, $pages&#91;0&#93;&#91;&#039;page_date_publish&#039;&#93;);</li>
<li class="odd">&nbsp;<b>if</b> ($page_id_date_now) $CI-&gt;db-&gt;where_not_in(&#039;page_id&#039;, $page_id_date_now);</li>
<li>&nbsp;$CI-&gt;db-&gt;order_by(&#039;page_date_publish&#039;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;limit(1);</li>
<li>&nbsp;$query = $CI-&gt;db-&gt;get(&#039;page&#039;);</li>
<li class="odd">&nbsp;<b>if</b> ($query-&gt;num_rows() &gt; 0)</li>
<li>&nbsp;{ </li>
<li class="odd">&nbsp;   $row = $query-&gt;row_<b>array</b>(1);</li>
<li>&nbsp;   $url = getinfo(&#039;siteurl&#039;) . &#039;page/&#039; . $row&#91;&#039;page_slug&#039;&#93;;</li>
<li class="odd">&nbsp;   $next_page_link = &#039;&lt;a href="&#039; . $url . &#039;" title="&#039; . mso_strip($row&#91;&#039;page_title&#039;&#93;) . &#039;"&gt;&#039; . mso_strip($row&#91;&#039;page_title&#039;&#93;) . &#039;&lt;/a&gt;&#039;;              </li>
<li>&nbsp;}</li></ol></div>
</div>
<h3>Получение ссылки "Назад к списку статей".</h3>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> получим ссылку на страницу пагинации home/next/n, на которой текущая страница </li>
<li>&nbsp;<span class="php-comment">//</span> для этого получим номер текущей по порядку сортровки по дате</li>
<li class="odd">&nbsp;</li>
<li>&nbsp;<span class="php-comment">//</span> кол-во на главной  </li>
<li class="odd">&nbsp;$home_limit = mso_get_option(&#039;home_limit_post&#039;, &#039;templates&#039;, &#039;7&#039;);</li>
<li>&nbsp;     </li>
<li class="odd">&nbsp;<span class="php-comment">//</span> получим все страницы только ID </li>
<li>&nbsp;$CI-&gt;db-&gt;select(&#039;page_id&#039;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;where(&#039;page_status&#039;, &#039;publish&#039;);</li>
<li>&nbsp;$CI-&gt;db-&gt;where(&#039;page_date_publish &lt;&#039;, date(&#039;Y-m-d H:i:s&#039;));</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;order_by(&#039;page_date_publish&#039;, &#039;desc&#039;);</li>
<li>&nbsp;$query = $CI-&gt;db-&gt;get(&#039;page&#039;);</li>
<li class="odd">&nbsp;$result = $query-&gt;result_<b>array</b>(); <span class="php-comment">//</span> здесь номера всех страниц</li>
<li>&nbsp;</li>
<li class="odd">&nbsp;<b>if</b> ($result) <span class="php-comment">//</span> имеются страницы </li>
<li>&nbsp;{</li>
<li class="odd">&nbsp;  <span class="php-comment">//</span> найдем страницу, на которой текущая</li>
<li>&nbsp;  $i = 1; <span class="php-comment">//</span> счетчик </li>
<li class="odd">&nbsp;  $found = 0; <span class="php-comment">//</span> найденный номер</li>
<li>&nbsp;  <b>foreach</b> ($result <b>as </b>$cur_page)</li>
<li class="odd">&nbsp;  {</li>
<li>&nbsp;     <b>if</b> ($cur_page&#91;&#039;page_id&#039;&#93; == $pages&#91;0&#93;&#91;&#039;page_id&#039;&#93;) </li>
<li class="odd">&nbsp;     {</li>
<li>&nbsp;     <span class="php-comment">//</span> если нашли нашу</li>
<li class="odd">&nbsp;     $no = (int) ($i/$home_limit); <span class="php-comment">//</span> номер страницы</li>
<li>&nbsp;         $no = $no+1; <span class="php-comment">//</span> т к первая - нулевая</li>
<li class="odd">&nbsp;         <b>if</b> ($no&gt;0) $url = getinfo(&#039;siteurl&#039;) . &#039;home/next/&#039; . $no;</li>
<li>&nbsp;         <b>else</b> $url = getinfo(&#039;siteurl&#039;) . &#039;home&#039;;</li>
<li class="odd">&nbsp;     $parent_page_link = &#039;&lt;a href="&#039; . $url . &#039;" title="&#039; . $info_text&#91;&#039;home&#039;&#93; . &#039;"&gt;&#039; . $info_text&#91;&#039;<b>return</b>&#039;&#93; . &#039;&lt;/a&gt;&#039;;    </li>
<li>&nbsp;      break;</li>
<li class="odd">&nbsp;     }  </li>
<li>&nbsp;     $i++;</li>
<li class="odd">&nbsp;  }</li>
<li>&nbsp;}</li></ol></div>
</div>
<h2>Как организовать вывод всего этого в своем шаблоне?</h2>
<p>Проще всего интегрировать описанный функционал в свой шаблон при помощи type_foreach файлов.</p>
<p>Вывод навигации: главная, предыдущая, следующая можно реализовать в файле type_foreach/page-do.php.</p>
<p>Пример можете наблюдать в этом блоге.</p>
<p>Вот готовый файл, который нужно разместить в type_foreach шаблона.</p>
<div class="stb-download_box stb_box" >Скачать файл: <a title="page_do.zip" href="http://filsadovnik.ru/files/page_do.zip">page_do.zip</a></div>
<h2>Дополнение: Как получить следующую и предыдущую только из рубрик текущей.</h2>
<p>Часто, может возникнуть дополнительная задача - чтобы следующая и предыдущая статья были из той же рубрики/рубрик, что и текущая. Речь, понятно, идет не о случае с циклом статей, а о глобально по сайту следующей и предыдущей.</p>
<p>Тогда к запросу получения нужно добавить такие строчки:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;$CI-&gt;db-&gt;join(&#039;cat2obj&#039;, &#039;cat2obj.page_id = page.page_id&#039;, &#039;left&#039;);</li>
<li>&nbsp;$CI-&gt;db-&gt;join(&#039;category&#039;, &#039;cat2obj.category_id = category.category_id&#039;);</li>
<li class="odd">&nbsp;$CI-&gt;db-&gt;where_in(&#039;category.category_id&#039;, $pages&#91;0&#93;&#91;&#039;page_categories&#039;&#93;);</li>
<li>&nbsp;$CI-&gt;db-&gt;group_by(&#039;page_id&#039;);</li></ol></div>
</div>
<p>Ну и, конечно, заменить в <strong>$CI->db->select()</strong> 'page_id' на 'page.page_id' во избежание ошибки: <strong>Error Number: 1052 Column 'page_id' in field list is ambiguous</strong>.</p><a href="http://filimonov.com.ua/page/cikly-statej-maxsite-cms#comments"> Обсудить</a>]]></description>
		</item>
				<item>
			<title><![CDATA[Сохраняем EXIF при изменении изображения в плагине Taggallery для MaxSite CMS]]></title>
			<link>http://filimonov.com.ua/page/exif_copy_write_pel</link>
			<guid>http://filimonov.com.ua/page/exif_copy_write_pel</guid>
			<pubDate>Thu, 05 Jan 2012 18:41:26 +0400</pubDate>
			<category><![CDATA[MaxSite CMS плагины, Taggallery plugin]]></category>
			<description><![CDATA[<p>В MaxSite CMS загружать изображения можно как при помощи  встроенного загрузчика MaxSite CMS, так и плагина-файлового менеджера. EXIF данные исходного файла загружаются в файл, создаваемый на сервере.</p>
<p>Если изображения загружать без изменений, то EXIF данные можно извлекать из файла изображения на сервере.</p>
<p>Если же происходит изменение изображения (ресайз, наложение водной метки) - EXIF теряются.</p>
<p>Как предотвратить потерю EXIF при изменении изображения?</p>
<a id="cut"></a> 
<h2>Почему, при наложении водной метки и ресайзе, теряются EXIF данные об изображении?</h2>
<p>Все очень просто.</p>
<p>Для изменения размера или наложения воной метки используется библиотека GD2. При изменении исходного изображения, вместо исходного изображения - создается новое. В это новое изображение и записывается измененная картинка.</p>
<p>EXIF же данные никак не переносятся.</p>
<h2>Зачем нужны EXIF данные? </h2>
<p>Раньше EXIF данные никак не использовал и о проблемах с этим делом не ведал.</p>
<p>Использовать начал дату снимка в плагине галерей изображений <a href="http://filimonov.com.ua/category/taggallery_maxsite_plugin" title="Taggallery plugin">Taggallery</a>. В этом плагине о добавляемом изображении создается запись, содержащая целых три поля даты: дата добавления в БД, дата изменения файла, дата снимка.</p>
<p>В настройках плагина можно указать сортировку картинок (как в админке, так и при выводе галерей в альбомах) по любому из полей, в том числе и по любой дате. Кроме того, можно указать: какая дата выводится, как дата картинки.</p>
<p>Очевидно, что красивее всего выглядит именно дата снимка. А дата снимка находится именно в EXIF.</p>
<p>Но и тут проблем не возникало. Дело в том, что удобнее загружать уже уменьшенные до нужного размера изображения. Ресайз удобно делать такими программами, как: Office Picture Manager или XnView, в которых EXIF не теряется.</p>
<p>Проблема возникла, когда я решил проставить водные метки изображениям, для чего приделал к плагину галерей Taggalery утилиту <a href="http://filimonov.com.ua/page/add_water" title="Плагин водных меток на загруженные ранее картинки Add_Water для MaxSite CMS">Watermark</a> для наложения водных меток. Эта утилита позволяет просмотреть все возможные варианты наложения, выбрать оптимальный вариант и откатить, если что.</p>
<p>И тут оказалось, что при наложении водной метки EXIF теряются. </p>
<p>Конечно можно сперва добавить картинку в БД, считав дату из EXIF - затем уже наложить watermark. Но это как-то некрасиво.</p>
<h2>Сохраняем EXIF при ресайзе и наложении водной метки на изображение. </h2>
<p>Порыв интернет я нашел несколько библиотек для работы с EXIF, но без сучка без задоринки заработала только одна: PEL (PHP Exif Library).</p>
<p>Архив с примерами и классом: <a title="PHP Exif Library" href="http://sourceforge.net/projects/pel/">http://sourceforge.net/projects/pel/</a>.</p>
<p>Вот как прикрутил к утилите Watermark:</p>
<div class="stb-code_box stb_box" ><div class="pre"><ol class="pre"><li class="odd">&nbsp;<span class="php-comment">//</span> $full_path - полный путь к исходной картинке </li>
<li>&nbsp;<b>if</b> ($wotermark_type) <span class="php-comment">//</span> $wotermark_typ - тип наложения для библиотеки GD2</li>
<li class="odd">&nbsp;{</li>
<li>&nbsp;   <span class="php-comment">//</span>каталог плагина галереи изображений</li>
<li class="odd">&nbsp;   $plugin_dir = getinfo(&#039;plugins_dir&#039;) . &#039;taggallery/&#039;;</li>
<li>&nbsp;   </li>
<li class="odd">&nbsp;   <span class="php-comment">//</span> подключаем ex<b>if</b>-библиотеку pel</li>
<li>&nbsp;   require($plugin_dir . &#039;<b>function</b>s/ex<b>if</b>/pel-0.9.1/PelJpeg.php&#039;);</li>
<li class="odd">&nbsp;  </li>
<li>&nbsp;   <span class="php-comment">//</span> получаем ex<b>if</b> исхоного изображения</li>
<li class="odd">&nbsp;   $image1 = <b>new </b>PelJpeg();</li>
<li>&nbsp;   $image1-&gt;loadFile($full_path);        </li>
<li class="odd">&nbsp;   $ex<b>if</b> = $image1-&gt;getEx<b>if</b>(); </li>
<li>&nbsp;  </li>
<li class="odd">&nbsp;   <span class="php-comment">//</span>Перед изменением создадим копию картинки для отката</li>
<li>&nbsp;   <b>if</b> (file_exists($tmp_file_path)) unlink($tmp_file_path);</li>
<li class="odd">&nbsp;   copy($full_path, $tmp_file_path);        </li>
<li>&nbsp;   $res_path = add_water_create_water($full_path , $wotermark_type , $userfile_water_file , $tmp_file_path); </li>
<li class="odd">&nbsp;   </li>
<li>&nbsp;   <span class="php-comment">//</span> сохраняем ex<b>if</b> в новое изображение</li>
<li class="odd">&nbsp;   $image2 = <b>new </b>PelJpeg();</li>
<li>&nbsp;   $image2-&gt;loadFile($res_path);        </li>
<li class="odd">&nbsp;   $image2-&gt;setEx<b>if</b>($ex<b>if</b>);</li>
<li>&nbsp;   file_put_contents($res_path, $image2-&gt;getBytes()); </li>
<li class="odd">&nbsp;   <b>if</b> ($res_path == $full_path) <b>echo</b> &#039;&lt;div class="update"&gt;Вотермарк наложена. Если не устраивает - произведите откат.&lt;/div&gt;&#039;;</li>
<li>&nbsp;   <b>else</b> <b>echo</b> &#039;&lt;div class="error"&gt;Ошибка создания Watermark.&lt;/div&gt;&#039;;</li>
<li class="odd">&nbsp;}</li></ol></div>
</div>
<div class="stb-download_box stb_box" >Скачать обновленный плагин: <a title="taggallery23.zip" href="http://filsadovnik.ru/files/taggallery23.zip">taggallery23.zip</a></div>
<a href="http://filimonov.com.ua/page/exif_copy_write_pel#comments"> Обсудить</a>]]></description>
		</item>
			</channel>
</rss>

