<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2russianfull.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>SimpleCoding.org</title>
	
	<link>http://www.simplecoding.org</link>
	<description>Блог о программировании</description>
	<lastBuildDate>Sat, 12 May 2012 16:22:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/simplecoding" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="simplecoding" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">simplecoding</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.bloglines.com/sub/http://feeds.feedburner.com/simplecoding" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://lenta.yandex.ru/settings.xml?name=feed&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2Fsimplecoding" src="http://lenta.yandex.ru/i/addfeed.gif">?????? ? ??????.?????</feedburner:feedFlare><feedburner:feedFlare xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" href="http://www.pusk.ru/#A:Rfeed=http://feeds.feedburner.com/simplecoding" src="http://blog.pusk.ru/wp-includes/images/rss_icon_neutral.png">Subscribe with pusk.ru</feedburner:feedFlare><item>
		<title>Синхронизация файлов с помощью Dropbox: несколько оригинальных вариантов использования</title>
		<link>http://www.simplecoding.org/sinxronizaciya-fajlov-s-pomoshhyu-dropbox-neskolko-originalnyx-variantov-ispolzovaniya.html</link>
		<comments>http://www.simplecoding.org/sinxronizaciya-fajlov-s-pomoshhyu-dropbox-neskolko-originalnyx-variantov-ispolzovaniya.html#comments</comments>
		<pubDate>Sat, 12 May 2012 16:22:06 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1275</guid>
		<description><![CDATA[Лет пять назад я перепробовал кучу разных программ для синхронизации файлов между компьютерами. Проблема тогда стояла очень остро, даже было несколько случаев когда я по неосторожности затирал новые версии файлов старыми Тогда более-менее проблему удалось решить с помощью программки Allway Sync. Помню, что пользовался ей довольно долго, но всё-равно было не очень удобно, т.к. синхронизация [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1276" class="wp-caption alignnone" style="width: 115px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/05/dropbox_logo.png" alt="dropbox logo" title="dropbox logo" width="105" height="94" style="float:left" class="size-full wp-image-1276" /><p class="wp-caption-text"> </p></div>
<p>Лет пять назад я перепробовал кучу разных программ для синхронизации файлов между компьютерами. Проблема тогда стояла очень остро, даже было несколько случаев когда я по неосторожности затирал новые версии файлов старыми <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Тогда более-менее проблему удалось решить с помощью программки <a href="http://allwaysync.com/">Allway Sync</a>. Помню, что пользовался ей довольно долго, но всё-равно было не очень удобно, т.к. синхронизация запускалась в ручном режиме. Кстати, я был удивлен, когда узнал, что эта программа развивается до сих пор. Но в любом случае, с появлением <a href="http://db.tt/ymVBtKjN">Dropbox</a> большинство проблем с синхронизацией файлов просто исчезло, во всяком случае, для меня. </p>
<p>Сейчас файлы обновляются полностью автоматически и обычно быстрее чем я успеваю начать работу <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  При этом частично устраняется зависимость от интернета, т.к. файлы хранятся и на винчестере, и на серверах Dropbox&#039;а.</p>
<p>Но, не смотря на то, что я использую Dropbox практически с момента его появления, о некоторых возможностях узнал совсем недавно и случайно. Поэтому в этой статье расскажу об известных мне вариантах использования Dropbox, а если вы их дополните – буду очень благодарен <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
<span id="more-1275"></span></p>
<h2>1) Безопасность</h2>
<p>Очень интересная тема, о которой, к сожалению, задумываются далеко не все пользователи. Поэтому здесь остановимся подробно.</p>
<p>Нужно четко понимать, что как только вы выкладываете файлы на какой-нибудь online хранилище, то в один «прекрасный» момент они могут оказаться доступны всем желающим. И не важно по какой причине это произойдет, из-за проблем с самим сервисом или из-за ваше халатности, решать эти проблемы в любом случае придется вам. Кстати, есть интересный <a href="http://habrahabr.ru/post/117465/">пост на хабре</a> на эту тему.</p>
<div id="attachment_1277" class="wp-caption alignnone" style="width: 241px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/05/keepass_truecrypt.png" alt="keepass truecrypt" title="keepass truecrypt" width="231" height="134" class="size-full wp-image-1277" /><p class="wp-caption-text"> </p></div>
<p>В общем, файлы с конфиденциальными данными нужно шифровать. Я для этих целей использую 2 программы: <a href="http://keepass.info/">KeePass</a> для хранения паролей и <a href="http://www.truecrypt.org/">TrueCrypt</a> для файлов.<br />
С KeePass всё достаточно просто, сбрасываете portable версию в папку Dropbox&#039;а и можно работать. А при использовании TrueCrypt нужно учесть, что в <a href="http://db.tt/ymVBtKjN">Dropbox</a> вы будете хранить образ зашифрованого диска (это один файл) и этот файл будет синхронизироваться целиком после любых изменений. Поэтому не делайте его очень большим. Если файлов много, лучше создайте несколько зашифрованных дисков.</p>
<h2>2) «Расшаривание» папок (Shared folders)</h2>
<p>Для использования ваш коллега должен быть <a href="http://db.tt/ymVBtKjN">зарегистрирован</a> на Dropbox&#039;е. А расшарить папку достаточно просто, в контекстном меню для нужной папки выбираете <code>Dropbox -> Share this folder</code>.</p>
<div id="attachment_1278" class="wp-caption alignnone" style="width: 460px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/05/dropbox_share.png" alt="dropbox share" title="dropbox share" width="450" height="76" class="size-full wp-image-1278" /><p class="wp-caption-text"> </p></div>
<p>Нужно будет ввести email пользователя Dropbox, которому вы хотите дать доступ к файлам.</p>
<h2>3) Использование в качестве галереи</h2>
<p>Если в расшареной папке есть картинки, то при просмотре через web интерфейс, Dropbox автоматически создаст галлерею. Примерно также, как это делают сервисы вроде <a href="http://picasaweb.google.com">Picasa</a> и <a href="http://fotki.yandex.ru/">Яндекс.Фотки</a>. Возможностей у последних, конечно больше, но иногда нужно показать парочку фотографий человеку, которому вы не хотите давать ссылку на ваш профиль в этих сервисах.</p>
<h2>4) Загрузка и раздача торрентов</h2>
<p>Не будем обсуждать легальный или нелегальный контент вы загружаете через торренты. В любом случае, Dropbox позволяет ускорить процесс. Особенно если загрузка происходит очень медленно. Вы сможете начать загрузку дома и спокойно продолжить её на работе. И появляется возможность раздавать файлы одновременно с нескольких компьютеров.</p>
<h2>5) Использование как файлообменника</h2>
<p>Использовать Dropbox для раздачи больших файлов не получится, во всяком случае, бесплатную версию. Вам просто не хватит места. Тем не менее, если нужно передавать файлы размером в несколько десятков или сотен мегабайт, то Dropbox подходит отлично. Копируете их в папку Public и в контекстном меню выбираете <code>Dropbox -> Copy public link</code>.</p>
<div id="attachment_1279" class="wp-caption alignnone" style="width: 460px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/05/dropbox_public.png" alt="dropbox public" title="dropbox public" width="450" height="58" class="size-full wp-image-1279" /><p class="wp-caption-text"> </p></div>
<p>После этого передаете ссылку нужным людям. Главный плюс такого подхода – вашим знакомым не придётся изучать рекламные ролики файлообменников в поисках кнопки Download <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h2>6) Хранение репозиториев, настроек программ</h2>
<p>У многих программ, особенно кроссплатформенных, настройки хранятся в виде обычных файлов, и вам ничто не мешает синхронизировать их с помощью <strong>dropbox</strong>. Сюда относятся: конфиги серверов, профили браузеров, save&#039;ы игрушек и т.п. Конечно, могут быть нюансы. Например, если файлы должны быть расположены в строго определённой папке, которая находится за пределами папки dropbox, то их придётся копировать вручную, но, по крайней мере, удобный инструмент для создания бекапов у вас будет. И, конечно, можно довольно быстро получить нужные настройки на новом компьютере.</p>
<p>Также я пробовал размещать небольшие репозитории Git, в основном для экспериментов, никаких проблем не заметил.</p>
<h2>7) Восстановление файлов и просмотр изменений</h2>
<p>Эти возможности доступны через web интерфейс. Пользоваться мне ими не приходилось и, надеюсь, не придётся <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  Тем не менее, отображаются удалённые файлы правильно.</p>
<h2>Альтернативные сервисы для хранения и синхронизации файлов</h2>
<p>За последнее время отрылось три сервиса практически полностью аналогичных <a href="http://db.tt/ymVBtKjN">Dropbox</a>. Причём, практически одновременно. Это:</p>
<p>1) <a href="https://drive.google.com/start#home">Google Drive</a>;<br />
2) <a href="http://disk.yandex.ru/">Яндекс.Диск</a>;<br />
3) <a href="https://skydrive.live.com/">SkyDrive</a> от Microsoft.</p>
<p>Принцип работы у всех трёх практически одинаков. Вы устанавливаете специальную программу и указываете папку, в которой будете хранить файлы. После этого синхронизация начинает работать автоматически.</p>
<p>Отличается лишь размер бесплатной версии хранилища и стоимость его расширения. Кстати, что характерно, у всех трёх сервисов цены ниже, чем у Dropbox. Но у последнего есть запас доверия со стороны клиентов, а люди не очень любят экспериментировать со своими файлами <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Поэтому, я думаю, в ближайшее время нас порадуют дополнительными возможностями.</p>
<p><strong>В общем, будет интересно!</strong></p>
<p><em>При подготовке статьи использовались:</em></p>
<p><a href="http://lifehacker.com/5527055/the-cleverest-ways-to-use-dropbox-that-youre-not-using">The Cleverest Ways to Use Dropbox That You’re Not Using</a><br />
<a href="http://www.makeuseof.com/tag/four-ways-to-integrate-the-dropbox-file-sharing-program-into-your-life/">4 Unique and Cool Ways To Use Dropbox</a><br />
<a href="http://web.appstorm.net/how-to/personal-media/5-creative-uses-for-dropbox/">5 Creative Uses for Dropbox</a></p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/TQ56t-DJCb4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/sinxronizaciya-fajlov-s-pomoshhyu-dropbox-neskolko-originalnyx-variantov-ispolzovaniya.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress: выбор случайных постов</title>
		<link>http://www.simplecoding.org/wordpress-vybor-sluchajnyx-postov.html</link>
		<comments>http://www.simplecoding.org/wordpress-vybor-sluchajnyx-postov.html#comments</comments>
		<pubDate>Sun, 29 Apr 2012 14:59:16 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1272</guid>
		<description><![CDATA[Идея написать этот пост у меня появилась после выхода статьи Random Redirection In WordPress в Smashing magazine. В ней рассказывается о том, как выполнить редирект на случайный пост. Но точно такой же подход можно использовать и для отображения случайных постов, например, в каком-нибудь виджете. Сразу хочу пояснить. Я ничего не имею против решения, описанного в [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1273" class="wp-caption alignnone" style="width: 295px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/04/wordpress_sql_rand.png" alt="wordpress sql rand" title="wordpress sql rand" width="285" height="230" class="size-full wp-image-1273" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Идея написать этот пост у меня появилась после выхода статьи <a href="http://wp.smashingmagazine.com/2012/04/19/random-redirection-in-wordpress/">Random Redirection In WordPress</a> в Smashing magazine.</p>
<p>В ней рассказывается о том, как выполнить редирект на случайный пост. Но точно такой же подход можно использовать и для отображения случайных постов, например, в каком-нибудь виджете.</p>
<p>Сразу хочу пояснить. Я ничего не имею против решения, описанного в Smashing magazine, это встроенный в <strong>WP</strong> способ выборки случайных записей, просто при его использовании можно ощутимо снизить скорость формирования страниц.</p>
<p>Для начала <strong>рассмотрим, как работает стандартный вариант</strong>.<br />
<span id="more-1272"></span><br />
Для этого немного перепишем функцию, приведённую в Smashing magazine.</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">function show_random_posts($count = 3) {
     $start = microtime(true);

     $args = array(
         &#039;numberposts&#039; =&gt; $count,
         &#039;orderby&#039; =&gt; &#039;rand&#039;,
         &#039;post_type&#039; =&gt; &#039;any&#039;,
     );

     $rnd_posts = get_posts( $args );

     foreach ( $rnd_posts as $post ) {
          echo &#039;&lt;p&gt;&lt;a href=&quot;&#039;.get_permalink($post-&gt;ID).&#039;&quot;&gt;&#039;.$post-&gt;post_title.&#039;&lt;/a&gt;&lt;/p&gt;&#039;;
     }

     $stop = microtime(true);
     echo &#039;&lt;p&gt;Затраченное время: &#039;.($stop - $start).&#039;&lt;/p&gt;&#039;;
}</pre>
<p>Здесь мы выбираем заданное количество случайных записей (<code>$count</code>) с помощью встроенной функции <code>get_posts</code>. Эта функция в качестве параметра получает массив с настройками поиска. В данном случае это:<br />
<code>numberposts</code> – количество записей, которые должен вернуть запрос;<br />
<code>orderby</code> – сортировка, в данном случае – <code>rand</code> – случайным образом;<br />
<code>post_type</code> – типы постов – <code>any</code> – все.</p>
<p>Затем в цикле (строки 12-14) просто выводим список полученных постов.</p>
<p>Кроме того, в переменных <code>$start</code> и <code>$stop</code> сохраняем время начала и завершения кода.</p>
<p>Использовать эту функцию не сложно, достаточно просто вставить её в шаблон нужной страницы.</p>
<p><strong>Но что именно происходит при вызове get_posts?</strong></p>
<p>WP делает один запрос к БД, который возвращает все необходимые данные.</p>
<pre class="brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false">SELECT   wp_posts.* FROM wp_posts  WHERE 1=1  AND wp_posts.post_type IN (&#039;post&#039;, &#039;page&#039;, …) AND (wp_posts.post_status = &#039;publish&#039;)  ORDER BY RAND() DESC LIMIT 0, 3;</pre>
<p>Просто и элегантно <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Но известно, что функция <code>RAND()</code> <strong>снижает скорость запроса</strong>.</p>
<p>Попробуем переписать нашу функцию так, чтобы получить тот же результат, но обойтись без <code>RAND()</code>.</p>
<p>У меня получился следующий код</p>
<pre class="brush: php; gutter: true; first-line: 1; highlight: []; html-script: false">function show_random_posts_optimized($count = 3) {
     $start = microtime(true);

     $args = array(
         &#039;numberposts&#039; =&gt; -1,
         &#039;fields&#039; =&gt; &#039;ids&#039;,
         &#039;post_type&#039; =&gt; &#039;any&#039;,
     );

     $random_posts_ids = get_posts($args);
     $rnd_posts = array_rand($random_posts_ids, $count);

     foreach ( $rnd_posts as $post_index ) {
          $id = (int)$random_posts_ids[$post_index];
          $post = get_post($id);
          echo &#039;&lt;p&gt;&lt;a href=&quot;&#039;.get_permalink($post-&gt;ID).&#039;&quot;&gt;&#039;.$post-&gt;post_title.&#039;&lt;/a&gt;&lt;/p&gt;&#039;;
     }

     $stop = microtime(true);
     echo &#039;&lt;p&gt;Затраченное время: &#039;.($stop - $start).&#039;&lt;/p&gt;&#039;;
}</pre>
<p><em>Идея следующая</em>. Сначала получаем ID всех постов. Обратите внимание, что если вы не укажите параметр <code>'fields' => 'ids'</code>, WordPress &#034;вытянет&#034; все посты целиком. Очень неприятная ошибка, в разы увеличивает потребление памяти.</p>
<p>На этом этапе выполняется запрос</p>
<pre class="brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false">SELECT   wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type IN (&#039;post&#039;, &#039;page&#039;, ...) AND (wp_posts.post_status = &#039;publish&#039;)  ORDER BY wp_posts.post_date DESC ;</pre>
<p>Затем выбираем случайным образом заданное количество постов, с помощью <code>array_rand</code>.</p>
<p>И в цикле получаем данные постов с помощью <code>get_post</code>. На этом этапе выполняются запросы вида</p>
<pre class="brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false">SELECT * FROM wp_posts WHERE ID = 23 LIMIT 1;</pre>
<p>Т.е. если мы выводим три случайных поста, то функция <code>show_random_posts_optimized</code> будет выполнять 4 запроса для получения информации о постах, а <code>show_random_posts</code> &#8211; всего 1.</p>
<p>Но <strong>проверим время выполнения</strong>.</p>
<p>Первый эксперимент я провел на блоге с ~40 постами.<br />
Результаты:</p>
<p><code>show_random_posts - 0.021620035171509 с<br />
show_random_posts_optimized - 0.0076930522918701 с</code></p>
<p>В абсолютном выражении цифры небольшие, но разница заметная &#8211; в <strong>2.8</strong> раза.</p>
<p>Теперь посмотрим, что произойдет на реальном блоге с 1700+ постами.</p>
<p>Результаты:</p>
<p><code>show_random_posts - 0.49169611930847 с<br />
show_random_posts_optimized - 0.039859056472778 с</code></p>
<p>Как видите, теперь первая функция работает в <strong>12.3</strong> раза медленнее.</p>
<p><strong>Выводы</strong> сделать несложно.</p>
<p>Второй вариант работает быстрее и выдаёт тот же результат, но дело не в этом. Подобные проблемы могут быть практически не заметны во время разработки и привести к очень не приятным результатам при запуске на реальном ресурсе. Или ещё хуже, скорость будет падать постепенно, по мере добавления новых постов.</p>
<p>А найти проблемный запрос довольно просто. Установите <a href="http://wordpress.org/extend/plugins/blackbox-debug-bar/">BlackBox Debug Bar</a> или аналогичный плагин и он вам выведет список всех выполненных запросов и затраченное на них время.</p>
<p>Что делать дальше, зависит от ситуации. В данном случае, оказалось достаточно переделать алгоритм выбора случайных постов. В других, возможно, придется использовать кеширование или, в крайнем случае, вообще отказаться от какой-то возможности. Главное, понять причину проблемы, тогда и выбранное решения будет обоснованным и эффективным… скорее всего <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Happy coding</strong> <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/XjkeWgAhfRE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/wordpress-vybor-sluchajnyx-postov.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Конференция для веб-разработчиков «ZFConf 2012»</title>
		<link>http://www.simplecoding.org/konferenciya-dlya-veb-razrabotchikov-zfconf-2012.html</link>
		<comments>http://www.simplecoding.org/konferenciya-dlya-veb-razrabotchikov-zfconf-2012.html#comments</comments>
		<pubDate>Sat, 14 Apr 2012 12:54:36 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1268</guid>
		<description><![CDATA[21 апреля в Москве состоится конференция для веб-разработчиков &#8211; ZFConf 2012. Как несложно догадаться из названия, мероприятие в основном будет посвящено одному из самых популярных на сегодняшний день фреймворку &#8211; Zend Framework, но также будут доклады о базах данных, архитектуре веб-приложений, очередях сообщений и деплойменте. Среди докладчиков будут: Enrico Zimuel из Zend Framework Core Team, [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1269" class="wp-caption alignnone" style="width: 202px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/04/logo_habr_friends_20120329.jpg" alt="logo zend conf 2012" title="logo zend conf 2012" width="192" height="139" class="size-full wp-image-1269" style="float:left" /><p class="wp-caption-text"> </p></div>
<p><strong>21 апреля в Москве</strong> состоится конференция для веб-разработчиков &#8211; ZFConf 2012. Как несложно догадаться из названия, мероприятие в основном будет посвящено одному из самых популярных на сегодняшний день фреймворку &#8211; Zend Framework, но также будут доклады о базах данных, архитектуре веб-приложений, очередях сообщений и деплойменте.</p>
<p>Среди докладчиков будут: Enrico Zimuel из Zend Framework Core Team, Виктор Фараздаги, Александр Веремьев, Алексей Качаев и другие специалисты.</p>
<p>Посмотреть <a href="http://www.zfconf.ru/2012/talks/" target="_blank">список докладов</a> и <a href="http://www.zfconf.ru/2012/registration/" target="_blank">зарегистрироваться</a> можно на официальном сайте конференции.<br />
<span id="more-1268"></span><br />
<strong>Доклады</strong></p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/zend-framework-2-a-quick-start/" target="_blank">Zend Framework 2, a quick start</a></strong><br />
Enrico Zimuel (<a href="http://www.zend.com/" target="_blank">Zend Technologies</a>, Zend Framework Core Team)</p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/code-generation-and-scaffolding-in-zend-framework-2/" target="_blank">Code Generation и Scaffolding в Zend Framework 2</a></strong><br />
Виктор Фараздаги (Simple Square, Senior Developer)</p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/ibm-db2-embedded-sql-for-php-implementation/" target="_blank">Реализация доступа к СУБД IBM DB2 посредством встраиваемого SQL</a></strong><br />
Александр Веремьев (Zend Framework contributor) </p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/distributed-network-applications-with-zend-framework-2-and-zeromq/" target="_blank">Распределенные сетевые приложения c Zend Framework 2 и ZeroMQ</a></strong><br />
Алексей Качаев (<a href="http://cogniance.com/" target="_blank">Сogniance</a>, Senior Software Engineer) </p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/dependency-management-in-php-and-zend-framework-2/" target="_blank">Dependency Management в PHP и Zend Framework 2</a></strong><br />
Кирилл Чебунин (<a href="http://www.creara.ru/" target="_blank">Creara</a>, Senior PHP Developer) </p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/caching-without-misses-with-zend-framework-2/" target="_blank">Кеш без промахов средствами Zend Framework 2</a></strong><br />
Никита Грибалев (<a href="http://www.nival.com/" target="_blank">Nival</a>, Lead PHP Developer) </p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/architecture-design-implementation-and-organization-of-the-development-process-on-the-example-of-own-zend-framework-project/" target="_blank">Проектирование архитектуры, внедрение и организация процесса разработки на примере собственного проекта на основе ZF</a></strong><br />
Антон Великанов (<a href="http://sandsign.ru/" target="_blank">Sand Sign</a>, Founder&amp;CEO) </p>
<p><strong><a href="http://www.zfconf.ru/2012/talks/capistrano-for-deployment-php-applications/" target="_blank">Capistrano для деплоймента PHP-приложений</a></strong><br />
Роман Лапин (<a href="http://evercodelab.com/" target="_blank">Evercode Lab</a>, Senior Developer) </p>
<p>К участию также приглашаются <a href="http://www.zfconf.ru/2012/sponsors/" target="_blank">спонсоры</a> и инфопартнеры. Вопросы и предложения отправляйте, пожалуйста, через <a href="http://www.zfconf.ru/contacts/" target="_blank">форму обратной связи</a>.</p>
<p><strong>Новости о конференции вы найдете в:</strong></p>
<ul>
<li><strong>Хабраблог:</strong> <a href="http://habr.ru/company/wizartech/blog/" target="_blank">habr.ru/company/wizartech/blog/</a>
<li><strong>Facebook:</strong> <a href="http://www.facebook.com/groups/143714275748061/" target="_blank">facebook.com/groups/143714275748061/</a>
<li><strong>ВКонтакте:</strong> <a href="http://vk.com/zfconf" target="_blank">vk.com/zfconf</a>
<li><strong>RSS:</strong> <a href="http://feeds.feedburner.com/zfconf" target="_blank">feeds.feedburner.com/zfconf</a>
<li><strong>Twitter:</strong> <a href="http://twitter.com/zfconf" target="_blank">twitter.com/zfconf</a>
</ul>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/wHBz0GJwqAw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/konferenciya-dlya-veb-razrabotchikov-zfconf-2012.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP: Компиляция LESS с помощью Phing</title>
		<link>http://www.simplecoding.org/php-kompilyaciya-less-s-pomoshhyu-phing.html</link>
		<comments>http://www.simplecoding.org/php-kompilyaciya-less-s-pomoshhyu-phing.html#comments</comments>
		<pubDate>Mon, 12 Mar 2012 14:22:10 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Phing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1264</guid>
		<description><![CDATA[В последнее время библиотеки, которые добавляют новые возможности CSS, становятся всё более популярными. Наиболее известные из них – LESS и SASS (SCSS). Какое-то время назад я пытался выбрать наиболее подходящую из них для собственных целей, но, в конечном итоге, понял, что разница минимальна и лучше потратить время на что-нибудь более полезное Тем не менее, одно [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1265" class="wp-caption alignnone" style="width: 258px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/03/phing-less.png" alt="phing-less" title="phing-less" width="248" height="119" class="size-full wp-image-1265" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>В последнее время библиотеки, которые добавляют новые возможности CSS, становятся всё более популярными. Наиболее известные из них – <a href="http://lesscss.org/">LESS</a> и <a href="http://sass-lang.com/">SASS</a> (SCSS). Какое-то время назад я пытался выбрать наиболее подходящую из них для собственных целей, но, в конечном итоге, понял, что разница минимальна и лучше потратить время на что-нибудь более полезное <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Тем не менее, одно отличие между LESS и SASS всё же есть. В дистрибутиве LESS есть скрипт less.js, который преобразует .less файлы в .css прямо в браузере. Это очень удобно использовать при разработке, т.к. вам будет достаточно обновить страницу, чтобы увидеть изменения. Но для продакшена такой вариант не подходит по нескольким причинам.<br />
<span id="more-1264"></span><br />
Во-первых, <em>увеличивается время загрузки страницы</em>, т.к. посетителям будет отправляться дополнительный скрипт.<br />
Во-вторых, <em>на преобразование стилей уходит какое-то время</em>, правда, less.js достаточно «умный» и кэширует стили в localStorage.<br />
В-третьих, <em>посетители с отключённым JavaScript вообще не увидят стилей</em>.</p>
<p>Избежать всех этих проблем можно просто <strong>преобразовав файлы на сервере</strong>. В этом случае посетитель получит обычный css файл, и вообще не будет знать, что вы использовали <strong>LESS</strong>.</p>
<p>На официально сайте для преобразования LESS файлов предлагается использовать Node.js. Но устанавливать его только ради LESS, по-моему, перебор. Кроме того, очень удобно, когда все операции для подготовки проекта к публикации на продакшн сервере можно выполнить одной командой.</p>
<p>Для этих целей отлично подходит <a href="http://www.phing.info/trac/">Phing</a> о котором я раньше написал <a href="http://www.simplecoding.org/category/phing">несколько статей</a>. Пересказывать основные принципы работы с ним я не буду, вместо этого просто покажу, как создать задачу, преобразующую <code>less</code>-файлы в <code>css</code>.</p>
<p>Среди стандартных задач Phing подходящей вы не найдете, но существует проект <a href="https://github.com/bhcarpenter/phing-tasks">My Custom Phing Tasks</a> в который входят все необходимые библиотеки.</p>
<h2>Установка</h2>
<p>1. Скачайте и распакуйте архив с проектом.</p>
<p>2. Скопируйте папку rych (из архива phing-tasks) в папку, в которую вы установили <strong>Phing</strong>.</p>
<p>3. Импортируйте задачу LessCompilerTask. Для этого, добавьте в ваш build файл строку</p>
<pre class="brush: xml; gutter: false; first-line: 1; highlight: []; html-script: false">&lt;taskdef name=&quot;lessc&quot; classname=&quot;phing.rych.tasks.LessCompilerTask&quot; /&gt;</pre>
<p>Обратите внимание, что путь к файлу указывается не через слеш, а через точку, начиная с папки в которую установлен phing. Если вы ошибётесь на этом шаге, то при запуске сборки увидите сообщение о том, что файл <code>LessCompilerTask.php</code> не найден.</p>
<p>4. Создайте задачу для сжатия файлов. Для начала рассмотрим стандартный пример из описания phing-tasks.</p>
<pre class="brush: xml; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;target name=&quot;compile-less&quot; description=&quot;Compile LESS to CSS&quot;&gt;
    &lt;lessc targetdir=&quot;path/to/published/css&quot;&gt;
        &lt;fileset dir=&quot;path/to/less/sources&quot;&gt;
            &lt;include name=&quot;*.less&quot; /&gt;
        &lt;/fileset&gt;
    &lt;/lessc&gt;
&lt;/target&gt;</pre>
<p>Как видите, для работы задачи нужно указать исходную папку, папку в которой будут размещены <code>css</code> файлы и шаблон для поиска <code>less</code> файлов. Это полностью рабочий пример, но если его немного изменить работать будет немного удобнее. Например:</p>
<pre class="brush: xml; gutter: true; first-line: 1; highlight: []; html-script: false">&lt;property name=&quot;LESS_DIR&quot; value=&quot;path/to/less/sources&quot; /&gt;
&lt;property name=&quot;CSS_DIR&quot; value=&quot;path/to/published/css&quot; /&gt;

&lt;target name=&quot;compile-less&quot; description=&quot;Compile LESS to CSS&quot;&gt;
    &lt;lessc targetdir=&quot;${CSS_DIR}&quot;&gt;
        &lt;fileset dir=&quot;${LESS_DIR}&quot;&gt;
            &lt;include name=&quot;**/*.less&quot; /&gt;
        &lt;/fileset&gt;
    &lt;/lessc&gt;
&lt;/target&gt;
</pre>
<p>Здесь мы использовали два свойства <code>LESS_DIR</code> и <code>CSS_DIR</code> для того, чтобы сохранить пути к папкам и не указывать их в параметрах задачи. И изменили шаблон файла. Взгляните,</p>
<p><code>*.less</code> – означает, что будут найдены все файлы с расширением <code>less</code>, которые находятся в папке, указанной в атрибуте <code>dir</code> тега <code>fileset</code>.</p>
<p><code>**/*.less</code> – означает, что будут найдены все файлы с расширением <code>less</code>, которые находятся в папке, указанной в атрибуте <code>dir</code> тега <code>fileset</code> <strong>и во всех вложенных папках</strong>.</p>
<p>Это очень удобно, если у вас большой проект, состоящий из нескольких компонентов, и в каждом из них есть свои <code>less</code> файлы.</p>
<p>После этого вам достаточно просто запустить сборку проекта и phing создаст все необходимые css файлы.</p>
<p><strong>Успехов!</strong></p>
<p><em>P.S.</em> Кстати, обратите внимание в проект My Custom Phing Tasks входит ещё одна задача, очень подходящая для следующего шага <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/i3UhEn884Xs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/php-kompilyaciya-less-s-pomoshhyu-phing.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>WordPress: простой способ отлючить трекбеки для части постов (без плагинов)</title>
		<link>http://www.simplecoding.org/wordpress-prostoj-sposob-otlyuchit-trekbeki-dlya-chasti-postov-bez-plaginov.html</link>
		<comments>http://www.simplecoding.org/wordpress-prostoj-sposob-otlyuchit-trekbeki-dlya-chasti-postov-bez-plaginov.html#comments</comments>
		<pubDate>Sat, 21 Jan 2012 14:46:53 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1259</guid>
		<description><![CDATA[С недавних пор этот блог опять стали одолевать спамеры. Не знаю с чем это связано, больше года всё было относительно спокойно. Проскакивало по несколько спамерских комментариев в неделю, явно написанных людьми, а не ботами, и всё. А тут по 10-20 требкеков в день. Удалить их, конечно, не сложно, но надоедает и раздражает, к тому же [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1260" class="wp-caption alignnone" style="width: 275px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/01/wordpress_block_trackback.png" alt="wordpress block trackback" title="wordpress block trackback" width="265" height="229" class="size-full wp-image-1260" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>С недавних пор этот блог опять стали одолевать спамеры. Не знаю с чем это связано, больше года всё было относительно спокойно. Проскакивало по несколько спамерских комментариев в неделю, явно написанных людьми, а не ботами, и всё. А тут по 10-20 требкеков в день. Удалить их, конечно, не сложно, но надоедает и раздражает, к тому же трекбеки явно ставились автоматически, т.е. спамер своё время на них не тратил.</p>
<p>Вообще я не сторонник отключения каких-либо каналов общения. В теории трекбеки сильно упрощают создание связей между блогами. Но на практике получается, что нормальные требкеки приходят к более-менее новым постам, а спамерские – обычно ко всем подряд.</p>
<p>Поэтому я решил закрыть трекбеки для всех постов старше 2-х месяцев. Ставить специальный плагин для решения этой задачи нет никакой необходимости, всё можно сделать с помощью несложного <strong>SQL запроса и cron&#039;а</strong>.<br />
<span id="more-1259"></span></p>
<h2>Теория</h2>
<p>В WordPress все посты хранятся в таблице <code>wp_posts</code> (префикс <code>wp_</code> может быть другим). В этой таблице есть поле <code>ping_status</code>, которому можно присвоить одно из двух значений: «open» или «closed». Как несложно догадаться по названию, значение «closed» отключает трекбеки к данном посту.</p>
<p>Теперь нужно определиться с датами. MySQL поддерживает довольно много <a href="http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html">функций для работы со временем и датами</a>. Нам потребуются:<br />
1) <code>CURDATE</code> – возвращает текущую дату;<br />
2) <code>DATE_SUB</code> – вычитает даты;<br />
и выражение <code>INTERVAL ... DAY</code> – позволяет указать интервал с заданным количеством дней.</p>
<p>Дата последнего изменения поста хранится в поле <code>post_modified</code> (таблицы <code>wp_posts</code>).</p>
<h2>Формируем запрос</h2>
<pre class="brush: sql; gutter: true; first-line: 1; highlight: []; html-script: false">UPDATE wp_posts SET ping_status=&quot;closed&quot; WHERE post_modified &lt; DATE_SUB(CURDATE(), INTERVAL 60 DAY)</pre>
<p>Как видите, это обычный UPDATE запрос, который установит полю <code>ping_status</code> значение «closed» для всех записей у которые последний раз обновлялись более 60-ти дней назад.</p>
<p>Кстати, аналогичным способом можно закрыть и комментарии. Для этого нужно установить значение «closed» для поля «comment_status».</p>
<h2>Остаётся настроить периодический запуск этого запроса</h2>
<p>Удобнее всего для этого использовать cron. Тут потребуются хотя бы базовые навыки работы с панелью управления хостингом. В большинстве панелей в меню находится ссылка на страницу cron, а для создания задачи нужно заполнить небольшую форму. При этом необходимо указать два обязательных параметра – команду, которую будет выполнять cron, и периодичность её выполнения.</p>
<p>В данном случае команда может выглядеть следующим образом.</p>
<pre class="brush: bash; gutter: true; first-line: 1; highlight: []; html-script: false">mysql --default-character-set=utf8 --user=user_name --password=user_password db_name &lt; path_to/block_trackbacks.sql</pre>
<p>Здесь <code>block_trackbacks.sql</code> – имя файла в котором записан наш запрос.</p>
<p>Периодичность выполнения можно указать – 1 раз в день. Принципиальной роли, в данном случае, она не играет.</p>
<h2>Результаты</h2>
<p>Как и следовало ожидать, работает данный метод очень неплохо. Количество спама в трекбеках снизилось практически до нуля <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  И, обратите внимание, данный способ подходит для любой CMS, главное, найти какое поле отвечает за отключение трекбеков.</p>
<p><strong>Успехов!</strong></p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/0aQlpMun8I4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/wordpress-prostoj-sposob-otlyuchit-trekbeki-dlya-chasti-postov-bez-plaginov.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS: оформление скроллбара в стиле Gmail</title>
		<link>http://www.simplecoding.org/css-oformlenie-skrollbara-v-stile-gmail.html</link>
		<comments>http://www.simplecoding.org/css-oformlenie-skrollbara-v-stile-gmail.html#comments</comments>
		<pubDate>Sat, 14 Jan 2012 19:30:05 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[Web дизайн]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1252</guid>
		<description><![CDATA[Сегодня мы рассмотрим небольшой пример оформления скроллбара для браузеров на движке WebKit (Chrome, Safari). Сразу хочу сказать, что я не сторонник изменения внешнего вида скролла, всё-таки это стандартный элемент управления и большинство пользователей привыкли к его виду. Злоупотребление возможностью его изменения может усложнить работу с сайтом. Тем не менее, в некоторых случаях создание собственного дизайна [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1253" class="wp-caption alignnone" style="width: 230px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/01/gmail-scroll.png" alt="gmail scrollbar" title="gmail scrollbar" width="220" height="208" class="size-full wp-image-1253" style="float:left" /><p class="wp-caption-text"> </p></div>
<p>Сегодня мы рассмотрим небольшой пример <strong>оформления скроллбара для браузеров на движке WebKit</strong> (Chrome, Safari).</p>
<p>Сразу хочу сказать, что я не сторонник изменения внешнего вида скролла, всё-таки это стандартный элемент управления и большинство пользователей привыкли к его виду. Злоупотребление возможностью его изменения может усложнить работу с сайтом.</p>
<p>Тем не менее, в некоторых случаях создание собственного дизайна для скроллбара полностью оправдано. Возьмем в качестве примера структуру страницы Gmail.<br />
<span id="more-1252"></span></p>
<div id="attachment_1254" class="wp-caption alignnone" style="width: 460px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/01/gmail-window.png" alt="gmail-window" title="gmail-window" width="450" height="327" class="size-full wp-image-1254" /><p class="wp-caption-text"> </p></div>
<p>Видите, скроллбар находится внутри страницы, т.е. логично, что его внешний вид должен соответствовать дизайну всей страницы. Ведь во многих случаях в web интерфейсах используется нестандартное оформление кнопок, чекбоксов, ползунков и других элементов управления.</p>
<h2>Теперь рассмотрим, каким образом можно изменить внешний вид скролла</h2>
<p>Движок WebKit поддерживает несколько CSS псевдоклассов, которые определяют оформление различных областей скроллбара. Взгляните на следующий рисунок.</p>
<div id="attachment_1255" class="wp-caption alignnone" style="width: 460px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/01/scroll-default.png" alt="scroll-default" title="scroll-default" width="450" height="204" class="size-full wp-image-1255" /><p class="wp-caption-text"> </p></div>
<p>Как видите, все псевдоклассы имеют префикс <code>-webkit-</code>.<br />
Кроме перечисленных на картинке, есть ещё два псевдокласса:<br />
<code>::-webkit-scrollbar-corner</code> – отвечает за оформление квадрата в месте соприкосновения вертикального и горизонтального скролла;<br />
<code>::-webkit-resizer</code> – используется для скроллбаров текстовой области, размеры которой можно изменять.</p>
<p>Также, вместе с этими классами можно использовать различные псевдоэлементы.</p>
<p>Обычные <code>:enabled</code>, <code>:disabled</code>, <code>:hover</code> и <code>:active</code> и специальные:</p>
<p><code>:horizontal</code> – применяется для частей скроллбара, которые расположены горизонтально;</p>
<p><code>:vertical</code> – применяется для частей скроллбара, которые расположены вертикально;</p>
<p><code>:decrement</code> – применяется к участкам полосы прокрутки и кнопкам при перемещении окна просмотра вверх или влево;</p>
<p><code>:increment</code> – применяется к участкам полосы прокрутки и кнопкам при перемещении окна просмотра вниз или вправо;</p>
<p><code>:start</code> – применяется к кнопкам и участкам полосы прокрутки. Показывает находится ли объект выше (левее) ползунка;</p>
<p><code>:end</code> – применяется к кнопкам и участкам полосы прокрутки. Показывает находится ли объект ниже (правее) ползунка;</p>
<p><code>:double-button</code> – применяется к кнопкам и участкам полосы прокрутки. Используется для того, чтобы определить, является ли кнопка частью двойной кнопки, расположенной на одном из концов полосы прокрутки. Для полосы прокрутки этот псевдокласс показывает граничит ли она с двойной кнопкой;</p>
<p><code>:single-button</code> – применяется к кнопкам и участкам полосы прокрутки. Используется для того, чтобы определить, является ли кнопка одинарной. Для полосы прокрутки этот псевдокласс показывает граничит ли она с одинарной кнопкой;</p>
<p><code>:no-button</code> – применяется к участкам полосы прокрутки и показывает, касается ли она края скроллбара (например, если нет кнопок на краях скроллбара);</p>
<p><code>:corner-present</code> – применяется к участкам полосы прокрутки и показывает, присутствует ли угловая область скроллбара (квадрат на стыке горизонтального и вертикального скроллбаров);</p>
<p><code>:window-inactive</code> – применяется ко всем элементам скроллбара и показывает является ли окно к которому относится данный скроллбар активным.</p>
<h2>Переходим к нашему примеру</h2>
<p>В скроллбаре, который используется в Gmail, нет кнопок вверх-вниз, а ползунок представляет собой обычный прямоугольник серого цвета. При наведении курсора на скроллбар, подсвечивается полоса прокрутки.</p>
<div id="attachment_1256" class="wp-caption alignnone" style="width: 26px"><img src="http://www.simplecoding.org/wp-content/uploads/2012/01/gmail-like-scroll.png" alt="gmail-like-scroll" title="gmail-like-scroll" width="16" height="101" class="size-full wp-image-1256" /><p class="wp-caption-text"> </p></div>
<p><strong>Займёмся оформлением.</strong></p>
<p>Для начала, зададим общую ширину скроллбара:</p>
<pre class="brush: css; gutter: true; first-line: 1; highlight: []; html-script: false">::-webkit-scrollbar{
    width:12px;
}</pre>
<p>Теперь займёмся оформлением полосы прокрутки (светлосерый фон, серая граница, делаем границу чуть толще с левой стороны):</p>
<pre class="brush: css; gutter: true; first-line: 1; highlight: []; html-script: false">::-webkit-scrollbar-thumb{
    border-width:1px 1px 1px 2px;
    border-color: #777;
    background-color: #aaa;
}</pre>
<p>При наведении курсора (<code>:hover</code>) на полосу прокрутки делаем её более тёмной:</p>
<pre class="brush: css; gutter: true; first-line: 1; highlight: []; html-script: false">::-webkit-scrollbar-thumb:hover{
    border-width: 1px 1px 1px 2px;
    border-color: #555;
    background-color: #777;
}</pre>
<p>Ползунок в неактивном состоянии будет выглядеть как сплошной прямоугольник серого цвета (без границы)</p>
<pre class="brush: css; gutter: true; first-line: 1; highlight: []; html-script: false">::-webkit-scrollbar-track{
    border-width:0;
}</pre>
<p>При наведении курсора на ползунок, делаем его темнее и добавляем границу.</p>
<pre class="brush: css; gutter: true; first-line: 1; highlight: []; html-script: false">::-webkit-scrollbar-track:hover{
    border-left: solid 1px #aaa;
    background-color: #eee;
}</pre>
<p>Как видите, используя обычные CSS правила можно изменить скроллбар до неузнаваемости <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Успехов!</strong></p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/3d6GOtuUaIQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/css-oformlenie-skrollbara-v-stile-gmail.html/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Yii фреймворк: создание XML-RPC сервера</title>
		<link>http://www.simplecoding.org/yii-frejmvork-sozdanie-xml-rpc-servera.html</link>
		<comments>http://www.simplecoding.org/yii-frejmvork-sozdanie-xml-rpc-servera.html#comments</comments>
		<pubDate>Sat, 24 Dec 2011 20:15:06 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[Yii]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1247</guid>
		<description><![CDATA[На мой взгляд, XML-RPC протокол является одним из наиболее удобных способов передачи данных между Интернет-ресурсами. Можно, конечно, поспорить, но на изучение XML-RPC требуется минимальное количество времени, есть множество готовых библиотек, да и используется он очень широко. Поэтому я никогда не понимал, почему разработчики отличного фреймворка Yii решили не включать библиотеку для работы с XML-RPC в [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1021" class="wp-caption alignnone" style="width: 272px"><img src="http://www.simplecoding.org/wp-content/uploads/2010/03/yii_xml_rpc.png" alt="yii xml rpc" title="yii xml rpc" width="262" height="189" style="float:left" class="size-full wp-image-1021" /><p class="wp-caption-text"> </p></div>
<p>На мой взгляд, <strong>XML-RPC протокол</strong> является одним из наиболее удобных способов передачи данных между Интернет-ресурсами. Можно, конечно, поспорить, но на изучение XML-RPC требуется минимальное количество времени, есть множество готовых библиотек, да и используется он очень широко. Поэтому я никогда не понимал, почему разработчики отличного <a href="http://www.yiiframework.com">фреймворка Yii</a> решили не включать библиотеку для работы с XML-RPC в дистрибутив. Хотя, возможно, это вопрос времени <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Тем не менее, работать нужно уже сейчас, и в этой статье мы разберём, как решить проблему с помощью сторонних библиотек.</p>
<p><em>Примечание</em>. Если вас интересует создание XML-RPC клиента, почитайте статью <a href="http://www.simplecoding.org/xml-rpc-i-yii-frejmvork.html">XML-RPC и Yii фреймворк</a>.</p>
<h2>Немного теории.</h2>
<p>Мы можем использовать два основных подхода при создании <strong>XML-RPC сервера</strong>.</p>
<p><strong>1) Отдельный скрипт.</strong> В этом случае создаём файл с именем вроде xmlrpc.php и помещаем его в корень сайта. В нём будет находиться код обработки XML-RPC запросов. Такой подход используется, например, в WordPress. Достоинство в том, что вам не нужно вносить никаких изменений в код вашего проекта, т.е. XML-RPC интерфейс получается независимым. С другой стороны, независимость приводит к тому, что вам будет гораздо сложнее работать со встроенными библиотеками фреймворка.</p>
<p><strong>2) Использование действий контроллера.</strong> Этот вариант гораздо интереснее. Во-первых, вы автоматически получаете доступ ко всем возможностям Yii. Во-вторых, в этом случае XML-RPC методы можно разделить по модулям. Т.е. подключение / отключение модуля будет автоматически подключать / отключать соответствующие XML-RPC методы.<br />
<span id="more-1247"></span><br />
Т.к. реализация первого подхода никакой сложности не представляет (фактически вы можете использовать примеры из документации к вашей библиотеке для работы с XML-RPC), мы рассмотрим второй вариант.</p>
<h2>Какие библиотеки можно использовать?</h2>
<p>По большому счёту – любые, т.к. подключение сторонних библиотек к Yii выполняется без особых проблем. Я обычно использую библиотеку <a href="http://scripts.incutio.com/xmlrpc/manual.php">Incutio XML-RPC Library</a>. Она достаточно простая, работает без проблем и, кроме того, используется в WordPress, а эта CMS используется очень часто.</p>
<p>Переходим к практике.</p>
<h2>Шаг 1. Подключаем библиотеку.</h2>
<p>Для этого скачиваем библиотеку и сохраняем файл <code>IXR_Library.php</code> в папку <code>protected/vendors</code>. Теперь подключить библиотеку можно так:</p>
<pre class="brush: php">Yii::import('application.vendors.*');
require_once ('IXR_Library.php');</pre>
<p>Этот код можно добавить в любое действие (<code>action</code>) контроллера.</p>
<h2>Шаг 2. Создаём точку входа.</h2>
<p>Как я уже говорил, в качестве точки входа мы используем действие контроллера. Код будет выглядеть примерно так:</p>
<pre class="brush: php">class MyController extends Controller {
	...
	public function actionXmlrpc() {
		Yii::import('application.vendors.*');
		require_once ('IXR_Library.php');

		$server = new IXR_Server(array(
			'my.hello' =&gt; array($this,'hello'),
		));
	}
	...
}</pre>
<p>В этом методе мы просто создаём объект типа <code>IXR_Server</code>, конструктору которого нужно передать массив с названиями XML-RPC методов. В данном случае в массиве только один элемент. Ключ этого элемента является названием XML-RPC метода, а значение – именем функции, которую нужно вызвать.</p>
<p><code>array($this,'hello')</code> означает, что будет вызван метод <code>hello</code> данного контроллера.</p>
<p>Тут нужно помнить об одном нюансе. Обычно в XML-RPC запросах не передаются данные сессий. Логин и пароль отправляются в каждом запросе в качестве параметров. Поэтому необходимо, обеспечить доступ к методу <code>actionXmlrpc()</code> без авторизации. Для этого немного изменим метод <code>accessRules</code></p>
<pre class="brush: php">public function accessRules() {
	return array(
		array('allow',  // allow all users to perform 'index' and 'view' actions
			'actions'=&gt;array('index','view','xmlrpc'),
			'users'=&gt;array('*'),
		),
		…,
	);
}</pre>
<h2>Шаг 3. Добавляем методы.</h2>
<p>Теоретически, можно ограничиться просто добавлением метода <code>hello</code>, который просто вернет «Hello, world!».</p>
<pre class="brush: php">public function hello($args) {
	return 'Hello, world!';
}</pre>
<p>Но в 99% нужно аутентифицировать пользователя. Добавим метод</p>
<pre class="brush: php">protected function xmlrpcLogin($username, $password) {
	$identity = new UserIdentity($username, $password);
	$identity-&gt;authenticate();
	if ($identity-&gt;errorCode === UserIdentity::ERROR_NONE) {
		Yii::app()-&gt;user-&gt;login($identity, 0);
		return true;
	}
	else {
		return false;
	}
}</pre>
<p>Здесь мы используем класс <code>UserIdentity</code>, который автоматически создаётся фреймворком Yii при создании приложения. В параметрах этого метода нужно передать логин и пароль. В случае успешной аутентификации метод вернёт TRUE, в противном случае – FALSE. Кроме того, данные пользователя будут доступны через Yii::app()-&gt;user, т.е. точно также как и при обычной работе с фреймворком.</p>
<p>Теперь перепишем код метода hello.</p>
<pre class="brush: php">public function hello($args) {
	if (!$this-&gt;xmlrpcLogin($args[0], $args[1])) {
		return new IXR_Error(-1, 'You did not provide the correct password');
	}
return 'Hello, world!';
}</pre>
<p>Здесь предполагается, что логин и пароль будут переданы в первом и втором параметрах XML-RPC запроса.</p>
<h2>Шаг 4. Проверяем работу.</h2>
<p>Для проверки достаточно создать обычный PHP скрипт со следующим кодом.</p>
<pre class="brush: php">require_once ('IXR_Library.php');

$client = new IXR_Client('http://my_site.domen/my/xmlrpc');
$client-&gt;debug = true;

$args = array();
$args[0] = 'login';
$args[1] = 'password';

if (!$client-&gt;query('my.hello', $args)) {
    die('Something went wrong - '.$client-&gt;getErrorCode().' : '.$client-&gt;getErrorMessage());
}
echo $client-&gt;getResponse();</pre>
<p>Как видите, создание XML-RPC сервера особой сложности не представляет. Конечно, самая сложная работа – это написание самих методов. Но не забывайте, что если у вас уже готов web интерфейс и логика по максимуму вынесена в модели, то вы сможете спокойно использовать её и в XML-RPC методах.</p>
<p><strong>Успехов!</strong></p>
<p><em>Полезная информация</em></p>
<p>Новогодний подарок от Inferno Solutions &#8211; всем новым клиентам панель ISP бесплатно и 30$ в подарок при заказе <a href="https://cp.inferno.name/cart.php">VPS в Германии</a>, Украине или Голландии! Укажите при заказе в примечании ISP+30.</p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/0gByRvLpcmc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/yii-frejmvork-sozdanie-xml-rpc-servera.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Плагин для WordPress – Terms Descriptions (версия 1.2.0)</title>
		<link>http://www.simplecoding.org/plagin-dlya-wordpress-terms-descriptions-versiya-1-2-0.html</link>
		<comments>http://www.simplecoding.org/plagin-dlya-wordpress-terms-descriptions-versiya-1-2-0.html#comments</comments>
		<pubDate>Thu, 03 Nov 2011 19:55:24 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1233</guid>
		<description><![CDATA[Приветствую всех! На днях доделал очередную версию моего плагина для WordPress &#8211; Terms Descriptions. Скачать вы её можете на отсюда. Либо, если вы уже используете этот плагин, через систему обновлений WP. После выхода предыдущего релиза прошло довольно много времени и накопилось большое количество замечаний и предложений по его доработке. Сразу хочу сказать большое спасибо всем, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Приветствую всех!</strong></p>
<p>На днях доделал очередную версию моего плагина для <strong>WordPress</strong> &#8211; <strong>Terms Descriptions</strong>. Скачать вы её можете на <a href="http://wordpress.org/extend/plugins/terms-descriptions/">отсюда</a>. Либо, если вы уже используете этот плагин, через систему обновлений WP.</p>
<p><a href="http://wordpress.org/extend/plugins/terms-descriptions/"><img src="http://www.simplecoding.org/wp-content/themes/three_cols/images/download_btn_blue.png" alt="архив с исходным кодом" /></a></p>
<p>После выхода предыдущего релиза прошло довольно много времени и накопилось большое количество замечаний и предложений по его доработке. Сразу хочу сказать большое спасибо всем, кто помогал советами и идеями, присылал подробные отчеты об ошибках. Эта информация очень пригодилась!</p>
<p>В этой версии, конечно, реализованы не все пожелания и она не идеальна, но, надеюсь, что работать с ней будет удобнее, чем с предыдущими <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><em>Примечание</em>. Посмотреть описание предыдущих версий плагина можно в статье: <a href="http://www.simplecoding.org/plagin-wordpress-terms-descriptions">Плагин WordPress: Terms Descriptions</a>.</p>
<p>Рассмотрим по порядку все основные изменения.<br />
<span id="more-1233"></span></p>
<h2>Интерфейс</h2>
<p>Переделан практически полностью. Надеюсь, будет удобнее <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>В предыдущих версиях плагин создавал всего одну страницу в админке WP. На которой были расположены форма создания новых терминов, таблица с терминами и форма с настройками. Для первых версий плагина этого было достаточно. Но добавлять новые формы было сложно, т.к. страница получалась очень загроможденной.</p>
<p>Сейчас плагин создаёт три административных страницы, которые находятся в меню «Термины».</p>
<p>На первой странице (рис.1) размещена форма добавления новых терминов и таблица с уже существующими терминами.</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_1.png"><img src="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_1-450x255.png" alt="terms_descriptions_1" title="terms_descriptions_1" width="450" height="255" class="size-medium wp-image-1235" /></a></p>
<p>Рис.1.</p>
<p>Принцип создания термина остался тем же, но форма изменилась. Во-первых, сейчас добавлена нормальная поддержка произвольных типов записей WP (custom post types). Во-вторых, для выбора записи (поста) используется поле с автокомплитом, а не выпадающий список с заголовками постов (рис. 2). Как оказалось, выпадающий список практически бесполезен, если блог содержит несколько сотен записей.</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_2.png"><img src="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_2-450x90.png" alt="" title="terms_descriptions_2" width="450" height="90" class="alignnone size-medium wp-image-1236" /></a></p>
<p>Рис. 2.</p>
<p>Также добавлена пагинация (листалка) для таблицы с терминами и возможность обновления постоянных ссылок (об этом чуть ниже).</p>
<p>На второй странице находится форма со всеми основными настройками блога (рис. 3).</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_3.png"><img src="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_3-450x235.png" alt="" title="terms_descriptions_3" width="450" height="235" class="alignnone size-medium wp-image-1237" /></a></p>
<p>Рис. 3.</p>
<p>На третьей странице (рис. 4) – инструменты для экспорта/импорта данных плагина и для пакетной загрузки терминов.</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_4.png"><img src="http://www.simplecoding.org/wp-content/uploads/2011/11/terms_descriptions_4-450x335.png" alt="" title="terms_descriptions_4" width="450" height="335" class="alignnone size-medium wp-image-1238" /></a></p>
<p>Рис. 4.</p>
<h2>Хранение терминов</h2>
<p>Способ хранения и работы с терминами также был существенно переработан. Поэтому после обновления плагина в админке появится сообщение с кнопкой «Обновить БД». Я настоятельно рекомендую <strong>сделать резервную копию базы</strong> перед выполнением этой операции.</p>
<p>Причин для внесения этих изменений было две.</p>
<p>1) Оказалось, что часть пользователей создаёт большие списки терминов. И для работы с ними целесообразно создать отдельную таблицу.</p>
<p>2) Функция <code>get_permalink</code>, которая используется в WP для формирования ЧПУ, при определённых структурах ссылок оказывается довольно ресурсоемкой. Чтобы исключить её использование при формировании страниц блога, формирование ссылки теперь осуществляется один раз при создании термина. А для того, чтобы плагин правильно работал после изменения структуры URL, добавлена возможность пакетного обновления ссылок из админки. Кнопка «Обновить ссылки» находится справа над таблицей терминов (рис. 1). Т.е. если меняете структуру ЧПУ не забудьте обновить ссылки терминов.</p>
<h2>Парсеры</h2>
<p>Одними из самых неприятных проблем, с которыми я столкнулся при поддержке плагина, были конфликты с другими плагинами.</p>
<p>На сегодняшний день, существует множество плагинов и тем, которые изменяют содержимое постов. Предугадать все последствия таких изменений практически не реально. И хоть я и старался свести такие проблемы к минимуму, избежать их не получилось. Чем сложнее становился анализ текста, тем больше проблем возникало.</p>
<p>Например, количество багрепортов увеличилось в несколько раз после того как я добавил поддержку кавычек.</p>
<p>Повторения этой ситуации с новой версией я не хотел, поэтому принял решение добавить поддержку нескольких алгоритмов установки ссылок для терминов.</p>
<p>Сейчас в дистрибутиве плагина есть два парсера.</p>
<p><strong>1) Простой</strong>. Ставит ссылку на текст, который полностью совпадает с одним из терминов.</p>
<p><strong>2) Простой с поддержкой кавычек</strong>. Работает также как и простой, но дополнительно проверяет символы вокруг найденного термина, и, если они являются кавычками, преобразует термин в ссылку.</p>
<p>Переключение между парсерами осуществляется на странице Термины-&gt;Настройки (рис. 3).</p>
<h2>Пакетная загрузка терминов</h2>
<p>Позволяет загрузить сразу несколько терминов. Удобно, если у вас есть список терминов, сформированный с помощью какой-нибудь программы.</p>
<p>Форма пакетной загрузки находится на странице Термины -&gt; Инструменты.</p>
<p>Формат добавления терминов следующий. Каждый термин должен быть записан в отдельной строке. Можно указать несколько словоформ для терминов. Разделитель словоформ – символ <code>|</code>. Т.е. точно так же, как и при добавлении нового термина. Но есть важное отличие, в качестве последней словоформы нужно указать ссылку. Ссылкой может быть обычный URL (наличие <code>http://</code> обязательно) или <code>id</code> поста (пост нужно создать до добавления терминов).</p>
<p>Например, </p>
<p><code>яблоко|яблоки|яблок|яблочный|http://apples.com<br />
груша|груш|груши|24</code><br />
и т.д.<br />
здесь, 24 – id поста на который нужно поставить ссылку.</p>
<p><em>Хочу предупредить</em>. Добавление терминов занимает некоторое время. И, при попытке загрузить большой список, время выполнения скрипта может превысить лимит, установленный хостером. В таких случаях единственный вариант решения (если не считать вариант переезда на выделенный сервер) – загружать список по частям.</p>
<h2>Заключение</h2>
<p>В общем, надеюсь, новая версия вам понравится и позволит сделать работу более комфортной <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  И, конечно, жду ваших предложений, пожеланий и баг репортов <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p><strong>Успехов!</strong></p>
<p>Полезные ссылки.</p>
<p><a href="http://cp.inferno.name/cart.php">Закажите VPS</a> Start и выше и получите 30$ + панель ISP в подарок! Отзывы &#8211; <a href="http://zapili.net">zapili.net</a></p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/KrclRDkRG3g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/plagin-dlya-wordpress-terms-descriptions-versiya-1-2-0.html/feed</wfw:commentRss>
		<slash:comments>43</slash:comments>
		</item>
		<item>
		<title>WordPress: публикация постов с помощью XML-RPC с поддержкой таксономий</title>
		<link>http://www.simplecoding.org/wordpress-publikaciya-postov-s-pomoshhyu-xml-rpc-s-podderzhkoj-taksonomij.html</link>
		<comments>http://www.simplecoding.org/wordpress-publikaciya-postov-s-pomoshhyu-xml-rpc-s-podderzhkoj-taksonomij.html#comments</comments>
		<pubDate>Tue, 11 Oct 2011 08:02:30 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web разработка]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1229</guid>
		<description><![CDATA[WordPress на сегодняшний день является одой из самых популярных CMS и последнее время активно развивается. Но, к сожалению, это развитие не всегда получается гармоничным. Одной из возможностей, которая почему-то по возможностям постоянно отстаёт от остальной части движка, является XML-RPC. На сегодняшний день этот протокол является основным средством удалённой публикации постов. И, при этом, он фактически [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1230" class="wp-caption alignnone" style="width: 310px"><img src="http://www.simplecoding.org/wp-content/uploads/2011/10/wordpress-xml-rpc-publish.png" alt="wordpress xml-rpc publish" title="wordpress xml-rpc publish" width="300" height="239" class="size-full wp-image-1230" style="float:left" /><p class="wp-caption-text"> </p></div>
<p><strong>WordPress</strong> на сегодняшний день является одой из самых популярных CMS и последнее время активно развивается. Но, к сожалению, это развитие не всегда получается гармоничным.</p>
<p>Одной из возможностей, которая почему-то по возможностям постоянно отстаёт от остальной части движка, является <strong>XML-RPC</strong>. На сегодняшний день этот протокол является основным средством удалённой публикации постов. И, при этом, он фактически бесполезен если вы используете произвольные типы записей (custom post types) и таксономии (custom taxonomies). Ни один XML-RPC метод публикации постов в WP 3.2.1 их не поддерживает.</p>
<p>Конечно, можно надеятся, что в будущих версиях ситуация изменится в лучшую сторону, но ничто не мешает добавить нужные методы прямо сейчас.</p>
<p>Рассмотрим небольшой пример.<br />
<span id="more-1229"></span><br />
Допустим, нам нужно <strong>публиковать посты произвольного типа через XML-RPC и связывать их с таксономиями</strong>. При этом, таксономии могут быть как иерархическими, так и плоскими.</p>
<p><em>Примечание</em>. Подробнее о типах постов и таксономиях рассказано в статьях: <a href="http://www.simplecoding.org/wordpress-vyvod-zapisej-proizvolnyx-tipov-custom-post-types.html">WordPress: вывод записей произвольных типов (Custom Post Types)</a> и <a href="http://www.simplecoding.org/upravlenie-kontentom-v-wordpress-cms-situaciya-na-segodnya-i-blizhajshaya-perspektiva.html">Управление контентом в WordPress CMS: ситуация на сегодня и ближайшая перспектива</a>.</p>
<h2>Немного теории</h2>
<p>В WordPress предусмотрен фильтр (<code>xmlrpc_methods</code>), позволяющий добавлять новые методы во встроенный XML-RPC сервер. Делается это следующим образом:</p>
<pre class="brush: php">add_filter('xmlrpc_methods', 'add_xml_rpc_methods');</pre>
<p>Во втором параметре фильтра указываем имя функции, которая создаст запись в глобальном массиве XML-RPC методов.</p>
<pre class="brush: php">function add_xml_rpc_methods($methods) {
	$methods['my.my_method_name'] = 'my_method_name';
	return $methods;
}

function my_method_name($args) {
//обработка XML-RPC запроса и отправка ответа
}</pre>
<p>Чтобы создать XML-RPC метод нужно добавить новый элемент в массив <code>$methods</code>. Ключ этого элемента является именем метода, а значение – именем функции, которая выполняет обработку XML-RPC запроса и формирует ответ.</p>
<h2>Реализация: XML-RPC клиент</h2>
<p>Начнём с кода, который отправляет XML-RPC запрос. В данном случае будем использовать библиотеку <a href="http://scripts.incutio.com/xmlrpc/">The Incutio XML-RPC Library</a> (она же используется и в WordPress).</p>
<pre class="brush: php">require_once ('IXR_Library.php');

$client = new IXR_Client('http://my_blog.com/xmlrpc.php');
$client-&gt;timeout = 60000;

$requestData[0] = 0; //id блога
$requestData[1] = 'admin'; //имя пользователя
$requestData[2] = 'pass'; //пароль

$post = array();

$post['post_title'] = 'New Post';
$post['post_excerpt'] = 'Short description';
$post['post_content'] = 'This story about ...';
$post['post_status'] = 'draft';
$post['post_type'] = 'my_custom_post_type'; //тип поста
$post['post_date'] = date('Y-m-d H:i:s');
$post['post_modified'] = date('Y-m-d H:i:s');

//формируем массив с терминами таксономий
$terms = array();
$terms['taxonomy_1'][] = (int)$term['term_id_1'];
$terms['taxonomy_1'][] = (int)$term['term_id_2'];
$terms['taxonomy_2'][] = (int)$term['term_id_3'];
$terms['taxonomy_3'][] = (int)$term['term_id_4'];

$post['tax_input'] = $terms;

$requestData[3] = $post;

if (!$client-&gt;query('my.publish_post', $requestData)) {
	echo 'Publish Post error: '.$client-&gt;getErrorMessage();
	return;
}

$publishedPost = $client-&gt;getResponse();</pre>
<p>Прежде всего, создаём объект <code>IXR_Client</code>, конструктору которого передаём адрес скрипт, который выполняет обработку XML-RPC запросов (xmlrpc.php).</p>
<p>Затем формируем массив с данными для публикации поста. В первых трёх элементах указываем: <code>id</code> блога (на данный момент не используется), логин и пароль. В четвертом элементе – массив с данными нового поста.</p>
<p>Чтобы сократить количество кода на стороне XML-RPC сервера, названия полей этого массива должны совпадать с полями массива, который передаётся функции <a href="http://codex.wordpress.org/Function_Reference/wp_insert_post">wp_insert_post</a>. Кстати, большинство ключей элементов этого массива совпадает с именами полей таблицы posts базы данных.</p>
<p>Обратите внимание на параметр</p>
<pre class="brush: php">$post['post_type'] = 'my_custom_post_type'; //тип поста</pre>
<p>В нём указан тип поста, который мы хотим создать. Естественно, этот тип должен быть <a href="http://codex.wordpress.org/Function_Reference/register_post_type">заранее создан</a>.</p>
<p><strong>Отдельно остановимся на таксономиях.</strong></p>
<p>WordPress поддерживает таксономии 2-х типов: иерархические и плоские. Чтобы связать пост с терминами таксономий нужно перечислить их в элементе tax_input массива, который передаётся функции <code>wp_insert_post</code>. Например, так:</p>
<pre class="brush: php">'tax_input' =&gt; array('taxonomy_1' =&gt; array('term', 'term2', 'term3'), 'taxonomy_2' =&gt; array('term1', 'term2'))</pre>
<p>Здесь <code>taxonomy_1</code>, <code>taxonomy_2</code> – имена таксономий, а <code>term</code>, <code>term1</code> и т.д. – имена терминов.</p>
<p>Но здесь есть нюансы. Если публикуется «плоская» таксономия, то можно указать, либо имя термина, либо его <code>id</code>. При этом, <code>id</code> должен иметь тип <code>int</code>, если <code>id</code> сохранён в виде строки, то WordPress просто создаст новый термин. Для иерархических таксономий можно использовать только <code>id</code> термина (при этом нет ограничения на тип значения, оно будет автоматически приведено к типу <code>int</code>).</p>
<p>Т.е. универсальный вариант установки таксономий выглядит так:</p>
<pre class="brush: php">$terms['taxonomy_1'][] = (int)$term['term_id_1'];
$terms['taxonomy_1'][] = (int)$term['term_id_2'];
$terms['taxonomy_2'][] = (int)$term['term_id_3'];
$terms['taxonomy_3'][] = (int)$term['term_id_4'];</pre>
<p>Отправка запроса выполняется с помощью метода query, а прочитать результат можно используя <code>getResponse</code>.</p>
<h2>XML-RPC сервер</h2>
<p>На серверной стороне нужно зарегистрировать новый XML-RPC метод и написать функцию, которая будет обрабатывать запрос, и возвращать результат.</p>
<p><em>Примечание</em>. Следующий код можно добавить в плагин или в файл functions.php темы.</p>
<pre class="brush: php">add_filter('xmlrpc_methods', 'add_xml_rpc_methods' );

function add_xml_rpc_methods($methods) {
	$methods['my.publish_post'] = 'my_publish_post';
	return $methods;
}

function my_publish_post($args) {
	$blog_id = (int) $args[0];
	$username = $args[1];
	$password = $args[2];
	$post_data  = $args[3];

	if ( !get_option( 'enable_xmlrpc' ) ) {
		return new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.  An admin user can enable them at %s'),  admin_url('options-writing.php') ) );
	}

	$user = wp_authenticate($username, $password);

	if (is_wp_error($user)) {
		return new IXR_Error(403, __('Bad login/pass combination.'));
	}

	wp_set_current_user( $user-&gt;ID );

	if ( !current_user_can( 'edit_private_posts' ) ) {
		return new IXR_Error( 401, __( 'Sorry, you cannot edit private posts.' ) );
	}

	if (!is_array($post_data)) {
		return new IXR_Error( 401, __( 'Sorry, no post data not found.' ) );
	}

	$id = wp_insert_post( $post_data );

	if ($id === 0) {
		return new IXR_Error( 401, __( 'Post save error.' ) );
	}

	$post = array();
	$post['id'] = $id;
	$post['permalink'] = get_permalink($id);

	return $post;
}</pre>
<p>Здесь мы регистрируем XML-RPC метод <code>my.publish_post</code> и указываем, что при обращении к нему WordPress должен вызвать функцию <code>my_publish_post</code>.</p>
<p>Большая часть кода в этой функции совпадает с большинством обработчиков стандартных XML-RPC методов WP. Собственно он оттуда и скопирован <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  . Этот код проверяет, разрешен ли XML-RPC для данного блога (строки 14-16, кстати, не забудьте его включить в админке на странице Settings -&gt; Writing), аутентифицирует пользователя и проверяет, достаточно ли у него прав для публикации поста.</p>
<p>Сама публикация выполняется с помощью всего одной функции <code>wp_insert_post</code> (строка 34).</p>
<p>Клиенту возвращаем <code>id</code> созданного поста и постоянную ссылку на него (формируем с помощью функции get_permalink).</p>
<h2>Заключение</h2>
<p>Как видите, принцип достаточно простой. Любую встроенную функцию WP можно вызвать через XML-RPC протокол и использовать все возможности движка при удалённой публикации постов.</p>
<p>Если есть вопросы или замечания, пишите, постараюсь ответить.</p>
<p><strong>Успехов!</strong></p>
<p>Интересные ссылки</p>
<p>Закажите <a href="http://printfotobook.ru">печать фотокниг</a> тремя способами: онлайн, в офисе или вип</p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/7FlRb0jVn4Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/wordpress-publikaciya-postov-s-pomoshhyu-xml-rpc-s-podderzhkoj-taksonomij.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>jQuery: обработка параметров URL</title>
		<link>http://www.simplecoding.org/jquery-obrabotka-parametrov-url.html</link>
		<comments>http://www.simplecoding.org/jquery-obrabotka-parametrov-url.html#comments</comments>
		<pubDate>Fri, 19 Aug 2011 07:45:55 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Web разработка]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=1225</guid>
		<description><![CDATA[Приветствую всех! Сегодня хочу показать небольшой пример использования библиотеки jQuery для работы с параметрами ссылок. Предположим на нашей странице есть ссылка, клик по которой отправляет запрос на выполнение некоторой операции. Пускай это будет удаление какого-нибудь объекта. HTML разметка такой ссылки может выглядеть следующим образом. &#60;a class="delete" href="http://www.simplecoding.org/script.php?action=delete_object&#38;object_id=1"&#62;Удалить&#60;/a&#62; Как видите, ссылка содержит два параметра (action и [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1226" class="wp-caption alignnone" style="width: 299px"><img src="http://www.simplecoding.org/wp-content/uploads/2011/08/jquery_parsequery.png" alt="jquery parsequery" title="jquery parsequery" width="289" height="152" class="size-full wp-image-1226" style="float:left" /><p class="wp-caption-text"> </p></div>
<p><strong>Приветствую всех!</strong></p>
<p>Сегодня хочу показать небольшой пример использования библиотеки <strong>jQuery</strong> для работы с параметрами ссылок.</p>
<p>Предположим на нашей странице есть ссылка, клик по которой отправляет запрос на выполнение некоторой операции. Пускай это будет удаление какого-нибудь объекта.</p>
<p><strong>HTML разметка</strong> такой ссылки может выглядеть следующим образом.</p>
<pre class="brush: html">&lt;a class="delete" href="http://www.simplecoding.org/script.php?action=delete_object&amp;object_id=1"&gt;Удалить&lt;/a&gt;</pre>
<p>Как видите, ссылка содержит два параметра (<code>action</code> и <code>object_id</code>), значения которых PHP скрипт сможет получить из массива <code>$_GET</code>.</p>
<p>Теперь, мы хотим выполнить удаление объекта с помощью <strong>AJAX запроса</strong>. Изменять ради него ссылку нет никакой необходимости. Просто назначаем обработчик для события <code>click</code>.<br />
<span id="more-1225"></span></p>
<pre class="brush: javascript">$('a.delete').click(function() {
  return false;
});</pre>
<p>Этот код блокирует отправку обычного запроса при клике по ссылке. Нам нужно <strong>получить параметры и отправить AJAX запрос</strong>.</p>
<p>В обработчике события <strong>click</strong> получить значение атрибута <strong>href</strong> ссылки можно следующим образом.</p>
<pre class="brush: javascript">$(this).attr('href')</pre>
<p>Затем нужно найти в этой строке параметры. Тут есть <strong>два варианта</strong>.</p>
<p>1) Если вам достаточно параметров, указанных в атрибуте <strong>href</strong> и вы не хотите их изменять, то просто передать методам <code>$.ajax</code> (или <code>$.post</code>, или <code>$.get</code>) строку с параметрами запроса.</p>
<p>Т.е. код будет выглядеть примерно так</p>
<pre class="brush: javascript">var params = $(this).attr('href').split('?');
$.post('ajax_delete.php', params[1], function(response) {
    console.log(response);
} );</pre>
<p>Здесь мы с помощью метода <code>split</code> разбили запрос на две части (по знаку вопроса), и передали методу <code>$.post</code> второй элемент массива <code>params</code>. Для данного примера он выглядит так<br />
<code>action=delete_object&amp;object_id=1</code></p>
<p>2) Если перед отправкой AJAX запроса нужно изменить/удалить/добавить какие-то параметры, то удобнее всего преобразовать строку с параметрами в хеш.</p>
<p>Для этих целей существует специальный плагин – <a href="http://plugins.jquery.com/project/parseQuery">parseQuery</a></p>
<p>Использовать его можно так.</p>
<pre class="brush: javascript">var params = $.parseQuery($( this ).attr( 'href' ).split('?'));</pre>
<p>В результате вы получите хеш</p>
<pre class="brush: javascript">{
	action: delete_object,
	object_id: 1
}</pre>
<p>Код отправки AJAX запроса при этом не изменяется. Точно также передаёте переменную <code>params</code> во втором параметре метода <code>$.post</code>.</p>
<p>В заключение посмотрите код обработчика целиком.</p>
<pre class="brush: javascript">$(document).ready(function() {
	$('a.delete').click( function() {
		var params = $(this).attr('href').split('?');
		$.post('ajax_delete.php', params[1], function(response) {
			console.log(response);
		});
		return false;
	});
});</pre>
<p>Как видите, задача решается с помощью минимального количества кода. И если у посетителя будет отключен JavaScript, то ничего особенного не произойдет. При кликах по ссылкам будут отправляться обычные запросы.</p>
<p>Если есть вопросы или замечания, пишите.</p>
<p><strong>Успехов!</strong></p>
<p><em>Интересно почитать</em></p>
<p>Платежный модуль <a href="http://www.rugento.ru/robokassa-payment-module.html" target="_blank">Robokassa для Magento</a> с поддержкой.</p>
<p>Нужна фотокнига? В наличие <a href="http://printfotobook.ru/primery_fotoknig">фотокниги образцы</a>, множество видов дизайна и верстки</p>
<img src="http://feeds.feedburner.com/~r/simplecoding/~4/C8TaO4i7wF0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/jquery-obrabotka-parametrov-url.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

