<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>PHP, Python, Perl, JavaScript</title>
	<atom:link href="http://inroot.ru/feed" rel="self" type="application/rss+xml" />
	<link>http://inroot.ru</link>
	<description>Об интернетах...</description>
	<lastBuildDate>Fri, 03 Feb 2012 12:53:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
<xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" />
		<item>
		<title>Переезд блога</title>
		<link>http://inroot.ru/2012-02/pereezda-bloga.html</link>
		<comments>http://inroot.ru/2012-02/pereezda-bloga.html#comments</comments>
		<pubDate>Fri, 03 Feb 2012 12:11:14 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Разное]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=817</guid>
		<description><![CDATA[Блог переезжает на домен omurashov.ru. Переезд весьма условный, тем не менее, некоторые публикации уже сейчас имеют редирект на новый домен. Далеко не все публикации окажутся на новом домене. Скорее всего, мигрирует только малая часть. Различная требуха и заметки сомнительного содержания останутся только здесь, а затем, через некоторое время, будут удалены окончательно. В новом блоге не [...]]]></description>
			<content:encoded><![CDATA[<p>Блог переезжает на домен <a href="http://omurashov.ru/" target="_blank">omurashov.ru</a>. Переезд весьма условный, тем не менее, некоторые публикации уже сейчас имеют редирект на новый домен.</p>
<p>Далеко не все публикации окажутся на новом домене. Скорее всего, мигрирует только малая часть. Различная требуха и заметки сомнительного содержания останутся только здесь, а затем, через некоторое время, будут удалены окончательно.</p>
<p>В новом блоге не будет статей в том смысле, в котором они бывают. Он будет состоять из заметок. В целом, будет соблюдена концепция блога. Никаких попыток написания учебного материала предприниматься больше не будет.</p>
<p>Как-то так.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2012-02/pereezda-bloga.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Обзор Acer Iconia Tab A501</title>
		<link>http://inroot.ru/2011-10/review-acer-iconia-tab-a501.html</link>
		<comments>http://inroot.ru/2011-10/review-acer-iconia-tab-a501.html#comments</comments>
		<pubDate>Sat, 01 Oct 2011 22:37:46 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Гаджеты]]></category>
		<category><![CDATA[Acer Iconia Tab A501]]></category>
		<category><![CDATA[Samsung Galaxy Tab 10.1]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=729</guid>
		<description><![CDATA[Данная заметка является продолжением другой, в которой я поведал о своем знакомстве с Samsung Galaxy Tab 10.1. Исходя из этого, я буду писать о Acer Iconia Tab A501, сравнивая его с Галакси. Именно в сравнении я выбирал новый планшет и в сравнении я буду описывать новые впечатления. Во-первых, отмечу тот факт, что средняя цена Acer [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/10/iconia_a501.jpg" alt="Acer Iconia Tab A501" title="Acer Iconia Tab A501" width="150" height="150" class="post_cover alignnone size-full wp-image-732" /></p>
<p>Данная заметка является <a href="/2011-09/review-samsung-galaxy-tab-10-1.html" target="_blank">продолжением другой</a>, в которой я поведал о своем знакомстве с Samsung Galaxy Tab 10.1. Исходя из этого, я буду писать о Acer Iconia Tab A501, сравнивая его с  Галакси. Именно в сравнении я выбирал новый планшет и в сравнении я буду описывать новые впечатления.</p>
<p>Во-первых, отмечу тот факт, что <strong>средняя цена Acer Iconia Tab A501</strong> на 4000 рублей ниже, чем <strong>средняя цена на Samsung Galaxy Tab 10.1</strong>. Для меня это не являлось основным критерием, но стало приятным бонусом. В конце концов, на полученную разницу можно купить аксессуары и прочую необходимую планшетную утварь. Во-вторых, планшет от Acera был в наличии во всех магазинах электроники, что позволяло никуда не ехать и сделать покупку не сильно удаляясь от дома или места работы.</p>
<p>И так, начну свой обзор по тому же принципу «перемывания костей», что был заявлен в предыдущей заметке. Начну с описания упаковки устройства.</p>
<p><span id="more-729"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<div class="aligncenter">
<a href="/wp-content/uploads/2011/10/Iconia_Tab_A501_front.jpeg" rel="lightbox" title="Acer Iconia Tab A501"><img src="/wp-content/uploads/2011/10/Iconia_Tab_A501_front-300x207.jpg" alt="Acer Iconia Tab A501" title="Iconia_Tab_A501_front" width="300" height="207" class="alignnone size-medium wp-image-749" /></a>
</div>
<p>Нельзя сказать, что Iconia Tab A501 упакован как-то по-особенному. В принципе, такая же простая коробка, как и в случае с Galaxy Tab 10.1. Но все же, нужно отдать должное, что Acer проявил несколько большую изобретательность и не стал делать упаковку, похожую на коробку от обуви. Как я уже сказал, разница невелика, но мой агрессивный настрой заставлял придираться абсолютно ко всему.</p>
<p>Комплектация тоже не блещет, но тряпочку для протирки экрана ребята таки положили, за что им респект и уважуха. Хотя, как выяснится потом, она не особо то и нужна, что позволило даже не вынимать ее из пакетика. Но присутствие тряпочки, судя по всему, нещадно уменьшило свободное пространство в коробке и его не хватило для наушников. Их в комплекте нет. Стыд и позор. Еще Acer не пожадничал различных инструкций и пользовательских гайдов. Этой макулатуры напихали целую вязанку. Даже какие-то рекламные листовки впихнули в общую кучу. Не могу сказать, что это большая заслуга, но при виде этих мануалов мне становилось спокойнее, чего не могу отметить в случае с Galaxy. Еще смутил тот факт, что на экране планшета не было защитной пленки. Уж не знаю, чей это косяк.</p>
<p>Galaxy Tab 10.1 выглядит потрясающе и соперничать с ним вряд ли кому-то под силу. <strong>Iconia Tab A501</strong> явно не из числа тех, кому стоит хоть попытаться. Планшет от Acer сильно уступает своим изяществом и, впрочем, не только Galaxy от Samsung. Но понятия о красивостях у всех разные и меня его внешний вид вполне устраивает, хоть и в восторг не приводит.</p>
<p>Конкуренция отсутствует и в вопросах взвешивания. Acer  тяжелее Samsung’а почти на две сотни грамма и эта разница не может оставаться незамеченной. Тем не менее, нужно отдать должное тому, что Acer  имеет алюминиевый корпус, в то время как Samsung выполнен полностью из пластика.  Также замечу, что избыток веса ощущается только при сравнении. Если просто пользоваться планшетом, то очень скоро его вес кажется совершенно нормальным и не вызывает ощущения дискомфорта. Хотя, для женской руки, пожалуй, он будет тяжеловат.</p>
<p>Экран у Acer’а совершенно обычный для подобных устройств. Он не выделяется чем-то особенным и не может похвастаться инновационными решениями. Но вот стеклянное покрытие меня откровенно порадовало. Оно крайне невосприимчиво к грязным рукам и практически не оставляет на себе следов. За целый день пользования устройством у меня ни разу не возникло желания протереть экран. Совершенно другие желания вызывал Samsung Galaxy Tab 10.1. Через 30 минут его экран имел такой вид, будто в него тыкали палкой колбасы, а не пальцами.</p>
<p>В предыдущем обзоре я писал, что, невзирая на некислое железо, анимация у Самсунговского планшета немного подтормаживает. Это практически незаметно, но имеет место. Acer  в этом плане ничуть не преуспел. Собственное, у них и железо одинаковое, нечему удивляться.</p>
<p>Снова я начал с тестирования производительности планшета. В числе предустановленного софта Acer Iconia Tab A501 было несколько 3D игр. Мало того, что это просто хорошие игры, в которые не грех поиграть на досуге, они еще и обладают хорошей графикой, что позволяет делать выводы о способностях устройства справляться с качественным медийным контентом. Samsung в этом плане подсунул свинью в виде нескольких казуальных хреновин, на которые смотреть- то противно.</p>
<p><strong>С 3D графикой Iconia Tab A501</strong> справляется превосходно. Никаких лагов, торможений или артефактов. Все, как по маслу. Полная версия (не демка) предустановленного NFS Shift убила почти весь мой рабочий день.</p>
<div class="aligncenter">
<a href="/wp-content/uploads/2011/10/2_1_Acer-Iconia-Tab-A501.jpg" rel="lightbox" title="Acer Iconia Tab A501"><img src="/wp-content/uploads/2011/10/2_1_Acer-Iconia-Tab-A501-300x215.jpg" alt="Acer Iconia Tab A501" title="Acer Iconia Tab A501" width="300" height="215" class="alignnone size-medium wp-image-755" style="border: #ccc 1px solid" /></a>
</div>
<p>Следующим шагом была загрузка трех видео: mp4, mkv и avi. С подключением по USB и обменом файлами между планшетом и настольным ПК не случилось никаких проблем. Для этой процедуры не потребовалась установка дополнительных драйверов и софта. Все в лучших традициях современности – воткнул гаджет в USB порт и пользуйся им как флешкой.</p>
<p>Без дополнительного софта и кодеков, предустановленный плеер смог прочитать только mp4 формат и то с очень большими тормозами. mkv и avi читать отказался. Но проблема решилась установкой приложения MX видеоплеер. При запуске MX видеоплеер предлагает докачать кодеки MX Video Player Codec (ARMv7) и, если вы согласны, открывает соответствующую страницу маркета. После установки кодеков и нового приложения просмотра видео, любые проблемы с тормозами и нечитабельными форматами решились. Avi формат проигрывается просто идеально. Чуть меньше динамики выдает mp4 и mkv, но тормозов или зависаний нет, что делает просмотр совершенно комфортным. Сам по себе MX видеоплеер исключительное приложение для просмотра фильмов и роликов на мобильном устройстве, очень рекомендую.</p>
<p>Кстати, при копировании видео на планшет, я не делал никакой предварительной конвертации. Возможно, если ее выполнить, то и штатный плеер окажется более способным.<br />
Предустановленным ПО Acer  несколько уступает Samsung’у.  Во-первых, офисный пакет представляет собой триальную версию Docs To Go, во-вторых, виртуальных клавиатур всего две и Swype пришлось ставить самостоятельно. Агрегатор социальных сервисов мне тоже не понравился. В принципе, я никогда подобным ПО не пользовался, но если бы хотел, то пришлось бы искать замену.</p>
<p>Постараюсь не терять объективности, но дальше буду рассказывать о том, чем <strong>Acer Iconia Tab A501 мне понравился больше Samsung Galaxy Tab 10.1</strong>.</p>
<p>Во-первых, Acer имеет USB порт, к которому можно подключить обычную USB клавиатуру, не докупая никаких док станций. Моя домашняя клавиатура прекрасно распозналась без танцев с бубном. Флешки тоже читаются без проблем. Хорошая возможность, если вы хотите заменить планшетом ноутбук или просто пытаетесь добиться максимального комфорта без лишних финансовых затрат. Также присутствует micro HDMI порт и гнездо для гарнитуры. К компьютеру планшет подключается через microUSB, что меня крайне порадовало, так как имеется ряд других устройств, подключаемых через этот же тип разъема, например, HTC Desire.</p>
<p>Во-вторых, присутствует поддержка карт памяти microSDHC объемом до 32 Гб. Если вы помните, то у Samsung Galaxy Tab 10.1 память не расширяема и вам придется довольствоваться объемом 16 или 32 Гб предустановленной памяти.</p>
<p>Помимо стандартного набора из Wi-Fi, 3G и Bluetooth присутствует GPS приемник с поддержкой A-GPS. Незаменимая вещь, если вы любите покидать домашний регион вашего мобильного оператора и не имеет возможности работать через дешевую 3G сеть. Теперь у меня появился отличный поводырь по дорогам зарубежья.</p>
<p>Когда я консультировался в магазинах на предмет возможностей и <strong>особенностей Acer Iconia Tab A501</strong>, все консультанты, как один, говорили о том, что время работы батареи значительно уступает Самсунговской. В принципе, это не удивительно, так как в Galaxy Tab 10.1 используется аккумулятор повышенной емкости. Но я сильно напрягся. Мне не хотелось бегать от розетки к розетке, так как Acer от USB тоже не заряжается.</p>
<p>Батарее я уделил особое внимание и пристально наблюдал за тем, как быстро она разряжается при той или иной интенсивности пользования устройством. Если кратко, то батарея очень даже ничего и зря меня пугали. Во-первых, у Acer’а вменяемая автобалансировка яркости экрана, что позволяет значительно уменьшить расход энергии. Аналогичная функция Samsung&#8217;а работает совершенно странным образом. Жалобы на непонятный принцип регулировки яркости присутствуют практически в любом <strong>обзоре Samsung Galaxy Tab 10.1</strong>. Такие же жалобы я слышал  от продавцов-консультантов, в довершении, подтверждаю их лично. Галакси вырубает яркость на минимум и не понятно, что дальше. Я так и не смог эмулировать ситуацию, при которой он бы увеличил ее. Видимо, нужные какие-то особые условия освещенности. Acer  в этом плане совершенно адекватен и с момента включения автобалансировки ни разу не возникало желания ее выключить.</p>
<p>Статистику пользования устройством и расход энергии батареи я запечатлел на скриншотах для большей наглядности.</p>
<div class="aligncenter">
<a href="/wp-content/uploads/2011/10/device-2011-09-30-063530.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063530-300x187.png" alt="" title="device-2011-09-30-063530" width="300" height="187" class="alignnone size-medium wp-image-734" /></a><br />
<b>Общая статистика</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063542.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063542-300x187.png" alt="" title="device-2011-09-30-063542" width="300" height="187" class="alignnone size-medium wp-image-739" /></a><br />
<b>Работа экрана устройства</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063553.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063553-300x187.png" alt="" title="device-2011-09-30-063553" width="300" height="187" class="alignnone size-medium wp-image-741" /></a><br />
<b>Режим ожидания</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063602.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063602-300x187.png" alt="" title="device-2011-09-30-063602" width="300" height="187" class="alignnone size-medium wp-image-743" /></a><br />
<b>Работа ОС Android</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063612.png" rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063612-300x187.png" alt="" title="device-2011-09-30-063612" width="300" height="187" class="alignnone size-medium wp-image-745" /></a><br />
<b>Игра NFS Shift</b></p>
<p><a href="/wp-content/uploads/2011/10/device-2011-09-30-063621.png"  rel="lightbox"><img src="/wp-content/uploads/2011/10/device-2011-09-30-063621-300x187.png" alt="" title="device-2011-09-30-063621" width="300" height="187" class="alignnone size-medium wp-image-747" /></a><br />
<b>Связь с сетью</b></p>
</div>
<p>К сожалению, по непонятным мне причинам, сборщик статистики не зафиксировал работу с некоторыми приложениями, например, браузером и видео плеером. Также в отчет не попало время работы с Wi-fi сетями и чтение книг. Наверное, оно было незначительным на фоне энергозатрат на другие приложения и модули. Тем не менее, суммарно составило порядка 2-3 часов активности планшета. Сколько устройство работало от батареи, можете видеть по скринам. Меня результаты удовлетворили полностью.</p>
<p>Время зарядки от 4% и до 100% заняло около полутора часа, что в 3 раза меньше, чем полная зарядка Samsung Galaxy Tab 10.1, которая длится порядка 5 часов.</p>
<p>Что еще можно добавить с казанному? Я полностью доволен покупкой. Acer Iconia Tab A501 оправдал все мои ожидания и я рад, что не оставил у себя планшет от Samsung&#8217;а. Все познается в сравнении и мне не жаль того времени, что я потратил на поиски приемлемого для себя планшетного компьютера. Если вы тоже стоите перед выбором и не знаете, что купить, я крайне советую обратить свое внимание на продукт от Acer а. Да, быть может он не такой элегантный и вычурный, как  Samsung Galaxy Tab 10.1, но зато даст фору во всем остальном. Если вы ищите устройство, успешно сочетающее рабочий инструмент и центр развлечений, я думаю, вы не пожалеете, остановив выбор на Acer Iconia Tab A501.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-10/review-acer-iconia-tab-a501.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Обзор Samsung Galaxy Tab 10.1</title>
		<link>http://inroot.ru/2011-09/review-samsung-galaxy-tab-10-1.html</link>
		<comments>http://inroot.ru/2011-09/review-samsung-galaxy-tab-10-1.html#comments</comments>
		<pubDate>Tue, 27 Sep 2011 05:41:30 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Гаджеты]]></category>
		<category><![CDATA[Samsung Galaxy Tab 10.1]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=723</guid>
		<description><![CDATA[Недавно приобрел планшетник Samsung Galaxy Tab 10.1. Сразу скажу, что впечатления двойственные и их совокупность меняла свою полярность то в одну, то в другую сторону на протяжении всего знакомства с девайсом. Нет, безусловно, положительных эмоций больше, нежели любых других. Но, как говорится, я ожидал большего. Предвкушал некую безграничную эйфорию, а в итоге впечатления оказались достаточно [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/09/samsung-galaxy-tab-10-1-p7510-150x150.jpg" alt="" title="samsung-galaxy-tab-10-1-p7510" width="150" height="150" class="post_cover alignnone size-thumbnail wp-image-724" /></p>
<p>Недавно приобрел планшетник Samsung Galaxy Tab 10.1. Сразу скажу, что впечатления двойственные и их совокупность меняла свою полярность то в одну, то в другую сторону на протяжении всего знакомства с девайсом.</p>
<p>Нет, безусловно, положительных эмоций больше, нежели любых других. Но, как говорится, я ожидал большего. Предвкушал некую безграничную эйфорию, а в итоге впечатления оказались достаточно приземленными. Может быть, прошел тот возраст, когда дорогая игрушка повергала в коматозную радость и заставляла писать кипятком от одного своего вида. А может, действительно, есть поводы для огорчений.</p>
<p>И так, начнем с упаковки. Она достаточно проста. Если выражаться точнее, то проще вряд ли можно что-то придумать. Я как-то привык к тому, что дорогие девайсы пакуют в красивые и хитрые коробки, которые открываются, выполняя тройной прыжок-переворот, исполняя интернационал голосами хора МВД России. Например, блок питания, который я покупал около года назад, был облачен в очень изящную, весьма оригинально собранную коробку, крышка которой фиксировалась липучками и имела окошко из плотного прозрачного пластика. Все это бесполезные рюшечки, но видимо, я из тех людей, которые все еще встречают по одежке.</p>
<p><span id="more-723"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Комплектация, в которой планшет попал ко мне, также ничем интересным не радует. Расстроило отсутствие тряпочки для протирания экрана, который, к слову, пачкается очень быстро. Никаких чехлов, само собой, тоже не было. Хотя на чехол я и не надеялся. С девайсом поставлялось всего ничего: адаптер для зарядки, USB шнур, наушники и тонкая брошюрка-инструкция, по содержимому которой можно смело предположить, что Samsung кладет ее в комплектации всех своих мобильных устройств, в том числе и телефонов. За наушники спасибо, не ожидал. Это таки не телефон и поставлять с планшетом гарнитуру никто не обязан, мне кажется, но положили.</p>
<p>Достаем планшет из коробки и наслаждаемся. Лично я получил массу удовольствия от тактильного контакта с этим гаджетом. Исполнение действительно на высоте. Приятная плавные линии, малый вес и действительно малая толщина производят впечатление. Не расстраивает даже то, что устройство полностью из пластика. В руке планшет лежит хорошо, не оставляя и намека на то, что он может соскользнуть с ладони.</p>
<p>Включаем девайс. В каком-то из обзоров я читал, что Samsung Galaxy Tab 10.1 включается ровно 40 секунд. Специально обратил внимание на время, которое проходит с момента нажатия клавиши питания и до появления экрана блокировки – секунд 10, не более. Может быть, я как-то неправильно его включаю? :)</p>
<p>Яркие обои экрана блокировки позволяют прочувствовать всю прелесть матрицы, установленной на <strong>Samsung Galaxy Tab 10.1</strong>. Качество и насыщенность изображения действительно впечатляют. Не зря Samsung так активно акцентировали внимание на этом моменте.</p>
<p>За экраном блокировки кроется первая ложка дегтя. Что не говори, а различные анимационные эффекты чуточку, но притормаживают. Возможно, если специально не обращать на это внимание, то и не заметишь, но я очень долго скролил различные списки и вертел виртуальные рабочие столы именно с целью выявления отрывистости анимации.</p>
<p>Я не буду перечислять и описывать приложения, идущие в стандартной поставке. Без внимания останется панель настроек и прочая лирика, имеющая отношение к программному обеспечению. Об этом и так немало написано, а что касается настроек, то они, в большинстве своем, стандартные для любых android устройств и данный планшет не исключение.<br />
Первое, что я захотел проверить – проигрывание видео и аудио файлов. В конце концов, мы имеем устройство с двухядерным процессором и будет очень грустно, если медиа контент окажется ему не по зубам. Тут то и начинается все самое интересное.</p>
<p>Подключив планшет по к USB порту, я сразу попытался закинуть на него несколько фильмов, каждый из которых был гигабайта по полтора. Буквально через несколько секунд процесс копирования сгенироровал ошибку, в которой говорилось, что устройство отключено или не отвечает. На самом планшете проблема давала о себе знать зависшим индикатором синхронизации. Переподключил устройство и предпринял еще одну попытку. Несложно догадаться, что и она не увенчалась успехом. Правда на этот раз девайс сообщил мне, что <strong>MTP приложение</strong> (судя по всему, это какой-то сервис, реализующий трансфер по <strong>MTP протоколу</strong>) зависло и предложил принудительно его закрыть. Погуглив минут 20 я убедился, что не только я столкнулся с подобной проблемой, но вот четкого руководства для ее решения никто не давал. Проблема, на самом деле, не в самом планшете, а по большей части в драйверах Windows. Основными страдальцами оказались владельцы устройств от Samsung и Nokia. Именно их перу принадлежали все найденные мною обсуждения в форумах. Конкретно о проблеме с Samsung Galaxy Tab 10.1 нигде не упоминалось. Наверное, ввиду относительной новизны гаджета.</p>
<p>Мне от всего этого легче не было и негативные впечатления от знакомства с Samsung Galaxy Tab 10.1 превращались в снежный ком. Я бы мог обвинить Windows и ее драйвера или даже Android и его реализацию протоколов, но это не первое мое устройство на базе Google Android, но первое, с которым у меня возникают такие вот проблемы. Я считаю, что планшет за 25000 рублей не должен вот так вот нагибать пользователя и заставлять его тратить время на поиск путей к отступлению.</p>
<p>Ушло немало времени, пока я нашел подходящий драйвер. Проблема исчезла, и файлы стали нормально заливаться на SD карту планшета. Тем не менее, спустя некоторое время, компьютер все равно потерял подключение к планшету, хотя сам планшет все еще считал, что он соединен по USB. При дальнейшем использовании проблема повторно не возникала, поэтому предположим, что это был какой-то фантомный глюк или я что-то не то нажал.</p>
<p>В общем, мне удалось залить три фильма в разных форматах: avi, mp4 и mkv. По заявлениям Samsung, все эти форматы должны проигрываться штатным плеером без каких-либо дополнительных плясок с бубном. Конвертацию файлов, которая предлагается при копировании на устройство, я не делал. В итоге, в числе прочитанных оказался только avi файл. Mp4 и mkv плеер не осилил. Правда, повторная загрузка mp4 с конвертацией позволила прочитать и его. Но стоит ли говорить, что конвертация ну ОЧЕНЬ длительный процесс. Файл размером 1.4 Гб конвертировался около двух часов. Это чуть больше, чем длиться сам фильм, который я закачивал :). Avi видео немного подтормаживает, если сравнивать просмотр того же ролика на настольной машине. Дискомфорта это не создает, так как подтормаживания совсем незначительные, но факт имеет место.</p>
<p>Что еще можно отнести к минусам? Нет слота для карты памяти. Иначе говоря, 16 гигабайт – это все, на что вы можете рассчитывать на протяжении всего пользования планшетом. Да, есть док станция, к которой можно подключить флешку, но это не то. Да и док станцию придется покупать отдельно. Планшетов с объемом памяти в 32 гигабайт пока в продаже не видел. Зарядка только от сети. От USB устройство не заряжается. Родной USB шнурок достаточно короткий и подключать его к системнику, стоящему под столом, жутко неудобно. Планшет приходится или на пол класть или держать на самом краю стола. Ввиду того, что у шнура специфичный разъем, заменить его на более длинный не получится. Вообще с аксессуарами на текущий момент ситуация плачевна. Их попросту нет. Даже чехол или защитную пленку не найти. Конечно, со временем, все это поступит в продажу, но если хотите все и сразу, то облом. Прошивка сыровата, конечно. Но это поправимо скорыми обновлениями, благо, Google Android развивается завидно быстрыми темпами, а аппаратная начинка Samsung Galaxy Tab 10.1 позволяет надеяться, что устройство сможет получить еще не одно обновление.</p>
<p>Что в итоге? Розовые очки быстро перестали быть розовыми и пришлось спуститься на землю. Кричать о том, что я счастливый обладатель крутого планшета как-то не открывается рот. Может, я сильно придираюсь и просто замечтался, а реальность, вон какая суровая, но было сильное желание отнести гаджет обратно в магазин. Просто потому, что он не стоит своих денег. Будь он тысяч на 5 дешевле, я бы взял и ни минуты об этом не жалел бы. Часть проблем, я уверен, решится с выходом новых прошивок. Остальные покроет более удачный софт, нежели тот, что предлагается изначально. Проблемы с USB подключением, с которыми я столкнулся, как мне кажется, вызваны работой под 64-битной версией ОС. Но какие аналоги есть? Почитав интернеты, сделал вывод, что заменить данный планшет нечем. Есть неплохая альтернатива среди планшетов от Acer &#8211; <strong>Acer Iconia Tab A501</strong>. Но в изяществе он значительно уступает Samsung Galaxy Tab 10.1, да и матрица там не так хорошая, а в экран Galaxy влюбляешься с первого взгляда в прямом смысле. Плюс очень сильно подкупает время работы Galaxy. Он действительно способен честно отработать до 10 часов при активном использовании.</p>
<p>В общем, если хотите хороший планшет, то покупайте <strong>Samsung Galaxy Tab 10.1</strong>, но только не сейчас. Подождите месяц-другой, когда он существенно упадет в цене, а это неизбежно случится, так как в начале следующего года на рынок поступит новое поколение планшетников, среди которых будет четырехядерный HTC и много других разных. Если очень хочется обзавестись устройством именно сейчас, то настоятельно рекомендую присмотреться к упомянутому Acer Iconia Tab A501. Отличная штука, но без лишних понтов и по адекватной цене. В принципе, изначально я на него и рассчитывал, но дернул черт посмотреть на продукт от Samsung&#8230;</p>
<p>Удачного вам выбора!</p>
<p><b>UPD 02.10.11:</b></p>
<p>История не закончилась. Я таки сделал то, о чем писал в конце данной заметки. Я отнес свой новый Galaxy Tab обратно в тот магазин, где его купил, благо, манибэк позволяет это сделать, не обосновывая свой поступок. На вопрос о том, что не так с купленным мною устройством, я ответил, что оно просто не стоит своих денег, и я был честен. Цена на Samsung Galaxy Tab 10.1 действительно завышена. В этом мнении я утвердился, когда увидел на яндекс маркете магазин, где данный гаджет стоит на 3000 рублей дешевле. Учитывая обилие недовольства от опыта общения с данным планшетом, я решил, что уж если и покупать его, то с максимальной экономией. Забрав свои деньги в одном магазине, я понес их в другой, где цена была более адекватной.</p>
<p>Не дураки придумали, что халявы не бывает. Магазин, который предлагал планшет по более низкой цене, продавал «серые» устройства. Собственно, спасибо продавцу-консультанту, который без лишних вопросов информировал меня о том, что устройство сертифицировано для Польши. Не могу сказать, что я брезгую «серым» товаром, но в данном конкретном случае это стало последней каплей. Для себя я понял, что на этом мое общение с Samsung Galaxy Tab 10.1 подошло к концу и пора прощаться. Но желание купить планшет никуда не делось и я пошел за другим девайсом, который также упоминал в данной заметке – это Acer Iconia Tab A501.</p>
<p>Продолжение истории я вынес в отдельную заметку. И так, кому интересно, <a href="/2011-10/review-acer-iconia-tab-a501.html">милости просим</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-09/review-samsung-galaxy-tab-10-1.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress функция query_posts()</title>
		<link>http://inroot.ru/2011-09/wordpress-function-query_posts.html</link>
		<comments>http://inroot.ru/2011-09/wordpress-function-query_posts.html#comments</comments>
		<pubDate>Mon, 26 Sep 2011 04:29:58 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress query_posts()]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=711</guid>
		<description><![CDATA[Тема для данной заметки навеяна проблемой, возникшей при переносе одного из блогов на VPS сервер. После переноса отказался работать плагин Advanced Category Excluder, который позволял отключить вывод постов из отдельной категории (или группы категория) в требуемых разделах блога, например, на главной странице или в архивах. В итоге, на главной оказались те публикации, которых там быть [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/09/wordpress_cover-150x150.jpg" alt="" title="wordpress_cover" width="150" height="150" class="post_cover alignnone size-thumbnail wp-image-717" /></p>
<p>Тема для данной заметки навеяна проблемой, возникшей при переносе одного из блогов на VPS сервер. После переноса отказался работать плагин Advanced Category Excluder, который позволял отключить вывод постов из отдельной категории (или группы категория) в требуемых разделах блога, например, на главной странице или в архивах. В итоге, на главной оказались те публикации, которых там быть не должно. Более того, в общую ленту вылезли ревизии, картинки и файлы. В общем, все, что пишется в таблицу wp_posts, повалило в продакшен. Что за изъян приключился с упомянутым плагином, я выяснять не стал, а просто поискал замену оному. Альтернатив оказалось не так много и было решено обойтись без плагина в принципе.</p>
<p>В целом, решение правильное, так как сам по себе плагин Advanced Category Excluder не добавляет к движку ничего нового, а служит лишь оберткой для базовых функций WordPress, делающей работу с ними более комфортной.</p>
<p><span id="more-711"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>У WordPress есть функция <strong>query_posts()</strong>, позволяющая переопределять стандартные запросы к базе данных, а следовательно, влиять на результаты выборки публикаций и страниц. Возможности ее очень богаты и можно без труда добиться практически любого результата. Так, например, в <a href="/2011-09/poisk_i_filtry_dlja_kataloga_na_wordpress_magic_fields_2.html" target="_blank">предыдущей заметке</a> я описывал процесс создания формы поиска и сортировок для каталога на WordPress, реализованного с помощью <strong>плагина Magic Fields</strong>. Желаемый эффект как раз достигался за счет использования query_posts(). Сегодня постараюсь развить тему.</p>
<p>Вызывать функцию query_posts() следует перед вызовом while (have_posts()). В качестве аргумента передается набор параметров, полным список которых, конечно же, можно найти в документации WordPress.</p>
<p>Так, например, чтобы добиться эффекта, который раньше создавался <strong>плагином Advanced Category Excluder</strong>, достаточно в индексном файле шаблона привести цикл вывода постов к следующему виду:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> query_posts<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cat=-3'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>have_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>have_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> the_post<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
		...
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Такой вызов query_posts() исключает из выборки посты, принадлежашие к категории с ID равным 3.</p>
<p>Но есть один важный нюанс. Вызывая функцию query_posts() мы полностью переопределяем способ формирования SQL запроса к базе данных. Зачастую это лишнее и требуется  только добавить новые условия к уже существующим, сгенерированным движком без нашего участия.</p>
<p>Для этого достаточно ввести переменную <b>$query_string</b> в текущую область видимости и конкатенировать ее с нашими дополнительными условиями выборки:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$query_string</span><span style="color: #339933;">;</span> query_posts<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query_string</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&amp;cat=-3'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>have_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>have_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> the_post<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
		...
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Собственно, то, что делал <strong>плагин Advanced Category Excluder</strong>, я реализовал путем добавления одной единственной строчки кода.</p>
<p>У меня нет большого желания перепечатывать родную документацию <strong>WordPress</strong>, которая, несомненно, значительно лучше меня расскажет обо всех возможностях <strong>функции query_posts()</strong>, но для полноты картины приведу несколько примеров из нее, снабдив их комментариями на русском языке.</p>
<p>Можно исключить из вывода публикации сразу из нескольких категорий, для этого достаточно перечислить их через запятую:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
	query_posts<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cat=-1,-2,-3'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Также есть возможность вывести посты по имени категории:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
	query_posts<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'category_name=software_news'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Выведет пост из блога, ID которого равен 5</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
	query_posts<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p=13'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Следующий запрос комбинирует сразу несколько условий. Он выведет 5 постов из категории с ID 7, сортированных по дате (в обратном порядке), опубликованных в 2011 году:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
	query_posts<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cat=7&amp;year=2011&amp;orderby=date&amp;order=DESC&amp;posts_per_page=5'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Данный способ определения запроса хорошо подходит в том случае, если вы не планируете полностью переопределить запрос, то есть вы будете использовать текущее значение $query_string. Если же текущее значение данной переменной вас не интересует, удобнее использовать ассоциативный массив в качестве аргумента query_posts():</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$args</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
	<span style="color: #0000ff;">'post_type'</span><span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'movie'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'actor'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'Bruce Campbell, Chuck Norris'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'order'</span>    <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'ASC'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
query_posts<span style="color: #009900;">&#40;</span><span style="color: #000088;">$args</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Официальная документация функции query_posts() находится в <a href="http://codex.wordpress.org/Function_Reference/query_posts" target="_blank" rel="external nofollow">кодексе WordPress</a></p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-09/wordpress-function-query_posts.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Поиск и фильтры для каталога на WordPress + Magic Fields. Часть 2</title>
		<link>http://inroot.ru/2011-09/poisk_i_filtry_dlja_kataloga_na_wordpress_magic_fields_2.html</link>
		<comments>http://inroot.ru/2011-09/poisk_i_filtry_dlja_kataloga_na_wordpress_magic_fields_2.html#comments</comments>
		<pubDate>Fri, 09 Sep 2011 23:49:28 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[WordPress query_posts()]]></category>
		<category><![CDATA[плагин Magic Fields]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=688</guid>
		<description><![CDATA[Продолжая тему, посвященную плагину Magic Fields, я постараюсь доступно рассказать о том, как организовать поиск по дополнительным полям, которые создаются с помощью этого плагина. Помимо процесса создания привычной поисковой формы, приведу пример организации одиночных фильтров. И то и другое, в готовом варианте, вы можете видеть в блоге, который я уже упоминал в первой заметке о [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://inroot.ru/wp-content/uploads/2011/09/magic_fields_l-150x150.png" alt="" title="magic_fields_l-150x150" width="150" height="150" class="post_cover alignnone size-full wp-image-689" /></p>
<p>Продолжая тему, посвященную плагину Magic Fields, я постараюсь доступно рассказать о том, как организовать поиск по дополнительным полям, которые создаются с помощью этого плагина. Помимо процесса создания привычной поисковой формы, приведу пример организации одиночных фильтров.</p>
<p>И то и другое, в готовом варианте, вы можете видеть в блоге, который я уже упоминал в <a target="_blank" href="/2011-07/funktsionalnyy_katalog_na_wordpress_magic_fields_1.html">первой заметке о Magic Fields</a>.  К сожалению, с тех пор я так и не удосужился уделить этому блогу сколько-нибудь достаточное количество времени, поэтому и форма и фильтры там находятся в зачаточном состоянии. Тем не менее, они отлично демонстрируют результат, являющийся логичным завершением использования данного WordPress плагина.</p>
<p>И так, приступим.</p>
<p><span id="more-688"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Единственным минусом <strong>плагина Magic Fields</strong> является невозможность создавать поля с парами ключ – значение. Быть может для вас это и не является минусом, но мне данный подход не слишком нравится. В любом случае, вариантов нет, поэтому мы будем фильтровать публикации в каталоге по строковым значениям дополнительных полей.</p>
<p>Допустим, помимо прочих, у нас есть дополнительное поле «Производитель». Список производителей строго регламентирован и при создании публикации он представляет собой selectbox.  В пользовательской части наша публикации может иметь следующий вид (скриншот с упомянутого блога)</p>
<p><img src="http://inroot.ru/wp-content/uploads/2011/09/catalog_item.png" alt="" title="catalog_item" width="547" height="242" class="aligncenter size-full wp-image-690" /></p>
<p>Все характеристики заданы дополнительным <strong>полями Magic Fields</strong>. Те значения, что подсвечиваются синим цветом являются ссылками, выполняющими роль фильтров.</p>
<p>Предположим, что мы кликаем на имя производителя LG и, перейдя обратно в каталог, хотим видеть товары только этой компании. Для реализации этой нехитрой логики открываем файл шаблона header.php и дописываем туда следующий код:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>is_category<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">||</span> in_category<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>is_home<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>is_single<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$x_params</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_type&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_type&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$x_params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'x_device_type'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_type&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_producer&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_producer&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$x_params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'x_device_producer'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_producer&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_os&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_os&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$x_params</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'x_device_os'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_os&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">sizeof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$x_params</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$query_string</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$x_string</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">null</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$x_params</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$x_string</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&amp;'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'='</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$value</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        query_posts<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query_string</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$x_string</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Код простой и не требует каких-то особых комментариев, кроме отдельных моментов.</p>
<p>Первый условный оператор банально предотвращает обработку данного кода вне требуемой категории. По моим планам, плагин должен был работать лишь для одной категории – устройства. В ней же мы фильтруем позиции, осуществляем поиск по дополнительным полям и прочему. Следовательно, нет смысла пытаться получить значения фильтров в других категориях. Из этих же соображений можно было вынести данный код в шаблон вывода постов, так как для страниц, например, он уже не актуален. Но я влепил его в <tt>header.php</tt> и так он там и остался.</p>
<p>Далее собираем все полученные значения дополнительных полей в массив <tt>$x_params</tt>. Если полей будет очень много, то не следует делать так, как сделал я, а именно писать блок условия для каждого поля. Иначе у вас будет много некрасивого и бестолкового кода. Лучше вынести имена полей в массив, а затем обходить его циклом, проверяя, пришло ли от пользователя значение для каждого поля. Но речь не об этом.</p>
<p>Собрали все значения в массив ключ =>значение и циклом конкатенируем их в строку вида <tt>&#038;x_field_name=field_value</tt>. Обратите внимание, на то, что имена дополнительных полей должны иметь <strong>префикс x_</strong>. После этого регистрируем наш обновленный запрос функцией <tt>query_posts()</tt>. Естественно, не забываем выполнить конкатенацию уже существующей строки запроса, которая храниться в переменной <tt>$query_string</tt> и наших добавленных параметров.</p>
<p>Собственно, на этом все. Если вы действовали согласно приведенному примеру, то должны получить желаемый результат. Код выше позволяет одинаково успешно использовать как фильтрацию по каждому отдельному полю, так и поисковую форму, которая будет задавать несколько параметров выборки одновременно.</p>
<p>Ниже привожу код, который будет выводить форму поиска по дополнительным полям Magic Fields. У меня она лежит в файле шаблона <tt>archive.php</tt>, но не факт, что у вас также (зависит от шаблона и способов его реализации).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>in_category<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$device_producers</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    	<span style="color: #0000ff;">'HTC'</span><span style="color: #339933;">,</span>
    	<span style="color: #0000ff;">'Sony Ericsson'</span><span style="color: #339933;">,</span>
    	<span style="color: #0000ff;">'Sumsung'</span><span style="color: #339933;">,</span>
    	<span style="color: #0000ff;">'Motorola'</span><span style="color: #339933;">,</span>
    	<span style="color: #0000ff;">'Wexler'</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&lt;form method=&quot;post&quot; action=&quot;/devices/&quot;&gt;
&lt;table&gt;
	&lt;tr&gt;
		&lt;td&gt;Производитель:&lt;/td&gt;
		&lt;td&gt;
			&lt;select name=&quot;device_producer&quot;&gt;
				&lt;option value=&quot;&quot;&gt;-&lt;/option&gt;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$device_producers</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$d_producer</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
				&lt;option<span style="color: #000000; font-weight: bold;">&lt;?</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">@</span><span style="color: #000088;">$_REQUEST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;device_producer&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$d_producer</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">' selected=&quot;selected&quot;'</span><span style="color: #339933;">;</span>  <span style="color: #000000; font-weight: bold;">?&gt;</span> value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?=</span><span style="color: #000088;">$d_producer</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?=</span><span style="color: #000088;">$d_producer</span><span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/option&gt;
				<span style="color: #000000; font-weight: bold;">&lt;?</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
			&lt;/select&gt;
		&lt;/td&gt;
	&lt;/tr&gt;
	&lt;tr&gt;
		&lt;td colspan=&quot;2&quot;&gt;&lt;input type=&quot;submit&quot; value=&quot;Показать&quot; /&gt;&lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;
&lt;/form&gt;
<span style="color: #000000; font-weight: bold;">&lt;?</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>У меня в блоге, на момент написания статьи, она выглядела примерно так:</p>
<p><img src="http://inroot.ru/wp-content/uploads/2011/09/catalog_search_form.png" alt="" title="catalog_search_form" width="614" height="130" class="aligncenter size-full wp-image-694" /></p>
<p>В общем, <strong>Magic Fields</strong> – действительно отличный <strong>WordPress плагин</strong>, позволяющий значительно расширять возможности стандартного блога. Потенциал у него достаточно большой и при желании, можно структурировать неплохой каталог со всеми необходимыми функциями.</p>
<p>Успехов!</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-09/poisk_i_filtry_dlja_kataloga_na_wordpress_magic_fields_2.html/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Bash скрипт создания виртуальных хостов Apache и Nginx</title>
		<link>http://inroot.ru/2011-08/bash-script-virtual-hosts-apache-nginx.html</link>
		<comments>http://inroot.ru/2011-08/bash-script-virtual-hosts-apache-nginx.html#comments</comments>
		<pubDate>Sat, 27 Aug 2011 07:56:34 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[bash скриптинг]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=675</guid>
		<description><![CDATA[Вчера опубликовал статью о своем опыте настройки VPS. Обещал, что как только появится время, напишу пару баш скриптов, которые автоматизируют часть рутинной работы и сведут количество действий, выполняемых руками, к разумному минимуму. Я напряг все имеющиеся извилины, откопал в аналах своей памяти скромные познания bash скриптинга и, потратив несколько часов, написал скромное приложение, которое упрощает [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2011/08/terminal_icon.png" alt="" title="" width="150" height="150" class="post_cover alignnone size-full wp-image-677" /></p>
<p>Вчера опубликовал статью о своем <a href="/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html">опыте настройки VPS</a>. Обещал, что как только появится время, напишу пару баш скриптов, которые автоматизируют часть рутинной работы и сведут количество действий, выполняемых руками, к разумному минимуму.</p>
<p>Я напряг все имеющиеся извилины, откопал в аналах своей памяти скромные познания bash скриптинга и, потратив несколько часов, написал скромное приложение, которое упрощает и ускоряет процесс создания виртуальных хостов для Apache и Nginx.</p>
<p>Чтобы скрипт был хоть сколько-нибудь интересен не только мне и имел минимум привязки к среде, где он будет запускаться, я постарался вынести все пути и прочее в блок конфига, сохранив их в переменные. Тем не менее, я не рекомендую бездумно использовать его. Хотя бы глазами пробегитесь по коду, чтобы понимать, подойдет ли он вам «из коробки» (я сомневаюсь, если честно). Всякую ответственность за последствия, которые могут приключиться с вами после использования данного скрипта, само собой, я снимаю :) Все на свой страх и риск, как говорится. Но поломаться ничего не должно. Скрипт ничего не удаляет, не вносит изменений ни в какие файлы. Он может только намусорить…</p>
<p><span id="more-675"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Ниже код скрипта и некоторые комментарии к блоку конфига и способам использования.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;">####### CONFIG START  ########</span>
&nbsp;
<span style="color: #007800;">OWNER_NAME</span>=<span style="color: #ff0000;">'username'</span> <span style="color: #666666; font-style: italic;"># Пользователь, которому будет принадлежать директория вирт. хоста </span>
<span style="color: #007800;">OWNER_GROUP</span>=<span style="color: #ff0000;">'username'</span> <span style="color: #666666; font-style: italic;"># Группа, которой будет принадлежать директория вирт. хоста </span>
<span style="color: #007800;">HOME_WWW</span>=~username<span style="color: #000000; font-weight: bold;">/</span>www <span style="color: #666666; font-style: italic;"># Домашняя директория для вирт. хостов </span>
<span style="color: #007800;">HOST_DIRS</span>=<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'backup'</span> <span style="color: #ff0000;">'logs'</span> <span style="color: #ff0000;">'public_html'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> 
<span style="color: #007800;">SERVER_IP</span>=<span style="color: #ff0000;">'127.0.0.1'</span> <span style="color: #666666; font-style: italic;"># IP адрес сервера</span>
&nbsp;
<span style="color: #007800;">WHEREIS_APACHE</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2
<span style="color: #007800;">WHEREIS_NGINX</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>nginx
&nbsp;
<span style="color: #007800;">APACHE_HOSTS_DIR</span>=<span style="color: #007800;">$WHEREIS_APACHE</span><span style="color: #ff0000;">'/sites-available'</span>
<span style="color: #007800;">NGINX_HOSTS_DIR</span>=<span style="color: #007800;">$WHEREIS_NGINX</span><span style="color: #ff0000;">'/sites-available'</span>
<span style="color: #007800;">NGINX_HOSTS_ENABLED</span>=<span style="color: #007800;">$WHEREIS_NGINX</span><span style="color: #ff0000;">'/sites-enabled'</span>
&nbsp;
<span style="color: #666666; font-style: italic;">######## CONFIG END ##########</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># COLORS</span>
<span style="color: #007800;">SETCOLOR_SUCCESS</span>=<span style="color: #ff0000;">&quot;echo -en \\033[1;32m&quot;</span>
<span style="color: #007800;">SETCOLOR_FAILURE</span>=<span style="color: #ff0000;">&quot;echo -en \\033[1;31m&quot;</span>
<span style="color: #007800;">SETCOLOR_NORMAL</span>=<span style="color: #ff0000;">&quot;echo -en \\033[0;39m&quot;</span>
<span style="color: #007800;">SETCOLOR_NOTICE</span>=<span style="color: #ff0000;">&quot;echo -en \\033[1;33;40m&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># FUNCTIONS</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> restart_servers <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Перезапускаем Apache'</span>
    <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 reload
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Перезапускаем Nginx'</span>
    <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>nginx reload
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_config <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_FAILURE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[Fail]&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'[CONFIG ERROR]: '</span><span style="color: #007800;">$1</span>
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_force_exec <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_FAILURE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[Fail]&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">'[FORCE EXEC ERROR]: '</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Скрипт не может корректно выполнить все процедуры в автоматическом режиме'</span>
    <span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_failure <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_FAILURE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[Fail]&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'[ERROR]: '</span><span style="color: #007800;">$1</span>
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">exit</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> error_notice <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">$SETCOLOR_NOTICE</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'[NOTICE]: '</span><span style="color: #007800;">$1</span>
    <span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Если запущен с ключем -f, значит задаем пользователю минимум вопросов </span>
<span style="color: #666666; font-style: italic;"># Игнорируются вопросы: </span>
<span style="color: #666666; font-style: italic;"># - имя директории виртуального хоста </span>
<span style="color: #666666; font-style: italic;"># - вопрос о перезапуске серверров (будут перезапущены)</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$1&quot;</span> == <span style="color: #ff0000;">&quot;-f&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">force_execution</span>=<span style="color: #c20cb9; font-weight: bold;">true</span>
<span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #007800;">force_execution</span>=<span style="color: #c20cb9; font-weight: bold;">false</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span>
&nbsp;
<span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$HOME_WWW</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #007800;">$HOME_WWW</span>
<span style="color: #000000; font-weight: bold;">else</span>
    error_config <span style="color: #ff0000;">&quot;Директория <span style="color: #007800;">$HOME_WWW</span> не существует&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Запрашивает имя домена, пока не будет введено</span>
<span style="color: #000000; font-weight: bold;">function</span> get_domain_name <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Имя домена: &quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">read</span> domain_name
&nbsp;
    <span style="color: #666666; font-style: italic;"># Если ничего не было введено</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$domain_name</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">$SETCOLOR_FAILURE</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Вы не ввели имя домена&quot;</span>
	<span style="color: #007800;">$SETCOLOR_NORMAL</span>
	get_domain_name
    <span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Запрашивает имя директории для виртуального хоста или предлагает создать автоматически </span>
<span style="color: #666666; font-style: italic;"># проверяет его на существование</span>
<span style="color: #000000; font-weight: bold;">function</span> get_host_dir <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Имя директории хоста: &quot;</span>
    <span style="color: #c20cb9; font-weight: bold;">read</span> host_dir
&nbsp;
    <span style="color: #666666; font-style: italic;"># Если ничего не было введено</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #007800;">$host_dir</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	<span style="color: #007800;">$SETCOLOR_NOTICE</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;Вы не ввели имя директории хоста. Создать автоматически? [Н/д]? &quot;</span>
	<span style="color: #007800;">$SETCOLOR_NORMAL</span>
&nbsp;
	<span style="color: #c20cb9; font-weight: bold;">read</span> answer
&nbsp;
	    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$answer</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
	    Y<span style="color: #000000; font-weight: bold;">|</span>y<span style="color: #000000; font-weight: bold;">|</span>д<span style="color: #000000; font-weight: bold;">|</span>Д<span style="color: #7a0874; font-weight: bold;">&#41;</span>
		<span style="color: #007800;">host_dir</span>=<span style="color: #800000;">${domain_name//\./_}</span>
		<span style="color: #007800;">host_dir</span>=<span style="color: #800000;">${host_dir//\-/}</span>
&nbsp;
		<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #800000;">${HOME_WWW}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${host_dir}</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
		    error_notice <span style="color: #ff0000;">&quot;Автоматический выбор имени директории невозможен. Задайте его самостоятельно&quot;</span>
		    get_host_dir
		<span style="color: #000000; font-weight: bold;">else</span>
		    error_notice <span style="color: #ff0000;">&quot;Директория хоста будет создана автоматически: <span style="color: #007800;">$host_dir</span>&quot;</span>
		<span style="color: #000000; font-weight: bold;">fi</span>
		<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
		<span style="color: #000000; font-weight: bold;">;;</span>
	    N<span style="color: #000000; font-weight: bold;">|</span>n<span style="color: #000000; font-weight: bold;">|</span>о<span style="color: #000000; font-weight: bold;">|</span>О<span style="color: #7a0874; font-weight: bold;">&#41;</span> get_host_dir
		<span style="color: #000000; font-weight: bold;">;;</span>
	    <span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> get_host_dir
		<span style="color: #000000; font-weight: bold;">;;</span>
	    <span style="color: #000000; font-weight: bold;">esac</span>
	get_host_dir
    <span style="color: #000000; font-weight: bold;">else</span>
	<span style="color: #7a0874; font-weight: bold;">return</span> <span style="color: #000000;">1</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
get_domain_name
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #007800;">$force_execution</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">host_dir</span>=<span style="color: #800000;">${domain_name//\./_}</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #800000;">${HOME_WWW}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${host_dir}</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	error_force_exec
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
    get_host_dir
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Проверяем пути апача из конфига</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$APACHE_HOSTS_DIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$APACHE_HOSTS_DIR</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
	error_failure <span style="color: #ff0000;">&quot;Виртуальный хост <span style="color: #007800;">$domain_name</span> уже существует для Apache&quot;</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
    error_config <span style="color: #ff0000;">&quot;Директория <span style="color: #007800;">$APACHE_HOSTS_DIR</span> не существует&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Проверяем пути nginx из конфига</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-d</span> <span style="color: #007800;">$NGINX_HOSTS_DIR</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-a</span> <span style="color: #007800;">$NGINX_HOSTS_DIR</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
        error_failure <span style="color: #ff0000;">&quot;Виртуальный хост <span style="color: #007800;">$domain_name</span> уже существует Nginx&quot;</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">else</span>
    error_config <span style="color: #ff0000;">&quot;Директория <span style="color: #007800;">$NGINX_HOSTS_DIR</span> не существует&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Домен: <span style="color: #007800;">$domain_name</span>&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Создаем директории виртуального хоста</span>
<span style="color: #007800;">host_dir_path</span>=<span style="color: #800000;">${HOME_WWW}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${host_dir}</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Создаем директории виртуального хоста:&quot;</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$host_dir_path</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> dir_name <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #800000;">${HOST_DIRS[@]}</span>; <span style="color: #000000; font-weight: bold;">do</span>
	<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #007800;">$host_dir_path</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$dir_name</span>
	<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span> <span style="color: #007800;">$host_dir_path</span>/<span style="color: #007800;">$dir_name</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #800000;">${host_dir_path}</span><span style="color: #ff0000;">'/public_html/index.html'</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Рекурсивно проставляем права</span>
<span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> <span style="color: #007800;">$OWNER_NAME</span>:<span style="color: #007800;">$OWNER_GROUP</span> <span style="color: #007800;">$host_dir_path</span>
&nbsp;
<span style="color: #007800;">apache_template</span>=<span style="color: #ff0000;">&quot;&lt;VirtualHost 127.0.0.1:8080&gt;
      ServerAdmin webmaster@<span style="color: #007800;">$domain_name</span>
      ServerName <span style="color: #007800;">$domain_name</span>
      ServerAlias www.<span style="color: #007800;">$domain_name</span>
      DocumentRoot <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/public_html
&nbsp;
      ScriptAlias /cgi-bin/ <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/public_html/cgi-bin/
      ErrorLog <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/logs/apache.error.log
      LogLevel warn
      CustomLog <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/logs/apache.access.log combined
&lt;/VirtualHost&gt;&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Создаем конфиг виртуального хоста apache</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Создаем конфиг виртуального хоста apache:'</span>
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #800000;">${APACHE_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #800000;">${APACHE_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
&nbsp;
<span style="color: #007800;">temp_ifs</span>=<span style="color: #007800;">$IFS</span>
<span style="color: #007800;">IFS</span>=
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$apache_template</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${APACHE_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span>
<span style="color: #007800;">IFS</span>=<span style="color: #007800;">$temp_ifs</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># создаем симлинк</span>
a2ensite <span style="color: #007800;">$domain_name</span>
&nbsp;
<span style="color: #007800;">nginx_template</span>=<span style="color: #ff0000;">&quot;server {
      listen <span style="color: #007800;">$SERVER_IP</span>:80;
&nbsp;
      server_name <span style="color: #007800;">$domain_name</span> www.<span style="color: #007800;">$domain_name</span>;
      access_log  <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/logs/nginx.access.log;
&nbsp;
      location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
            root /home/omm/www/<span style="color: #007800;">$host_dir</span>/public_html;
      }
&nbsp;
&nbsp;
      location / {
            proxy_pass http://backend;
            proxy_redirect off;
            proxy_set_header Host <span style="color: #000099; font-weight: bold;">\$</span>host;
            proxy_set_header X-Real-IP <span style="color: #000099; font-weight: bold;">\$</span>remote_addr;
&nbsp;
            charset utf-8;
            index index.html;
            root <span style="color: #007800;">$HOME_WWW</span>/<span style="color: #007800;">$host_dir</span>/public_html;
      }
}&quot;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;"># Создаем конфиг виртуального хоста nginx</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Создаем конфиг виртуального хоста nginx:'</span>
<span style="color: #c20cb9; font-weight: bold;">touch</span> <span style="color: #800000;">${NGINX_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\t</span>&quot;</span><span style="color: #800000;">${NGINX_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #800000;">${domain_name}</span>
&nbsp;
<span style="color: #007800;">temp_ifs</span>=<span style="color: #007800;">$IFS</span>
<span style="color: #007800;">IFS</span>=
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #007800;">$nginx_template</span> <span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #800000;">${NGINX_HOSTS_DIR}</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span>
<span style="color: #007800;">IFS</span>=<span style="color: #007800;">$temp_ifs</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># создаем симлинк</span>
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #007800;">$NGINX_HOSTS_DIR</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span> <span style="color: #007800;">$NGINX_HOSTS_ENABLED</span><span style="color: #ff0000;">'/'</span><span style="color: #007800;">$domain_name</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># Перезапускаем сервера</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #007800;">$force_execution</span>; <span style="color: #000000; font-weight: bold;">then</span>
    restart_servers
<span style="color: #000000; font-weight: bold;">else</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">'Перезапустить Apache и Nginx? [Д/н] '</span>
    <span style="color: #c20cb9; font-weight: bold;">read</span> restart_answer
&nbsp;
    <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$restart_answer</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span>
	Y<span style="color: #000000; font-weight: bold;">|</span>y<span style="color: #000000; font-weight: bold;">|</span>д<span style="color: #000000; font-weight: bold;">|</span>Д<span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    restart_servers
	<span style="color: #000000; font-weight: bold;">;;</span>
	<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
	    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">'Apache и Nginx не были перезагружены'</span>
	<span style="color: #000000; font-weight: bold;">;;</span>
    <span style="color: #000000; font-weight: bold;">esac</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #007800;">$SETCOLOR_SUCCESS</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tput hpa $(tput cols)</span>)<span style="color: #007800;">$(tput cub 6)</span>[OK]&quot;</span>
<span style="color: #007800;">$SETCOLOR_NORMAL</span></pre></td></tr></table></div>

<h2>Конфигурирование скрипта</h2>
<p>В скрипте есть комментарии, но опишу переменные настройки еще раз.</p>
<p><strong>OWNER_NAME</strong> – имя системного пользователя, которому будут принаджелать директории и файлы, создаваемые скриптом для виртуального хоста.</p>
<p><strong>OWNER_GROUP</strong> – системная группа, которой будут принаджелать директории и файлы, создаваемые скриптом для виртуального хоста.</p>
<p><strong>HOME_WWW</strong> – внутри этой директории будет создана директория виртуального хоста.</p>
<p><strong>HOST_DIRS</strong> – директории виртуального хоста, которые будут созданы. По-умолчанию сюда вписана директория для логов apache и nginx, директория для бэкапов и директория, которая будет доступна по http протоколу, собственно, куда и нужно будет класть все файлы вашего сайта.</p>
<p><strong>SERVER_IP</strong> – ip адрес вашего сервера. Прописывается в конфигах nginx.</p>
<p><strong>WHEREIS_APACHE</strong> – директория установки Apache. Относительно нее будут искаться конфиги виртуальных хостов и прочее.</p>
<p><strong>WHEREIS_NGINX</strong> &#8211; директория установки Nginx. Относительно нее будут искаться конфиги виртуальных хостов и прочее.</p>
<p><strong>APACHE_HOSTS_DIR</strong> – директория, где Apache хранит конфиги для каждого отдельного виртуального хоста. Обычно это sites-available.</p>
<p><strong>NGINX_HOSTS_DIR</strong> &#8211; директория, где Nginx хранит конфиги для каждого отдельного виртуального хоста. Обычно это sites-available.</p>
<p><strong>NGINX_HOSTS_ENABLED</strong> – директория, где хранятся симлинки на конфиги виртуального хоста Nginx. В nginx нет утилиты подобной a2ensite, поэтому нужно знать, куда создать ссылку самим. Обычно данная директория называется sites-enabled.</p>
<p>Есть еще несколько переменных, в которых хранится код разукраски сообщений, которыми скрипт отписывается в консоль. Также можно поправить поведение ряда функци. Но все это совсем опционально и если очень хочется, то поглядите сами. Там все просто.</p>
<p>В скрипте есть еще две переменных, которые объявлены почти в конце листинга: apache_template и nginx_template. В них хранятся шаблоны для виртуальных хостов. Хотя бы посмотрите, что в них описано, чтобы быть уверенными в том, что конфиги имеют именно тот вид, который вам требуется.</p>
<h2>Работа со скриптом</h2>
<p>Скрипт может работать в двух режимах.</p>
<p><strong>Простой запуск</strong> – запускаете скрипт и отвечаете на его вопросы. Он потребует ввести:</p>
<ul>
<li>имя домена, для которого создаются конфиги;</li>
<li>имя директории виртуального хоста;</li>
<li>спросит перезагрузить ли сервера, после того, как конфиги будут созданы</li>
</ul>
<p>Если не задать скрипту имя директории виртуального хоста, то он создает ее автоматически. От перезагрузки серверов можно отказаться. Это удобно, когда вы планируете создать несколько виртуальных хостов подряд и нет смысла каждый раз заставлять Nginx и Apache делать reload (при reload создается избыточная нагрузка на процессор и потребляется больше памяти. Лучше сделать это один раз, когда все хосты будут добавлены).</p>
<p><strong>Форсированный запуск</strong> – это типа автоматического режима. Скрипт задает только один вопрос – о имени домена. Все остальное он делает сам, в том числе перезагружает Nginx и Apache. При этом, если в ходе проверок скрипт выяснит, что выполнить какие-то операции он не сможет, то работа прекратится. Но учтите, что никаких подробных сообщений о проблеме не будет. Скрипт просто скажет, что он не может отработать в автоматическом режиме (скорее всего, конфликты с путями). </p>
<p>Для вызова скрипта в форсированом режиме необходимо запустить его с параметром –f</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">bash</span> script_name.sh <span style="color: #660033;">-f</span></pre></div></div>

<p>На баше я пишу раз в сотню лет, так что, уж не обессудьте.</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-08/bash-script-virtual-hosts-apache-nginx.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Сборка сервера Apache + Nginx + MySQL + PHP + ProFTPD</title>
		<link>http://inroot.ru/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html</link>
		<comments>http://inroot.ru/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html#comments</comments>
		<pubDate>Fri, 26 Aug 2011 21:39:11 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Nxing]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ProFTPD]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=646</guid>
		<description><![CDATA[Как ни странно, несмотря на развитость рынка хостинга и обилие предложений VPS, многие все еще сидят на виртуальных хостингах. Я не исключение. Раньше меня останавливали ценники на услуги dedecated или colocation. Потом эти услуги значительно упали в цене и появились еще более дешевые – VPS. Но меня все равно останавливали неведомые силы и я продолжал [...]]]></description>
			<content:encoded><![CDATA[<p>Как ни странно, несмотря на развитость рынка хостинга и обилие предложений VPS, многие все еще сидят на виртуальных хостингах. Я не исключение. Раньше меня останавливали ценники на услуги dedecated или colocation. Потом эти услуги значительно упали в цене и появились еще более дешевые – VPS. Но меня все равно останавливали неведомые силы и я продолжал ютиться на виртуалке. Наверное, просто не было веских причин для смены площадки. Я вообще очень консервативен в таких вопросах.</p>
<p>Но пришел момент, когда меня утомило то, что сайты разбросаны по разным аккаунтам и разным хостингам. Захотелось иметь возможность использовать сервера кэширования, сервер баз данных последней стабильной версии, а также несколько библиотек для PHP и Python, которых нет на виртуалках. Не могу сказать, что всего этого хотел очень сильно, но мотивация появилась и я решил съехать на VPS.</p>
<p>Сразу скажу, что я никогда не администрировал сервера сколько-нибудь серьезно. Я вообще их не администрировал, не считая смешного опыта где-то там, на заре своей карьеры. Уровень познания Linux можно назвать «слабенький пользователь». То есть, если оставить меня один на один с linux’ом, я не впаду в панику и таки добьюсь того, что требуется, но проведу долбанную кучу времени за чтением манов.</p>
<p><span id="more-646"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>И так, учитывая уровень моих познаний, вы можете сделать вывод – читать дальше или нет. Писал исключительно для тех, кто настолько же просвещен, как я. Остальным будет не интересно или даже вредно для здоровья.</p>
<p>Насколько я прав в своей статья, я не знаю. Но то, что я собрал – работает и меня это радует. Значит можно будет двигаться дальше. Если вас такой расклад устраивает, то милости прошу к прочтению.</p>
<p>Также замечу, что собирать я буду некоторое подобие виртуального хостинга. То есть на VPS будет ютиться n-ое количество сайтов, с возможностью заведения FTP, например, для каких-нибудь посторонних людей. Про посторонних людей, я немного погорячился, наверное, так как и апач и nginx всегда будут запускаться от одного пользователя. Но это можно будет поправить патчами.</p>
<h2>Сборка сервера Apache + Nginx + MySQL + PHP + ProFTPD</h2>
<p>И так, в качестве ОС я выбрал Debian, как достаточно популярный, как мне кажется, дистрибутив и, что немаловажно, наиболее простой для меня. В Debian все ставится из репозитария, где лежат стабильные версии, хотя порой несколько устаревшие. К слову, сначала я попробовал собрать весь комплект из исходников и даже собрал. Но потом случился какой-то затык, уже не помню с чем и я на своем опыте убедился, что сбор из исходников это не «Debian way». Забросил эту идею и все переделал по уму.</p>
<p>VPS я взял у <a href="http://clodo.ru/r5091" target="_blank" rel="external nofollow">Clodo</a>. Есть недельный Moneyback. Недели тестового периода как раз хватит для того, чтобы понять, что получается из всей этой затеи и стоит ли продолжать. Ценник меня тоже вполне устроил:  512 памяти и 10гб HDD обойдутся в туже сумму, что мне сейчас обходится два аккаунта на виртуальном хостинге. То есть, с финансовой точки зрения, я даже сэкономлю рублей 200, если перенесу все сайты на VPS. Сумасшедшая сумма, конечно.</p>
<p>Версия Debian 6-64 bits. Все остальное, как я уже говорил, ставил из репозитариев, поэтому с версиями особо не напрягался.</p>
<p>Вся установка ведется от <tt>root</tt> пользователя и на совершенно чистую систему.</p>
<h2>Устанавливаем Apache 2</h2>
<p>Сначала просто поставим Apache. Настройку и конфигурирование оставим на потом.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> apache2</pre></div></div>

<p>Если все установилось нормально, то обратившись по ip адресу сервера, мы увидим страницы приветствия Apache.</p>
<h2>Установка Nginx</h2>
<p>На текущий момент, в репозитарии Debian лежит версия 0.7.67. Старова-то, конечно, но ничего не поделаешь. В Backports лежит тоже самое, а собирать из исходников я не стал. Как можно убедиться из многочисленных обсуждений на форумах, это не &#8220;Debian way&#8221;. Можно было бы попробовать собрать свой deb пакет, но что-то я пока морально не готов к этому. В общем, ставим из репозитария то, что предлагают.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> nginx</pre></div></div>

<h2>Устанавливаем MySQL сервер</h2>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> mysql-server</pre></div></div>

<p>Конфигурировать пока тоже ничего не будем. Единственное, что потребуется – задать пароль для root пользователя. Не оставляйте пароль пустой строкой.</p>
<h2>Устанавливаем PHP</h2>
<p>Перед тем, как приступить к установке, можете проверить, какая версия PHP присутствует в репозитарии. Это можно сделать командой</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-cache</span> policy php5</pre></div></div>

<p>Если вас все устраивает, то ставим</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5 php-pear
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-mysql <span style="color: #666666; font-style: italic;"># ставим пакет для работы php с mysql</span>
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-suhosin <span style="color: #666666; font-style: italic;"># патчим php, повышая его безопасность, хотя он мог установиться сразу с php</span></pre></div></div>

<h2>Небольшая настройка</h2>
<p>Еще немного ПО для удобства работы. Я поставил Midnight Commander, чтобы было удобнее осуществлять навигацию по файловой системе.<br />
Теперь приступаем к настройке всего, что поставили.</p>
<p>Мне нравится, когда файлы всех виртуальных хостов лежат в поддиректориях домашней директории какого-нибудь пользователя. Привычка такая, наверное. Плюс можно будет сделать скрипт, который автоматизирует процесс создания виртуальных хостов, если их у вас будет много. Если вас не смущает такая политика, то предлагаю добавить в систему пользователя и задать ему пароль:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">useradd omm <span style="color: #660033;">-d</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm <span style="color: #660033;">-m</span> <span style="color: #666666; font-style: italic;"># omm замените на желаемое вами имя пользователя, но у меня оно такое</span>
<span style="color: #c20cb9; font-weight: bold;">passwd</span> omm</pre></div></div>

<p>Ключ –d задает путь к домашней директории пользователя, а -m говорит о том, что эту директорию нужно создать.<br />
Все пути, связанные с домашней директорией пользователя, я буду указывать с учетом имени omm, вам же следует подставлять имя своего пользователя.<br />
Виртуальные хосты я буду складывать в /home/omm/www.  Туда же будут ходить отдельные FTP пользователи, каждый в свою поддиректорию внутри www.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm<span style="color: #000000; font-weight: bold;">/</span>www <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> omm:omm <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm</pre></div></div>

<p>Если хотите другую версию PHP, то можно поискать репозитарии, в которых она есть, добавить их и ставить оттуда.</p>
<h2>Установка FTP сервера ProFTPD </h2>
<p>Я также хочу поднять FTP сервер. Почитал несколько разных статей и решил, что поставлю Proftpd. Замечу, что во время установки лучше выбрать режим standalone (не лучше, но диктуется обстоятельствами), так как в Debian нет демона inеtd (есть xinetd).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> proftpd</pre></div></div>

<p>Теперь нужно конфигурировать FTP сервер. Для этого открываем в редакторе файл /etc/proftpd/proftpd.conf<br />
Расскомментируем директиву DefaultRoot и меняем ее значение. Также снимаем комментарий с директивы RequireValidShell.</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">DefaultRoot                     /home/omm/www #выше этой директории ни один пользователь не поднимется</pre></div></div>

<p>Если у вас таки будет полноценный виртуальный хостинг, то лучше оставить значение по-умолчанию. Тогда для каждого пользователя домашней директорией будет его домашняя директория.</p>
<p>Где-нибудь после директивы DeferWelcome добавялем</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">RootLogin                       off</pre></div></div>

<p>Это запретит подключение по FTP под учетной записью root.</p>
<p>Также добавим ведение еще одного лога, у которого будет понятный для чтения формат. Для этого, после директивы SystemLog пишем:</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">LogFormat custom &quot;%t [pid %P] [%u] ip: %a %m %f [%b b for %T seconds]&quot;
ExtendedLog /var/log/proftpd/transfer.log</pre></div></div>

<p>Я обычно увеличиваю таймауты на простой FTP соединения. Но это по вкусу. Сохраняем изменения.</p>
<p>В конец конфига добавляем строку</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">Include /etc/proftpd/rules/*</pre></div></div>

<p>Следом создаем эту директорию и первый файл конфига в ней</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">mkdir /etc/proftpd/rules &amp;&amp; touch /etc/proftpd/rules/omm</pre></div></div>

<p>Открываем файл omm и пишем туда конфиг, который позволит пользователю omm видеть/изменять все, что в этой директории и ниже. То есть, у нас получается что-то типа главного ftp пользователя. Это удобно, но не очень безопасно. Если у вас сопрут пароль от этого пользователя, то смогут одним махом побить файлы на всех сайтах.</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">&lt;directory /home/omm/www&gt;
        &lt;limit READ WRITE DIRS&gt;
                 Order allow,deny
                 AllowUser omm
                 DenyAll
         &lt;/limit&gt;
&lt;/directory&gt;</pre></div></div>

<p>Проверяем файл конфига на наличие ошибок и если все хорошо, перезапускаем ftp сервер.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">proftpd <span style="color: #660033;">-td5</span>
<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>proftpd restart</pre></div></div>

<p>Если ошибок в файле конфига допущено не было, то сервер перезагрузится в штатном режиме. Осталось только открыть ваш FTP клиент и проверить, все ли работает.</p>
<p>Не охота забегать вперед, но все же напишу немного о том, как создавать виртуальных ftp пользователей.</p>
<p>Сначала создадим директорию внутри нашей www, которая якобы будет корневой директорией для одного из сайтов</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> ~omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru</pre></div></div>

<p>Создаем виртуального FTP пользователя testru и указываем созданную директорию как его домашнюю. Используем утилиту ftpasswd c необходимыми параметрами:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ftpasswd <span style="color: #660033;">--passwd</span> <span style="color: #660033;">--file</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd <span style="color: #660033;">--name</span>=testru <span style="color: #660033;">--shell</span>=<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span> <span style="color: #660033;">--home</span>=<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru <span style="color: #660033;">--uid</span>=<span style="color: #000000;">1001</span> <span style="color: #660033;">--gid</span>=<span style="color: #000000;">1002</span>
ftpasswd <span style="color: #660033;">--group</span> <span style="color: #660033;">--file</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.group <span style="color: #660033;">--name</span>=proudprods <span style="color: #660033;">-m</span> testru <span style="color: #660033;">-gid</span>=<span style="color: #000000;">1002</span>
<span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">644</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.group
<span style="color: #c20cb9; font-weight: bold;">chown</span> proftpd:nogroup <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.passwd <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>proftpd<span style="color: #000000; font-weight: bold;">/</span>ftpd.group</pre></div></div>

<p>Обратите внимание на uid и gid. Я указал id своего пользователя omm и его группы, так как все файлы будут лежать ниже его домашней директории.</p>
<p>Теперь снова открываем конфиг /etc/proftpd/proftpd.conf и добавляем еще две директивы. Как нетрудно догадаться, они указывают пути для файлов с данными виртуальных пользователей и групп.</p>

<div class="wp_syntax"><div class="code"><pre class="config" style="font-family:monospace;">AuthUserFile                    /etc/proftpd/ftpd.passwd
AuthGroupFile                   /etc/proftpd/ftpd.group</pre></div></div>

<p>Делаем рестарт сервера и пробуем залогиниться под созданным виртуальным пользователем. Должно все работать правильно.</p>
<p>Чтобы теперь добавить нового виртуального пользователя используем туже команду, что и раньше, только без параметра &#8211;file, например:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ftpasswd <span style="color: #660033;">--passwd</span> <span style="color: #660033;">--name</span> testru <span style="color: #660033;">--home</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru <span style="color: #660033;">--shell</span>=<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">false</span> <span style="color: #660033;">--uid</span>=<span style="color: #000000;">1001</span> <span style="color: #660033;">--gid</span>=<span style="color: #000000;">1002</span></pre></div></div>

<h2>Настройка Apache</h2>
<p>Открываем /etc/apache2/ports.conf и в значении директивы NameVirtualHost звездочку заменяем на 127.0.0.1:8080, тоже самое пишем для директивы Listen:</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;"><span style="color: #00007f;">NameVirtualHost</span> 127.0.0.1:<span style="color: #ff0000;">8080</span>
<span style="color: #00007f;">Listen</span> 127.0.0.1:<span style="color: #ff0000;">8080</span></pre></div></div>

<p>Мы перевесили Apache на порт 8080 и сделали его недоступным напрямую. Рестартим Apache и смотрим поцепился ли он на 127.0.0.1:8080</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 restart <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">netstat</span> <span style="color: #660033;">-anp</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> LISTEN <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">grep</span> apache2</pre></div></div>

<p>Теперь нужно создать конфиги виртуальных хостов для каждого вашего домена или поддомена. Скажу лишь только то, что для каждого хоста нужно создавать отдельный конфиг в директории /etc/apache2/sites-available</p>
<p>Там уже есть два конфига, на примере которых вы можете создать свои. Я не стану описывать синтаксис, так как ничего сложного там нет. Приведу лишь подправленный мною default, который я переписал на работу с /home/omm/www/test_ru. Имя хоста не прописывал ввиду того, что у меня пока нет доменов, привязанных к настраиваемому VPS, следовательно тестить буду по IP адресу сервера.</p>
<p>Содержимое /etc/apache2/sites-available/default</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">&lt;<span style="color: #000000; font-weight:bold;">VirtualHost</span> 127.0.0.1:<span style="color: #ff0000;">8080</span>&gt;
        <span style="color: #00007f;">ServerAdmin</span> webmaster@localhost
&nbsp;
        <span style="color: #00007f;">DocumentRoot</span> /home/omm/www/test_ru/
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> /&gt;
                <span style="color: #00007f;">Options</span> <span style="color: #0000ff;">FollowSymLinks</span>
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> /home/omm/www/test_ru&gt;
                <span style="color: #00007f;">Options</span> <span style="color: #0000ff;">Indexes</span> <span style="color: #0000ff;">FollowSymLinks</span> MultiViews
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
                <span style="color: #00007f;">allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
        <span style="color: #00007f;">ScriptAlias</span> /cgi-bin/ /usr/lib/cgi-bin/
        &lt;<span style="color: #000000; font-weight:bold;">Directory</span> <span style="color: #7f007f;">&quot;/usr/lib/cgi-bin&quot;</span>&gt;
                <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
                <span style="color: #00007f;">Options</span> +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                <span style="color: #00007f;">Order</span> <span style="color: #00007f;">allow</span>,<span style="color: #00007f;">deny</span>
                <span style="color: #00007f;">Allow</span> from <span style="color: #0000ff;">all</span>
        &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
        <span style="color: #00007f;">ErrorLog</span> ${APACHE_LOG_DIR}/error.log
&nbsp;
        <span style="color: #adadad; font-style: italic;"># Possible values include: debug, info, notice, warn, error, crit,</span>
        <span style="color: #adadad; font-style: italic;"># alert, emerg.</span>
        <span style="color: #00007f;">LogLevel</span> warn
&nbsp;
        <span style="color: #00007f;">CustomLog</span> ${APACHE_LOG_DIR}/access.log combined
&nbsp;
    <span style="color: #00007f;">Alias</span> /doc/ <span style="color: #7f007f;">&quot;/usr/share/doc/&quot;</span>
    &lt;<span style="color: #000000; font-weight:bold;">Directory</span> <span style="color: #7f007f;">&quot;/usr/share/doc/&quot;</span>&gt;
        <span style="color: #00007f;">Options</span> <span style="color: #0000ff;">Indexes</span> MultiViews <span style="color: #0000ff;">FollowSymLinks</span>
        <span style="color: #00007f;">AllowOverride</span> <span style="color: #0000ff;">None</span>
        <span style="color: #00007f;">Order</span> <span style="color: #00007f;">deny</span>,<span style="color: #00007f;">allow</span>
        <span style="color: #00007f;">Deny</span> from <span style="color: #0000ff;">all</span>
        <span style="color: #00007f;">Allow</span> from 127.0.0.0/255.0.0.0 ::<span style="color: #ff0000;">1</span>/<span style="color: #ff0000;">128</span>
    &lt;/<span style="color: #000000; font-weight:bold;">Directory</span>&gt;
&nbsp;
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</pre></div></div>

<p>Директории, которые указаны в конфиге виртуального хоста должны существовать. Если все сделали, выполняем команду</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">a2ensite default <span style="color: #666666; font-style: italic;"># default – имя файла конфига</span></pre></div></div>

<p>Выполнение данной команды создаст ссылку на файл конфига в директории sites-enabled.</p>
<p>Перечитываем конфиги apache</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 reload</pre></div></div>

<p>Создаем файл и пишем в него что-нибудь</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">touch</span> ~omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru<span style="color: #000000; font-weight: bold;">/</span>index.html <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #c20cb9; font-weight: bold;">nano</span> ~omm<span style="color: #000000; font-weight: bold;">/</span>www<span style="color: #000000; font-weight: bold;">/</span>test_ru<span style="color: #000000; font-weight: bold;">/</span>index.html</pre></div></div>

<p>Теперь обращаемся к вашему серверу по IP адресу и если видим строку, которую вписали в файл index.html, то радуемся. Если не видим, то расстраиваемся и думаем, где накосячили.</p>
<h2>Настройка Nginx</h2>
<p>Теперь можно запустить Nginx. Если он нормально поцепился на 80 порт, то при обращении к серверу по ip мы должны увидеть страницу приветствия Nginx.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>nginx start</pre></div></div>

<p>Открываем конфиг /etc/nginx/nginx.conf и в секцию http, перед  директивами include, описываепроксирующий сервер с помощью модуля <a href="http://sysoev.ru/nginx/docs/http/ngx_http_upstream.html" target="_blank" rel="external nofollow">upstream</a></p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">http {
    <span style="color: #adadad; font-style: italic;"># …</span>
    upstream backend {
        server 127.0.0.1:<span style="color: #ff0000;">8080</span>;
    }
&nbsp;
    <span style="color: #00007f;">include</span> /etc/nginx/conf.d/*.conf;
    <span style="color: #00007f;">include</span> /etc/nginx/sites-enabled/*;
}</pre></div></div>

<p>Теперь открываем конфиг /etc/nginx/sites-available/default и приводим его к следующему виду</p>

<div class="wp_syntax"><div class="code"><pre class="apache" style="font-family:monospace;">server {
         <span style="color: #00007f;">listen</span> <span style="color: #ff0000;">80</span>;
         server_name localhost;
&nbsp;
         location ~* ^.+\.(jpg|jpeg|gif|png|svg|js|css|mp3|ogg|mpe?g|avi|zip|gz|bz2?|rar)$ {
                root /home/omm/www/test_ru;
         }
&nbsp;
         location / {
                proxy_pass http://backend;
                proxy_redirect <span style="color: #0000ff;">off</span>;
                proxy_set_header Host   $host;
                proxy_set_header X-Real-IP      $remote_addr;
&nbsp;
                charset utf-<span style="color: #ff0000;">8</span>;
                index test.php index.html;
                root /home/omm/www/ test_ru;
         }
 }</pre></div></div>

<p>Перезапускаем сервер. Пробуем запрашивать статику и скрипты. Смотрим access логи apache и nginx, по которым будет видно, какие запросы и куда уходят.</p>
<p>Теперь статика будет отдаваться через nginx, а все остальное уйдет на проксирующий apache.</p>
<h2>Настрайка MySQL</h2>
<p>Запускаем mysql_secure_installation и следуем всем инструкциям и отвечаем на все вопросы, которые нам зададут.</p>
<p>Так как пароль для root мы уже задали при установке, то сейчас потребуется его ввести и на следующий вопрос о смене пароля можно ответить «нет»<br />
На все последующие вопросы отвечаем утвердительно. Это максимально правильно и безопасно. В описание к фонфигуратору говорится, что они только для тестовых запусков сервера и никак не для продакшена.</p>
<p>На этом настройка окончена :)</p>
<h2>Настройка PHP</h2>
<p>Настраивать, на самом деле, нечего. PHP и так уже работает. Вы можете поковырять /etc/php5/apache2/php.ini, если знаете, что там и к чему. Если не знаете, очень советую узнать.<br />
Не забывайте, что после изменений в php.ini, нужно перезапускать апач, чтобы они вступили в силу.</p>
<p>Пока можете потестировать работу PHP с MySQL, например.</p>
<h2>В заключении</h2>
<p>Файлы, которые мы создавали в директории ~omm/www/test_ru/ нужно удалить от root пользователя, так как мы от него их и создавали (во всяком случае, я создавал от root) и по FTP они доступны только для чтения.</p>
<p>Теперь весь этот огород осталось настроить для оптимальной работы. Отключить не нужное, правильно сконфигурировать необходимое, установить по, которого не хватает, но очень хочется, например Memcached и eAccelerator. Не забывайте, что это VPS, а не виртуальный хостинг и теперь вы можете вытворять все, что вашей душе угодно. Собственно, к чему и шли.</p>
<p>Еще можно поставить phpMyAdmin для удобства работы с БД, поднять свой DNS и все остальное. Но это по желанию. </p>
<p>Если вы все это делаете впервые, то самым правильным решением будет попытаться написать bash скрипт, который автоматизирует процесс создания хостов, перезапуска серверов и прочего. И дело полезное сделаете и знания полученные закрепите. Если я таки найду время набросать пару скриптов, выложу их здесь.</p>
<p>Еще настоятельно рекомендую почитать документацию по Nginx и Apache, особенную ту ее часть, где описывается правильное конфигурирование виртуальных хостов.</p>
<p>Собственно, на этом все.</p>
<p>P.S: Совершенно не факт, что я все делал правильно, поэтому, если вам есть что сказать или вы можете указать на мои конкретные ошибки, пишите в комментариях. Спасибо.</p>
<h2>Тестируем на нагрузку</h2>
<p>Как только весь этот зоопарк заработал, я решил проверить сервер на нагрузку и сравнить результаты с тестом того же сайта, но на виртуальном хостинге. Тестировалось через бесплатный аккаунт на <a href="http://loadimpact.com/" target="_blank" rel="external nofollow">loadimpact.com</a>.</p>
<h3>Тест на VPS</h3>
<p><img style="border: #666 1px solid" src="/wp-content/uploads/2011/08/vps_test.png" alt="" title="vps_test" width="547" height="537" class="aligncenter size-full wp-image-658" /></p>
<h3>Тест на Sweb.ru</h3>
<p><img style="border: #666 1px solid"  src="http://inroot.ru/wp-content/uploads/2011/08/sweb_test.png" alt="" title="sweb_test" width="541" height="540" class="aligncenter size-full wp-image-661" /></p>
<p>Я думаю, что разница очевидна и можно обойтись без лишних слов. VPS и глазом не моргнул. Ну а реакция виртуального хостинга вполне ожидаема и, нужно отдать должно, положительно удивила меня. Я думал, что все будет значительно хуже.</p>
<p>Также предлагаю ознакомиться с графиками из панели управления VPS. По ним вы можете судить о том, как сервер реагировал на возрастающую нагрузку.</p>
<div class="aligncenter">
<img style="border: #666 1px solid" src="http://inroot.ru/wp-content/uploads/2011/08/stats_cpu.png" alt="" title="stats_cpu" width="662" height="183" class="aligncenter size-full wp-image-662" /></p>
<p><img style="border: #666 1px solid" src="http://inroot.ru/wp-content/uploads/2011/08/stats_ram.png" alt="" title="stats_ram" width="674" height="183" class="aligncenter size-full wp-image-665" /></p>
<p><img style="border: #666 1px solid" src="http://inroot.ru/wp-content/uploads/2011/08/stats_hdd.png" alt="" title="stats_hdd" width="680" height="189" class="aligncenter size-full wp-image-666" />
</div>
<blockquote><p><strong>UPD:</strong><br />
А вот и <a href="/2011-08/bash-script-virtual-hosts-apache-nginx.html">bash скрипт создания виртуальных хостов</a>, как и обещал. Надеюсь, он поможет вам написать собственный, в разы более функциональный и удобный.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-08/linux-server-apache-nginx-mysql-php-proftpd.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress и кириллические домены</title>
		<link>http://inroot.ru/2011-08/wordpress-and-cyrillic-domains.html</link>
		<comments>http://inroot.ru/2011-08/wordpress-and-cyrillic-domains.html#comments</comments>
		<pubDate>Thu, 25 Aug 2011 02:38:54 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=638</guid>
		<description><![CDATA[Случилось мне ставить WordPress на сайт с кириллическим доменом. Сначала я перенес все с локальном машины, должным образом подправил в базе конфиг, но нет. Часть функций админки банально не работала. Не работали элементы интерфейса, реализованные на JavaScript, в том числе формы, данные из которых отправлялись через ajax. Переустановил движок уже по-человечески. Картина аналогична. В первую [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="http://inroot.ru/wp-content/uploads/2011/08/wp_logo-150x150.jpg" alt="" title="wp_logo" width="150" height="150" class="aligncenter size-thumbnail wp-image-639" /></p>
<p>Случилось мне ставить WordPress на сайт с кириллическим доменом. Сначала я перенес все с локальном машины, должным образом подправил в базе конфиг, но нет. Часть функций админки банально не работала. Не работали элементы интерфейса, реализованные на JavaScript, в том числе формы, данные из которых отправлялись через ajax.</p>
<p>Переустановил движок уже по-человечески. Картина аналогична.</p>
<p>В первую очередь не работало управление виджетами меню. Меню можно было создать, но добавить в него страницы &#8211; нет. Данные просто не сохранялись в базу, а скрипт подвисал. Совершенно случайно выяснилось, что  управление меню работает в FireFox. Но потом не менее случайно выяснилось и то, что в FireFox не работает загрузка файлов через flash-загрузчик, зато она прекрасно работает в Opera.</p>
<p><span id="more-638"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Вот так, худо-бедно, но я таки слепил работающий сайт. Не думаю, что мне удалось выявить все проблемы, вызванные несовместимостью <strong>WordPress с кириллическим доменом</strong>, но теперь вы знаете, где искать выход :)</p>
<p>В общем-то, все это не решение проблемы, как такое, а способ ее игнорировать, пусть и не самый удобный. Для сайта, который часто обновляется, это не выход, наверное. Но я делал промо-сайт и меня такой расклад вполне устраивает. Надеюсь, что в следующих версиях WordPress все эти досадные баги будут исправлены. Ну а мораль остается прежней – кириллические домены плохая затея во всех отношениях.</p>
<p>P.S: В IETester, для IE7 невозможно открыть сайт по кириллическому домену. </p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-08/wordpress-and-cyrillic-domains.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Функциональный каталог на WordPress + Magic Fields. Часть 1</title>
		<link>http://inroot.ru/2011-07/funktsionalnyy_katalog_na_wordpress_magic_fields_1.html</link>
		<comments>http://inroot.ru/2011-07/funktsionalnyy_katalog_na_wordpress_magic_fields_1.html#comments</comments>
		<pubDate>Sun, 24 Jul 2011 06:27:23 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[плагин Magic Fields]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=607</guid>
		<description><![CDATA[Небольшое лирическое отступление. До недавнего времени, я не относился к WordPress серьезно. Ничего, кроме хорошего и популярного блогового движка я в нем не замечал. Что касается плагинов, то мне даже в голову не приходило, что среди них есть не просто «вкусные плюшки», но и весьма серьезные разработки, которые превращают WordPress в действительно мощный движок, способный [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="/wp-content/uploads/2011/07/magic_fields_l-150x150.png" alt="WordPress + Magic Fields. Часть 1" title="magic_fields_l" width="150" height="150" class="aligncenter size-thumbnail wp-image-631" /></p>
<p>Небольшое лирическое отступление.</p>
<p>До недавнего времени, я не относился к WordPress серьезно. Ничего, кроме хорошего и популярного блогового движка я в нем не замечал. Что касается плагинов, то мне даже в голову не приходило, что среди них есть не просто «вкусные плюшки», но и весьма серьезные разработки, которые превращают WordPress в действительно мощный движок, способный на значительно большее, нежели типовой блог.</p>
<p>В число таких плагинов входит Magic Fields, возможностям которого посвящена данная заметка.</p>
<p>Нельзя сказать, что <strong>плагин Magic Fields</strong> очень сложен в использовании. Все достаточно просто и интуитивно понятно, но, по какой-то причине, мало кто осознает всю широту возможностей <strong>Magic Fields</strong>. Обычно, его используют как несколько более удобную альтернативу стандартным произвольным полям. Но это не серьезно…</p>
<p><span id="more-607"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>И так, что можно сделать с помощью этого плагина? Я узнал о нем, когда мне понадобилось превратить одну из категорий блога в полноценный каталог. Где-то пару месяцев назад я заинтересовался разработкой приложений под Google Android. Так как большого количества свободного времени нет, решил для начала замутить скромненький блог об этой ос и обо всем, что с ней связано и интересно, прежде всего, мне самому. В общем-то сразу пришла мысль сделать каталог гаджетов (смартфоны, планшетники), которые работают на Android.<br />
Что должно входить в число функциональных возможностей каталога? Безусловно, нужны сортировки и фильтры по каким-либо параметрам позиций каталога. Также форма поиска, для быстрого доступа к конкретным позициям. Сразу становится очевидно, что базовых возможностей WorPress будет недостаточно.</p>
<p>Рекомендую устанавливать Magic Fields из репозитария WordPress. Таким образом вы обеспечите себе работу с последней версией приложения.</p>
<p>Непосредственно у самого плагина нет никаких настроек. Сразу после установки Magic Fields можно переходить к созданию списка дополнительных полей. Делается это на странице плагина, попасть на которую можно из левого меню панели управления WordPress.</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_main_page.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_main_page.jpg" alt="" title="Magic_Fields_main_page" width="550" class="aligncenter wp-image-611" /></a></p>
<p>Как видно из скриншота, набор полей можно импортировать, например, если он уже был создан предварительно. Это очень удобно, допустим, если вы делаете сайты в массовом порядке и все они должны содержать однотипный каталог, как то рубрикатор интернет-магазина.<br />
Для создания нового набора полей предназначена кнопка «+ Create Write Panel».</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_create_write_panel.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_create_write_panel.jpg" alt="" title="Magic_Fields_create_write_panel" width="550" class="aligncenter wp-image-613" /></a></p>
<p>На очередном скриншоте вы можете видеть форму создания набора дополнительных полей. Чтобы вам было понятнее, что означает часть настроек, забегая немного вперед, я поясню основной принцип работы плагина Magic Fields.</p>
<p>И так, в параметре Placement вы задаете для публикаций какого-типа будет работать данная группа полей. Как видно из скриншота, это могут быть либо обычные посты блога, либо страницы. Также вам необходимо выбрать категории. После создания группы, в левом меню админки WP появится еще один блок, имя которого будет соотвествовать имени группы полей. Примерно вот так:</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_menu_block.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_menu_block.jpg" alt="" title="Magic_Fields_menu_block" width="148" height="83" class="aligncenter size-full wp-image-616" /></a></p>
<p>Тыркнув на «New», вы попадете на страницу с привычной формой публикации постов (или страниц) блога, но с дополнительными кнопками и блоками. Иначе говоря, <strong>плагин Magic Fields</strong> создает альтернативную форму для публикации новостей и снабжает ее дополнительными возможностями.</p>
<p>Собственно, различные настройки на странице создания группы полей, как раз таки позволяют определить, какие из стандартных возможностей формы WordPress мы желаем оставить, а какие следует убрать. Например, в блоке Advanced Fields логично снять галочку с чекбокса Сustom Fields, так как именно для их замены мы поставили плагин. В Standard Fields я отключал вывод списка категорий (чекбокс Categories), потому, что мне дополнительные поля требовались только для категории  с устройствами и выбирать попросту было нечего.</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_main_page_1.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_main_page_1.jpg" alt="" title="Magic_Fields_main_page_1" width="550" class="aligncenter wp-image-617" /></a></p>
<p>Созданная группа появляется в списке и пригодна для добавления в нее полей.</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_fields_list.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_fields_list.jpg" alt="" title="Magic_Fields_fields_list" width="550" class="aligncenter wp-image-619" /></a></p>
<p>Список полей пуст, поэтому сразу приступаем к созданию нового поля. Для этого жмем «+ Create a Field»</p>
<p>Делать скриншот формы я не буду. Там все понятно и без лишних комментариев. Отмечу только, что поле «Name» должно содержать уникальный (в рамках набора полей) идентификатор для создаваемого поля. Именно по этому идентификатору вы сможете выводить поля в шаблоне, сортировать и искать публикации.</p>
<p>Я создал два поля типа <em>Dropdown List</em> – это обычный Select.</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_fields_list_1.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_fields_list_1.jpg" alt="" title="Magic_Fields_fields_list_1" width="550" class="aligncenter wp-image-620" /></a></p>
<p>Теперь давайте посмотрим, как будет выглядеть форма для добавления постов, а именно, наши дополнительные поля.</p>
<p><a rel="lightbox" target="_blank" href="/wp-content/uploads/2011/07/Magic_Fields_new_post.jpg"><img src="/wp-content/uploads/2011/07/Magic_Fields_new_post.jpg" alt="" title="Magic_Fields_new_post" width="550" class="aligncenter wp-image-622" /></a></p>
<p>Собственно, как вы можете наблюдать, все достаточно просто и очень удобно. Работа с таким представлением полей намного приятнее, нежели с их родным аналогом. Учитывая обилие типов полей, которые предлагает <strong>плагин Magic Fields</strong>, скорее всего, можно будет решить практически любую задачу.</p>
<p>Ну а теперь пример того, как вывести значение дополнительного поля в шаблоне.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>in_category<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;table&gt;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$device_producer</span> <span style="color: #339933;">=</span> get<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'device_producer'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$device_producer</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;tr&gt;
		&lt;th&gt;&lt;span&gt;Производитель&lt;/span&gt;&lt;/th&gt;
		&lt;td&gt;&lt;a href=&quot;/c/devices/?device_producer=<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$device_producer</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$device_producer</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;&lt;/td&gt;
	&lt;/tr&gt;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$device_os</span> <span style="color: #339933;">=</span> get<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'device_os'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$device_os</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;tr&gt;
		&lt;th&gt;&lt;span&gt;Операционная система&lt;/span&gt;&lt;/th&gt;
		&lt;td&gt;&lt;a href=&quot;/c/devices/?device_os=<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$device_os</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$device_os</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;&lt;/td&gt;
	&lt;/tr&gt;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;/table&gt;
<span style="color: #000000; font-weight: bold;">&lt;?</span> <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Вот такой код я использую в шаблоне вывода одиночной записи блога. Первый условный оператор IF осуществляет проверку принадлежности записи к той категории, для которой я создавал дополнительные поля. В других категориях рисование таблицы не актуально.</p>
<p>Чтобы видеть, как все это работает, можете посмотреть любую публикацию с этой страницы <a href="http://iamdroid.ru/c/devices">http://iamdroid.ru/c/devices</a>. Это тот самый каталог мобильных устройств, о котором я говорил в начале.</p>
<p>Во второй части заметки я расскажу о том, как сделать форму поиска по каталогу и фильтрацию по значениям отдельных полей.</p>
<p><strong>UPD 10.09.11</strong>: продолжение темы &#8211; <a href="/2011-09/poisk_i_filtry_dlja_kataloga_na_wordpress_magic_fields_2.html">Поиск и фильтры для каталога на WordPress + Magic Fields. Часть 2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-07/funktsionalnyy_katalog_na_wordpress_magic_fields_1.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Двойной CSS background</title>
		<link>http://inroot.ru/2011-07/dual-css-background-hack.html</link>
		<comments>http://inroot.ru/2011-07/dual-css-background-hack.html#comments</comments>
		<pubDate>Sun, 03 Jul 2011 16:25:52 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CSS/xHTML]]></category>
		<category><![CDATA[CSS background]]></category>
		<category><![CDATA[CSS tricks]]></category>
		<category><![CDATA[CSS хаки]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=579</guid>
		<description><![CDATA[Работая над одним из проектов, я столкнулся с необходимостью задать одновременно два фоновых изображения для страницы. Этого требовал макет дизайна, в котором левая и правая половины страницы имели разные бэкграунды. Спецификация CC3 поддерживает такую возможность, но, увы, даже в наше время активного развития WEB, далеко не все браузеры полноценно поддерживают 3-ю версию CSS. А хотелось [...]]]></description>
			<content:encoded><![CDATA[<p>Работая над одним из проектов, я столкнулся с необходимостью задать одновременно два фоновых изображения для страницы. Этого требовал макет дизайна, в котором левая и правая половины страницы имели разные бэкграунды.</p>
<p>Спецификация CC3 поддерживает такую возможность, но, увы, даже в наше время активного развития WEB, далеко не все браузеры полноценно поддерживают 3-ю версию CSS. А хотелось бы, конечно, найти кросс-браузерное решение, доступное даже таким мамонтам, как, например, Internet Explorer 7.</p>
<p>Вариант с вырезанием одного большого фонового изображения никак не подходит. Во-первых, это совсем плохая идея, особенно если можно обойтись без таких радикальных мер, во-вторых, требовалось, чтобы фон заполнял страницу по ширине при любом экранном разрешении.</p>
<p><span id="more-579"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Конечно, хотелось бы найти решение, не требующее дополнительной HTML разметки, но в итоге оказалось, что без этого не обойтись. Все же, найденное решение работает и работает хорошо.</p>
<p>Начнем с HTML разметки, которая потребует использования дополнительного контейнера:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;second_bg&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;content&quot;</span>&gt;</span>
        <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;./images/header_image.png&quot;</span> <span style="color: #000066;">alt</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>Дополнительный контейнер имеет ID second_bg. Ниже может идти привычная для вас разметка страницы. Одним из плюсов данного способа является простота его внедрения в уже существующую верстку. Так как дополнительный контейнер позиционируется абсолютно, почти наверняка, его появление в коде не создаст никаких дополнительных трудностей.</p>
<p><strong>CSS для body и #second_bg</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="css" style="font-family:monospace;">body <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">font</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">normal</span> <span style="color: #933;">75%</span> Tahoma<span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#e5e5e5</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'./images/bg_body_0.gif'</span><span style="color: #00AA00;">&#41;</span> <span style="color: #000000; font-weight: bold;">left</span> <span style="color: #000000; font-weight: bold;">top</span> <span style="color: #993333;">repeat-x</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#second_bg</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">96px</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">position</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">absolute</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">top</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">50%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">transparent</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000;">'bg_body_1.gif'</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">repeat-x</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>Если слой с фоном будет перекрывать какой-то элемент, просто задайте этому элементу относительно позиционирование, также можете поиграться с z-index.</p>
<p>Как видно из кода селектора, вся суть в ширине слоя и его позиции в 50% от левого края. Таким образом, достигается нужный нам эффект.</p>
<p>В завершении, предлагаю посмотреть <a href="/files/dual_css_background/" target="blank">рабочий пример</a> и изучить полный код страницы, если это потребуется.</p>
<p><a href="/files/dual_css_background/" target="blank"><img src="http://inroot.ru/wp-content/uploads/2011/07/demo.png" alt="" title="Двойной CSS background - онлайн демо" width="64" height="64" class="alignleft" /></a></p>
<p>За основу была принята вот <a href="http://cherny.com/webdev/11/dual-background-images" target="_blank" rel="nofollow external">эта публикация</a>. Сначала думал сделать перевод, но как-то не сложилось. Тем не менее, копирайт и все такое &#8211; сослаться обязан!</p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-07/dual-css-background-hack.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CodeIgniter 2.0 + HMVC + шаблонизатор Dwoo</title>
		<link>http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html</link>
		<comments>http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html#comments</comments>
		<pubDate>Sat, 28 May 2011 08:14:15 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[Dwoo]]></category>
		<category><![CDATA[HMVC]]></category>
		<category><![CDATA[Модульность CodeIgniter]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=561</guid>
		<description><![CDATA[Хочу рассказать о том, как свести вместе CodeIgniter версии 2.* и две достаточно популярных библиотеки для этого фреймворка: шаблонизатор Dwoo и библиотеку Modular Extensions &#8211; HMVC. Версии ПО: CodeIgniter 2.0.2 Dwoo 1.1.1 CodeIgniter HMVC 5.4 Для начала ставим сам CodeIgniter. Там ничего сложного и нужный эффект достигается путем распаковки файлов. Далее, на чистый CI, ставим [...]]]></description>
			<content:encoded><![CDATA[<p>Хочу рассказать о том, как свести вместе <strong>CodeIgniter</strong> версии 2.* и две достаточно популярных библиотеки для этого фреймворка: <strong>шаблонизатор Dwoo</strong> и библиотеку <strong>Modular Extensions &#8211; HMVC</strong>.</p>
<p>Версии ПО:</p>
<ul>
<li><a rel="nofollow" target="_blank" href="http://codeigniter.com/">CodeIgniter 2.0.2</a></li>
<li><a rel="nofollow" target="_blank" href="http://dwoo.org/">Dwoo 1.1.1</a></li>
<li><a rel="nofollow" target="_blank" href="https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home">CodeIgniter HMVC 5.4</a></li>
</ul>
<p>Для начала ставим сам CodeIgniter. Там ничего сложного и нужный эффект достигается путем распаковки файлов.</p>
<p>Далее, на чистый CI, ставим HMVC. Процесс установки HMVC описан специально для CodeIgniter версии 2.*. Добавить от себя нечего, поэтому привожу перевод официального мануала.<br />
<span id="more-561"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<ol>
<li>Начните с чистым CI</li>
<li>Установите верное значение для $config["base_url"] в файле /application/config/config.php</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
<li>Скопируйте директорию third_party в директорию /application/ (с заменой файлов)</li>
<li>Скопируйте директорию core в директорию /application/ (с заменой файлов)</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
<li>Создайте директорию модуля welcome &#8211; /application/modules/welcome/controllers</li>
<li>Переместите контроллер application/controllers/welcome.php в application/modules/welcome/controllers/welcome.php</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
<li>Создайте директорию /application/modules/welcome/views</li>
<li>Скопируйте файл представления /application/views/welcome_message.php в /application/modules/welcome/views/welcome_message.php</li>
<li>Обратитесь по URL /index.php/welcome. Вы должны увидеть «Welcome to CodeIgniter»</li>
</ol>
<p>Установка завершена.</p>
<p>Несмотря на то, что необходимости в этом нет, я предлагаю сразу создать базовый контроллер, который будем расширять контроллерами модулей. Раз уж мы накатили HMVC, то почему бы не сделать этого.</p>
<p>Создадим файл /application/core/MY_Controller.php c вот таким вот содержимым:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BASEPATH'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> OR <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'No direct script access allowed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* load the MX_Loader class */</span>
<span style="color: #b1b100;">require</span> APPPATH<span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;third_party/MX/Controller.php&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> MY_Controller <span style="color: #000000; font-weight: bold;">extends</span> MX_Controller
<span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        parent<span style="color: #339933;">::</span>__construct<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Теперь в этом классе можно организовать проверку авторизации пользователя, разграничение прав доступа и прочее.  Но в данном конкретном случае он потребуется только для централизованного подключения библиотек, которые должны быть доступны всему приложению, а именно шаблонизатора.</p>
<h2>Устанавливаем шаблонизатор Dwoo</h2>
<ol>
<li>Распаковываем Dwoo/Adapters/CodeIgniter в /application/</li>
<li>Полностью распаковываем библиотеку в /application/libraries/</li>
<li>В файле /application/config/dwootemplate.php  меняем настройки на ваши</li>
</ol>
<p>У меня файл настроек имеет следующее содержание:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">defined</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BASEPATH'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'No direct script access allowed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// The name of the directory where templates are located.</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'template_dir'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../views/'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// The directory where compiled templates are located</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'compileDir'</span><span style="color: #009900;">&#93;</span>   <span style="color: #339933;">=</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../views/__compile/'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//This tells Dwoo whether or not to cache the output of the templates to the $cache_dir.</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'caching'</span><span style="color: #009900;">&#93;</span>      <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cacheDir'</span><span style="color: #009900;">&#93;</span>     <span style="color: #339933;">=</span> <span style="color: #990000;">dirname</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/../views/__cache/'</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$config</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'cacheTime'</span><span style="color: #009900;">&#93;</span>    <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Несмотря на то, что мы используем <strong>HMVC</strong>, которая позволяет для каждого модуля иметь свою директорию views, я предпочитаю все шаблоны хранить в одном месте, поэтому пользуюсь /application/views/, как и задумано изначально в <strong>CodeIgniter</strong>. С учетом этого, я здесь же храню компилированные шаблоны и их кэш. Если у вас иная политика, меняйте настройки в dwootemplate.php на свой вкус.</p>
<p>Теперь небольшие грабли. Увы, адаптер не рассчитан на последние версии CodeIgniter, поэтому библиотека <strong>Dwootemplate</strong> требует напильника. Во-первых, из коробки она просто не работает, так как в методе <tt>Dwootemplate::display()</tt> осуществляется обращение к свойству <tt>Output::$final_output</tt>, которое объявлено с модификатором protected. Для решения проблемы, в файле /application/libraries/Dwootemplate.php ищем строку</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">final_output</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$template</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>И заменяем ее на</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">output</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set_output</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$template</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Также я заменил все строки</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span> <span style="color: #339933;">=</span> get_instance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>на</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$CI</span> <span style="color: #339933;">=</span> CI_Controller<span style="color: #339933;">::</span><span style="color: #004000;">get_instance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>После этого все работает но на самом деле, имеет смысл написать свою обертку для Dwoo. Класс Dwootemplate обладает достаточно скромными возможностями и сгодится лишь для простеньких задач. Правильнее взять его за основу и написать свой, более гибкий и функциональный. Но это уже отдельный разговор.</p>
<p>Осталось все проверить на работоспособность.<br />
Открываем файл /modules/welcome/controllers/welcome.php и заменяем метод <tt>Welcome::index()</tt> на следующий:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> index<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">load</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">library</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Dwootemplate'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dwootemplate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assign</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'itshowlate'</span><span style="color: #339933;">,</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'H:i:s'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dwootemplate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">display</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dwoowelcome.tpl'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>В принципе, мы собрали и подготовили базовый набор для написания практически любого приложения, например, небольшой CMS.</p>
<p>Публикую дистрибутив Dwoo и HMVC. Делаю это для того, чтобы в случае выхода новых версий этих библиотек, статья оставалась актуальной. Тем не менее, само собой, следует использовать последние версии ПО. </p>
<p>Также выкладываю уже патченный /application/libraries/Dwootemplate.php</p>
<blockquote><p>
<strong>Файлы:</strong><br />
<a href='http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/dwoo-1-1-1-tar' rel='attachment wp-att-566'>dwoo-1.1.1.tar</a><br />
<a href='http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/wiredesignz-codeigniter-modular-extensions-hmvc-89f47c3248f7' rel='attachment wp-att-567'>modular-extensions-hmvc</a><br />
<a href='http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/dwootemplate' rel='attachment wp-att-568'>Dwootemplate</a></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-05/codeigniter-2-0-hmvc-and-dwoo.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Sticky Footer &#8211; Прилипающий футер</title>
		<link>http://inroot.ru/2011-05/css-sticky-footer.html</link>
		<comments>http://inroot.ru/2011-05/css-sticky-footer.html#comments</comments>
		<pubDate>Thu, 19 May 2011 20:49:03 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[CSS/xHTML]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=542</guid>
		<description><![CDATA[Есть несколько способов реализовать футер, прилипающий к низу страницы (Sticky Footer), используя свойства CSS. Но многие из них прибегают к громоздким и неудобным хакам, или требуют много дополнительного HTML кода. Описанный здесь метод использует всего 15 строк CCS кода и почти не требует дополнительной HTML разметки. Также он отличается тем, что построен на валидном CSS [...]]]></description>
			<content:encoded><![CDATA[<p>Есть несколько способов реализовать футер, прилипающий к низу страницы (<strong>Sticky Footer</strong>), используя свойства CSS. Но многие из них прибегают к громоздким и неудобным хакам, или требуют много дополнительного HTML кода. Описанный здесь метод использует всего 15 строк CCS кода и почти не требует дополнительной HTML разметки. Также он отличается тем, что построен на валидном CSS коде. И, само собой, работает во всех популярных браузерах (IE5 и старше, FireFox, Safari, Opera и Chrome).</p>
<p>Прежде всего, вы можете посмотреть, как это работает. Здесь находится <a href="/files/sticky_footer/" target="_blank">пример реализации</a> описанного метода. Убедитесь в том, что он валиден и является кроссбраузерным.</p>
<p><span id="more-542"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Добавьте следующий CSS код в вашу таблицу стаилей. При этом обратите внимание, что отрицательное значение margin-bottom равно высоте .footer и .push. Это отрицательное значение должно быть равно полной высоте <strong>footer</strong>, включая какие-либо отступы или border последнего. Если не следовать этому принципу, то появится вертикальная полоса прокрутки. Она появится даже в том случае, если фактически контент будет помещаться на странице.</p>
<p><strong>CSS код:</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="css" style="font-family:monospace;"><span style="color: #00AA00;">*</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
html<span style="color: #00AA00;">,</span> body <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">100%</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #6666ff;">.wrapper</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">min-height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">100%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">auto</span> !important<span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">100%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">margin-bottom</span><span style="color: #00AA00;">:</span> <span style="color: #933;">-80px</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* Отрицательное значение высоты footer'а */</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #6666ff;">.footer</span><span style="color: #00AA00;">,</span> <span style="color: #6666ff;">.push</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">80px</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* .push и .footer должны быть одинаковой высоты */</span>
	<span style="color: #000000; font-weight: bold;">clear</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">both</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p><strong>HTML код</strong> представлен ниже. Весь контент должен содержаться только внутри.wrapper и .footer. Внутри .push также ничего не должно быть, так как этот слой является скрытым элементом, <strong>прижимающим футер</strong>. Разумеется, все это не касаетс я элементов с абсолютным позиционированием. Они могут находиться где-угодно.</p>
<p><strong>HTML код</strong></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;wrapper&quot;</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;header&quot;</span>&gt;</span>
		Header block
	<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
&nbsp;
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>Main content<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;push&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">class</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;footer&quot;</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">p</span>&gt;</span>Footer<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">p</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span></pre></td></tr></table></div>

<p>Учитывая то, что под IE6 верстают все меньше, можно привести селектор .wrapper к такому виду:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.wrapper</span> <span style="color: #00AA00;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">min-height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">100%</span><span style="color: #00AA00;">;</span>
	<span style="color: #000000; font-weight: bold;">margin-bottom</span><span style="color: #00AA00;">:</span> <span style="color: #933;">-80px</span><span style="color: #00AA00;">;</span> <span style="color: #808080; font-style: italic;">/* Отрицательное значение высоты footer'а */</span>
<span style="color: #00AA00;">&#125;</span></pre></td></tr></table></div>

<p>Метод останется рабочим для всех браузеров, кроме IE6 и меньше. Конечно, две строчки кода погоды не делают, но для педантов они могут показаться лишними.</p>
<blockquote><p>
На основе статьи <a href="http://ryanfait.com/resources/footer-stick-to-bottom-of-page/" rel="nofollow">CSS Sticky Footer</a>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-05/css-sticky-footer.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Где на Руси жить хорошо. Пару слов о фрилансе</title>
		<link>http://inroot.ru/2011-05/about-freelance-part-1.html</link>
		<comments>http://inroot.ru/2011-05/about-freelance-part-1.html#comments</comments>
		<pubDate>Tue, 10 May 2011 23:50:26 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Вольнодумье]]></category>
		<category><![CDATA[Freelance]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=532</guid>
		<description><![CDATA[Любой фрилансер, рано или поздно, пишет в свой блог о фрилансе. Это как дань моде или традиция. Я на вольных хлебах уже почти два года и, думаю, что время пришло. Особенно мне есть что сказать, сейчас, когда к моменту сдачи приближаются несколько совершенно разных проектов, каждый из которых принес свой бесценный опыт. Это первая заметка. [...]]]></description>
			<content:encoded><![CDATA[<p>Любой фрилансер, рано или поздно, пишет в свой блог о фрилансе. Это как дань моде или традиция. Я на вольных хлебах уже почти два года и, думаю, что время пришло. Особенно мне есть что сказать, сейчас, когда к моменту сдачи приближаются несколько совершенно разных проектов, каждый из которых принес свой бесценный опыт.</p>
<p>Это первая заметка. Остальные будут позже и окажутся более практичными. Сейчас я просто хочу полить воды на горячие камни. Потрепаться, так скажем.</p>
<p>Прежде всего, следует учитывать, что фриланс – штука индивидуальная. Каждый из нас имеет свою сферу деятельности, количество профессионального опыта, а также багаж в виде трудолюбия и самоконтроля.</p>
<p>Начну я с начала, а именно с того, почему некоторые офисные работники уходят свободный поиск.  Пойдем по списку.<br />
<span id="more-532"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<ol>
<li>Я не хочу работать на «дядю».
<li>На фрилансе я сам буду решать, за какую работу браться, а какую слать к черту.
<li>Я смогу зарабатывать больше. В офисе меня нихрена не ценят.
<li>В офисе некомфортно. Шумно, много людей. Все отвлекают.
<li>Буду экономить время на дороге, следовательно, делать свою работу быстрее.
<li>Я смогу работать там и тогда, когда мне это удобно.
</ol>
<p>Нумерация здесь не отражает хронологию или приоритет, хотя, бесспорно, первый пункт звучит наиболее часто.</p>
<p>Вполне возможно, у вас другой список, но, я уверен, большую часть всего этого вы неоднократно говорили или думали. Я также имею возможность общаться с другими фрилансерами и прекрасно помню свои мыски, когда я покидал последний офис. Список достаточно объективен и весьма актуален. Для чего он? Если вкратце, то все это – бред!</p>
<p>1. Можно ли считать благом отсутствие официального трудоустройства? Сомнительно. Во-первых, вы лишаете себя самого минимального социального пакета. Например, никакой вам теперь медицинской страховки. Также забудьте про сколько-нибудь серьезные кредиты в банке. Вам их не дадут. Даже при съеме жилья придется врать. Никто не хочет сдавать квартиру безработному, а фрилансеры именно таковыми являются. Кстати, не каждое посольство даст вам визу. США, например, очень не любит безработных, имейте ввиду. Перечислять можно долго, но самое главное, действительно ли вы теперь не работаете на «дядю»? А кем является каждый ваш заказчик? Это такой же работодатель только с тараканами, о которых вы ничего не знаете. Если своего руководителя вы знали на отлично и всегда понимали, когда его лучше не дергать или наоборот, можно подкатить с просьбой дать отгул. То теперь хрен. Каждый клиент – темная лошадка, у которой может меняться настроение от силы порыва ветра.</p>
<p>2. Да, так и есть, но до поры до времени. Крутить носом получается, когда денег куры не клюют. А если предыдущий месяц не выдался урожаем, то браться вы будите за все, что сколько-нибудь кормит. Конечно, все зависит от того, насколько вы успешны, но поверьте, черная полоса не минет и вас. Четко осознавайте, что далеко не всегда получается работать в удовольствие. Особенно, учитывая тот факт, что на фриланс, как правило, клиент приходит в поиске тех, кто сможет исправить возникшие проблемы. То есть основная часть работы – это правки и доработки уже чего-то, что сделано не вами. Соответственно, мне, как программисту, часто приходится сталкиваться с тоннами говно-кода. Вряд ли можно назвать это работой в радость.</p>
<p>3. Вот это полная херня. Кто это придумал и на каком основании? И почему люди в это так наивно верят? Да, теоретически, вы сможете зарабатывать больше, но готовьтесь к тому, что ваш рабочий день будет составлять 25 часов в сутки. Расклад простой. В офисе вы делали только ту работу, которая вам предписывалась по должности. Сейчас в ваши обязанности войдет необходимость переписки с клиентами, поиска заказов, предварительного ознакомления с ТЗ и прочее.  На все это уходит огромное количество времени, зачастую значительно большее, нежели время на выполнение задания непосредственно. Ко всему прочему, например, если вы программист, в офисе вы работали с корпоративной CMS, которую знали вдоль и поперек. На фрилансе каждый клиент приходит со своим «самоваром», в котором вам сначала придется разобраться, а уже потом его дописывать.</p>
<p>4. Да, верно.  Офисный планктон много курит, пьет кофе и никогда не откажется потрепаться о незыблемом. Соблазнов заниматься херней предостаточно. Но уверены ли вы в том, что дома их будет меньше? Семья, друзья и любимый хомяк не скоро поймут, что если вы дома, это не значит, что вы свободны и готовы составить им компанию за чашкой чая или же вас просто можно отправить в магазин за пакетом картошки и молоком. Прошло не меньше полугода, прежде чем мои родные таки осознали, что я работаю и меня не нужно дергать по поводу и без, ну а нормально я смог работать только тогда, когда переехал. Про такие внешние раздражители как зомбоящик и компьютерные игры я вообще молчу.</p>
<p>5. Читайте пункт 4. В нем я уже ответил и на эту глупость. Можно еще добавить, что время, которое вы сэкономили, уйдет явно не на работу. У вас появится повод подольше поспать, побольше пожрать и покурить на балконе с чашкой кофе. Также заметно больше времени будет на чтение блогов, посещение социальных сетей и прочую фигню, но никак не на работу.</p>
<p>6. Ага, конечно. Там – это где? Я пробовал работать на даче, например. Назвать атмосферу рабочей язык не поворачивается. Ну а настроение тем более.<br />
А работать вам придется тогда, когда это удобно вашим заказчикам. Никто не будет в восторге от того, что вы весь день мнете морду об подушку, а к работе приступаете ночью. Любой клиент желает, чтобы вы были на связи именно в рабочее время. Более того, для некоторых проектов это обязательное требование. В итоге, как не крути, а все равно придется быть онлайн днем, хотя бы с 12 и до 20:00. Также не забывайте о тех клиентах, что живут в других часовых поясах. С ними вам тоже придется общаться именно тогда, когда это удобно им. В итоге, ваш рабочий день превращается в рабочие сутки.</p>
<p>На самом деле, продолжать можно бесконечно. Мифов существует более чем достаточно. Да, в каждом из них есть капля правды, но это совсем не то, на что вы могли надеяться.</p>
<p>Тем не менее, без положительных моментов никуда. Иначе не было бы такого понятия, как фриланс. Ведь почему-то люди опускаются в это болото и здесь остаются, многие навсегда. Давайте и об этом поговорим.</p>
<p>Конечно, работать «на себя» приятно. Пусть это условность и не до конца правда, но отчасти это действительно так. Если вам позволяют обстоятельства, вы можете браться только за ту работу, которая вам нравится. К сожалению, это не всегда возможно, но гораздо реальнее, нежели в офисе. Там у вас никогда не бывает выбора, здесь он есть в тех или иных случаях.</p>
<p>В целом, решение любого вопроса зависит только от вас. Иногда такая свобода и количество ответственности откровенно напрягают и грузят, иногда наоборот, это придает сил. Вы будете успешны настолько, насколько хватит ваших талантов. Любой завершенный проект – только ваша заслуга. То, сколько вы заработали – плоды вашего труда. Но и провалы чувствуются гораздо острее. Всегда трудно осознавать, что в вашей лаже никто кроме вас не виноват. Свалить вину на кого-то уже не получится.</p>
<p>Что касается свободного времени, то здесь все зависит от вашей самоорганизации. Если сильно напрячься, можно успевать многое. Я этому так до конца и не научился. Иногда сложно заставить себя приступить к работе, иногда наоборот – трудно осознать факт того, что загруз уже максимальный и не нужно набирать работы еще больше. В итоге, сидишь, обложившись горящими проектами и думаешь только о том, как бы ласты не склеить. Но я всегда могу устроить себе выходной, пусть он будет и за мой счет. Могу дать себе бессрочный отпуск, несмотря на то, что это грозит последующей неизбежной диетой. Но по факту, в случае необходимости, я таки могу это сделать. В офисе такого не простят.</p>
<p>Что касается денег, то да – можно зарабатывать больше, но только ценой больших трудозатрат, значительно превышающих те, что вы позволяли себе в офисе. Тем не менее, если вам нечем заняться, можно забить время работой и превратить его в деньги. На рабочем месте такое неосуществимо, так как выше оклада не прыгнешь, хоть из кожи вылези. Премии и прочие подачки я в учет не беру, это не те суммы, о которых можно говорить и далеко не везде ими балуют.</p>
<p>Ну и самое главное, что я для себя нашел на фрилансе – бесценный опыт. Во-первых, появилась отличная возможность развивать свои коммуникативные навыки и навыки менеджера по продажам. Вряд ли еще где-либо вы столкнетесь с необходимостью настолько умело продавать свои услуги, как на рынке фриланса. Всегда есть возможность вытащить ценник на тот уровень, который удобен вам, добиться лучших условий сотрудничества, отказаться от тех решений, которые вам неудобны и заменить их другими, снижающими ваши трудозатраты. Во-вторых, любой проект – это в той или иной степени нестандартное решение. Даже самые тривиальные задачи содержат оговорки и свои особенности, что заставляет вас регулярно расширять свой кругозор актуальных технологий. Например, с XSL я познакомился только на фрилансе. Здесь же я получил опыт работы с новым для себя БД, с массой неплохих CMS, взял на вооружение дюжину новых алгоритмов и прочее. Для офисного работника никогда не будет такого раздолья. Любая компания движется по накатанной дорожке: корпоративная CMS, отстроенный цикл разработки и прочее. В итоге, любой проект превращается в выполнение одних и тех же телодвижений. Само собой, количество опыта, который вы получите, напрямую зависит от вашего собственного желания. Можно продолжать тупить, как и прежде, но предпосылок для развития все равно больше.</p>
<p>В общем, фриланс – это сложно, но интересно. Есть к чему стремиться, куда двигаться. Перспективы, кажется, менее очевидны, но их значительно больше. Запасайтесь терпением. Успехов! </p>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-05/about-freelance-part-1.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHPShop или встреча с дьяволом</title>
		<link>http://inroot.ru/2011-03/phpshop-or-meeting-with-sotona.html</link>
		<comments>http://inroot.ru/2011-03/phpshop-or-meeting-with-sotona.html#comments</comments>
		<pubDate>Tue, 29 Mar 2011 01:57:58 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Вольнодумье]]></category>
		<category><![CDATA[Разное]]></category>
		<category><![CDATA[PHPShop]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=492</guid>
		<description><![CDATA[Так как я являюсь фрилансером уже почти два года, само собой, что за это время я успел повидать немало различных программных решений: от самопальных скриптов, писаных в пьяном бреду, до громоздких и навороченных социальных движков, реализованных с использованием паттернов и и прочих прелестей программисткой мысли. Конечно, как любой разработчик, я почти никогда не бываю доволен [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="http://inroot.ru/wp-content/uploads/2011/03/phpshop_logo.png" alt="Отзыв о движке интернет магазина PHPShop" title="Отзыв о движке интернет магазина" width="150" height="150" class="alignleft size-full wp-image-496" /></p>
<p>Так как я являюсь фрилансером уже почти два года, само собой, что за это время я успел повидать немало различных программных решений: от самопальных скриптов, писаных в пьяном бреду, до громоздких и навороченных социальных движков, реализованных с использованием паттернов и и прочих прелестей программисткой мысли.</p>
<p>Конечно, как любой разработчик, я почти никогда не бываю доволен тем, с чем приходится работать. Всегда есть свои взгляды на самые тривиальные, казалось бы, вопросы. Всегда присутствует «я сделал бы здесь по-другому», но всегда в меру. Бывало я хотел убить авторов того или иного приложения, ну или просто оторвать им руки. Иногда я хотел эти руки пожать и дружески обнять тех, кто писал такой понятный и красивый код. Как бы там ни было, никогда не доходило до того, чтобы я писал гневные посты в блог или куда-либо еще. Но все бывает в первый раз и это случилось сегодня…</p>
<p>Добро пожаловать на церемонию торжественной казний PHPShop!</p>
<p><span id="more-492"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Не знаю как вы, но до недавнего времени я никогда даже не слышал об этом движке интернет магазина. Это, по меньшей мере, странно, ведь ребята продают <s>пирожки</s> свой продукт на рынке с 2004 года. Согласитесь, хоть краем уха, но слышать должен был.</p>
<p>Для начала замечу, что скрипт платный и стоит, если сравнивать с прочими подобными, весьма не дешево, а целых 11790 рублей (март 2011). Я бы попросил вас запомнить этот факт и обращать на него внимания по ходу чтения заметки. </p>
<p>Мое недовольство начинает рождаться в глубинах сознания уже с первых минут знакомства. Прежде всего, жутко не понравилось то, что некоторые файлы закрыты зендом. Достаточно давно миновали те времена, когда можно было париться за секретность каких-нибудь гениальных программных решений. Все уже давно решено и лежит в открытом доступе. К чему создавать лишние трудности тем, кто захочет поработать напильником. А поработать есть над чем и напильник потребуется немалый…</p>
<p>Второй приступ восторга вызвала админка, которую некто умный, проникшийся столпами юзабилити, сделать целиком и полностью на pop-up окнах. Мало того, что половину pop-up’ов блокирует глушилка рекламы, так вы еще может забыть про работу с админкой из нескольких вкладок. Вместо вкладок, чертова хрень плодит отдельные окна самого браузера. Первое время я никак не мог к этому привыкнуть и постоянно терял открытые поп-апы.</p>
<p>Еще больше позитива добавляли JavaScript ошибки, загадившие всю консоль Firebug’а. Я сразу понял, что с PHPShop мы поладим, и работа будет веселой и непринужденной (это сарказм, если что, но скучно действительно не было).</p>
<p>Поставленные задачи были просты:</p>
<ul>
<li><strong>Сверстать и нацепить шаблон</strong></li>
<li><strong>Настроить движок</strong></li>
<li><strong>Набить базу несколькими примерами контента</strong></li>
</ul>
<p>Я решил начать с предварительной настройки. И сразу сюрприз! Местами админка банально не работает.  Указанные настройки просто не сохраняются, хоть ты тресни. Например, в настройках категорий товаров можно выбрать количество товаров, выводимых в одну строку, при просмотре содержимого категории. Мало того, что есть всего четыре варианта выбора (от 1 до 4 товаров в ряд), так из них работает только три :) Вариант с четырьмя товарами просто не сохраняется… А как думаете, сколько нужно было мне? Бинго! Мне нужно было 4 товара в ряд.</p>
<p>Пошел  я смотреть в код, отчего же оно так все плохо. И тут плохо стало мне… Такого ужаса я не видел давно. То, что код не структурирован отступами – дело обыденное, а вот имена переменных из одной или двух букв повергли меня под стол. Увы, мой личный телепат ушел в декретный отпуск, поэтому о значении переменных с именами $ij, $j, $k и так далее, мне приходилось догадываться самостоятельно. А таких переменных там около 30% от общего числа. С таким я встретился впервые.</p>
<p>Далее я долго смеялся над транслитерированными именами лексем. Например, вы можете найти следующие шедевры:</p>
<blockquote><p>
Vivod_cat_table()<br />
$SysValue['my']['setka_num']<br />
$LoadItems['Podcatalog']
</p></blockquote>
<p>То есть чупакабра, которая писала код, знала некоторое количество английских слов, но совсем небольшое. Нет, ну если в школе тебе сильно били и ты пропускал уроки английского,  то почему бы не поискать слово «display в словаре? А правильно, нафиг, пусть «Vivod» убьет умы людей!</p>
<p>К слову, проблема имен коснулась не только переменных и функций, но и директорий, файлов и всего остального. Авторский стиль выдержан на твердую пять!</p>
<p>Дальше мне предстояло заняться одеванием шаблона. То, что это будет не самая простая задача, я уже понял, так как в скриптах забито огромное количество HTML кода, а значит, сами шаблоны большой гибкостью не отличаются. Знал бы я тогда, насколько сильно я ошибаюсь.</p>
<p>Если вы не знаете PHP, то сделать адекватную верстку для PHPShop вы не сможете. Как я уже сказал, очень много кода содержится в самих скриптах. Причем не какой-нибудь там строки пагинации или кнопки десятой важности, а вывода списка товаров, например. Более того, код, зашитый в скрипты, содержит незакрытые HTML тэги. А так как авторы PHPShop таблицами не брезговали, вылавливать глюки верстки вы замучаетесь.</p>
<p>Что касается встроенного шаблонизатора, то его в общем-то и нет. Ту хрень, что предлагают авторы движка, никак нельзя назвать шаблонизатором. Никаких вам  привычных {foreach} или {loop}, никаких условных операторов {if}. Шаблонизатор этого просто не умеет. Все, что он может – подставлять данные на место переменных вида <tt>@imya_peremennnoi@</tt>. Как с таким инструментарием сделать вменяемые и функциональный шаблон? Увы, ответа я не нашел.</p>
<p>Кстати об ответах. Решать проблемы вам придется самостоятельно потому, что никакой вменяемой справки нет. Та документация, что предлагают на сайте – набор букв. Найти в ней  нечто, несущее пользу нереально, вполне возможно потому, что там этого нет. Форум тоже отсутствует. Его роль выполняет гостевая книга – еще одно гениальное решение разработчиков. Они бы еще чат для этих целей использовали.</p>
<p>Что касается отстраненных впечатлений, то они тоже далеко не лучшие. Движок неудобен во всех отношениях. Админка кривая, как кочерга. Для человека неискушенного она не помощник, а препятствие. Учитывая недоработки, которых в ней с избытком, я боюсь даже представить, как малоопытный владелец такого интернет магазина сможет с ним управляться. Об интуитивности интерфейса я даже говорить не стану. Функциональные возможности движка также на нуле. Кроме организации магазина и новостной ленты, по сути, он толком больше ничего не умеет. Рубрикатор в магазине может быть всего двух уровней, то есть, сложной системы каталога добиться не получится.</p>
<p>Резюмируя и подводя итоги, предлагаю вам вспомнить стоимость данного скрипта и сопоставить ее с теми фактами, которые я здесь привел. Честно говоря, я просто в ужасе от того, какие программные решения и за какие деньги продаются. Еще хуже то, что эти решения покупают и используют.</p>
<p>Анафеме предан без права на права! Засим все…</p>
<blockquote><p><strong>UPD 16.08.11:</strong><br />
Сегодня в бэках яндекса наткнулся на &#8220;<a target="_blank" rel="external nofollow" href="http://forum.phpshopcms.ru/index.php?showtopic=1141">ответ Чемберлену</a>&#8221; от автора PHPshop. Думаю, комментариев не нужно. Товарищ Dennion ушел дискутировать среди своих :)</p>
<p>P.S: Из всей истории делаю один вывод &#8211; про PHPShop или хорошо, или никак, равным счетом, как об усопших. Критика, конструктивная, я считаю, ибо везде по пунктам и с конкретными претензиями, вызывает неадекватную реакцию.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-03/phpshop-or-meeting-with-sotona.html/feed</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Captcha. Использование Zend_Captcha_Image</title>
		<link>http://inroot.ru/2011-03/captcha-zend-captcha-image-in-use.html</link>
		<comments>http://inroot.ru/2011-03/captcha-zend-captcha-image-in-use.html#comments</comments>
		<pubDate>Wed, 23 Mar 2011 00:49:19 +0000</pubDate>
		<dc:creator>Олег Мурашов</dc:creator>
				<category><![CDATA[Zend Framework]]></category>
		<category><![CDATA[Captcha]]></category>
		<category><![CDATA[Zend_Captcha_Image]]></category>

		<guid isPermaLink="false">http://inroot.ru/?p=461</guid>
		<description><![CDATA[Поднимаемый вопрос не блещет своей оригинальностью и новизной. О механизмах защиты веб-ресурсов от спама написано бесконечное количество букв. Внесу свою скромную лепту данной заметкой, посвященной библиотеке Zend_Captcha_image, которая, как было нетрудно догадаться, идет в поставке с Zend Framework’ом. Собственно, почему именно эта библиотека? Если вам доводилось изучать рынок CMS, то вы не могли не заметить, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="post_cover" src="http://inroot.ru/wp-content/uploads/2011/03/zf_logo-150x150.gif" alt="Zend Framework" title="zf_logo" width="150" height="150" class="alignleft size-thumbnail wp-image-469" /></p>
<p>Поднимаемый вопрос не блещет своей оригинальностью и новизной. О механизмах защиты веб-ресурсов от спама написано бесконечное количество букв. Внесу свою скромную лепту данной заметкой, посвященной <strong>библиотеке Zend_Captcha_image</strong>, которая, как было нетрудно догадаться, идет в поставке с Zend Framework’ом. </p>
<p>Собственно, почему именно эта библиотека? Если вам доводилось изучать рынок CMS, то вы не могли не заметить, что в большинстве движков защитное изображение каптчи имеет совершенно одинаковый вид. Это особенно касается скриптов, производимых на свет нашими соотечественниками.</p>
<p>Очень большую популярность завоевала библиотека, распространяемая с сайта <a href="http://captcha.ru/" rel="external nofollow" target="_blank">captcha.ru</a>. При этом те, кто ее использует, даже не пытаются напрячь себя нуждой хоть немного подпилить алгоритм отрисовки защитного изображения. В итоге, данная каптча прекрасно распознается любым спам ботом, что делает ее совершенно бесполезной.</p>
<p><span id="more-461"></span></p><script type="text/javascript"><!--google_ad_client = "ca-pub-8815939525134657";/* Inroot.ru (post more) */google_ad_slot = "8033510070";google_ad_width = 728;google_ad_height = 90;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script><p></p>
<p>Может быть моя писанина о <strong>Zend_Captcha_image</strong> хоть кого-то натолкнет на мысль пойти чуть дальше в поиске решения проблемы защиты сайта от спама.</p>
<p>Не желая полностью копировать других авторов, буду описывать эту библиотеку в отрыве от всего остального фреймворка. То есть мы <strong>не будем использовать Zend_Form</strong> и иже с ней. Это даст возможность без особых проблем вкрутить каптчу в ваш сайт, даже если он отродясь не видел фреймворков и CMS.</p>
<p>Для работы Zend_Captcha_image потребуется наличие GD адекватной версии. Это не должно быть проблемой, тем не менее, если что-то не будет работать, убедитесь, что GD присутствует (смотрите в phpinfo).</p>
<p>Прежде всего, давайте вытащим из <strong>ZendFramework</strong> нужные нам библиотеки. Увы, взять только одну Zend_Captcha_image не получится, так как она имеет ряд зависимостей. Зависимостей этих не так мало, как хотелось бы. Придется подцепить библиотеки работы с сессиями, Zend_Loader и исключения. Иными словами, если вы уже используете какие-то части ZF или планируете делать это в будущем, то не запаривайтесь, берите весь фреймворк целиком. Все равно придете к этому рано или поздно. Для тех, кому таки хочется взять минимум, привожу список файлов, без которых жизнь не жизнь:</p>
<p><code><br />
Zend/Captcha/Adapter.php<br />
Zend/Captcha/Base.php<br />
Zend/Captcha/Image.php<br />
Zend/Captcha/Word.php<br />
Zend/Session/SaveHandler/Interface.php<br />
Zend/Session/Abstract.php<br />
Zend/Session/Exception.php<br />
Zend/Session/Namespace.php<br />
Zend/Validate/Abstract.php<br />
Zend/Validate/Interface.php<br />
Zend/Exception.php<br />
Zend/Loader.php<br />
Zend/Session.php<br />
</code></p>
<h2>Рисовалка каптчи</h2>
<p>Сначала напишем скрипт, который будет рисовать картинку, создавать сессию и прочее подобное.</p>
<p><b>application.php</b></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Массив с именами файлов шрифтов.
 * Каждый раз при генерации, будет выбираться случайный шрифт
 * @var array
 */</span>
<span style="color: #000088;">$fontsBase</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'verdana.ttf'</span><span style="color: #339933;">,</span>
    <span style="color: #0000ff;">'arial.ttf'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * HTTP путь к директории с изображениями.
 * Указывается относительно корня сайта
 * @var string
 */</span>
<span style="color: #000088;">$imagesHttpPath</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'/captcha/images'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span>
    PATH_SEPARATOR <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'DOCUMENT_ROOT'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/libs'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Captcha/Image.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$captcha</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Captcha_Image<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$captcha</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setTimeout</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'600'</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setWordLen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'5'</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setWidth</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">200</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setHeight</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">90</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFont</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'DOCUMENT_ROOT'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/captcha/fonts/'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$fontsBase</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$fontsBase</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">setImgDir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'DOCUMENT_ROOT'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$imagesHttpPath</span><span style="color: #009900;">&#41;</span>
        <span style="color: #339933;">-&gt;</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$captchaID</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$captcha</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Дабы скрипт был чуть более интересным, я решил, что будет весьма неплохо рисовать картинку разными шрифтами. Это еще несколько усложнит отгадывание нашей каптчи. Список шрифтов, кто бы мог подумать, хранится в массиве <tt>$fontsBase</tt>.</p>
<p>Далее подключаем саму библиотеку и создаем объект. Дабы не иклудить все зависимости руками, я просто добавил путь к директории с ZF в <tt>include_path</tt>. Кто уже работал с Zend Framework, не будет удивлен.</p>
<p>После создания объекта, задаем настройки защитного изображения. Имена методов говорят сами за себя. Остается пояснить лишь значение <tt>Zend_Captcha_Image::setTimeout()</tt>. Данный метод задает время жизни сессии, иными словами, за отведенное нами количество секунд, пользователь должен будет уж как-нибудь осилить заполнение формы. Иначе ему придется повторить ввод защитного кода, так как прежний станет недействительным. Думаю, 10 минут будет достаточно, хотя на практике нужно и того меньше.</p>
<p>При таких настройках, мы получим примерно следующее изображение:</p>
<p><img src="http://inroot.ru/wp-content/uploads/2011/03/4529acb3a15deacac53b9453e10dd706.png" alt="Результат использования Zend_Captcha_Image" title="4529acb3a15deacac53b9453e10dd706" width="200" height="90" class="size-full wp-image-468" /></p>
<p>Также заметьте, что директория, задаваемая в <tt>Zend_Captcha_Image::setImgDir()</tt> должна существовать и быть доступна для записи. В нее буду складываться сгенерированные изображения. Об очистке переживать не стоит, это будет происходить автоматически.</p>
<p>В последней строчке кода мы получаем ID сессии, который по совместительству является именем сгенерированного файла изображения. Сохраняем в переменной для дальнейшего использования в html форме.</p>
<h2>HTML форма</h2>
<p>С формой все банально.</p>
<p><b>index.php</b></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
</pre></td><td class="code"><pre class="html4strict" style="font-family:monospace;"><span style="color: #009900;">&lt;?php</span>
<span style="color: #009900;">	require_once <span style="color: #ff0000;">'application.php'</span>;</span>
<span style="color: #009900;">?&gt;</span>
&nbsp;
<span style="color: #00bbdd;">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">html</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">meta</span> <span style="color: #000066;">http-equiv</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Content-Type&quot;</span> <span style="color: #000066;">content</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/html; charset=UTF-8&quot;</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">title</span>&gt;</span>Captcha<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">title</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">head</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">form</span> <span style="color: #000066;">action</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;/target.php&quot;</span> <span style="color: #000066;">method</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;post&quot;</span>&gt;</span>
	Username: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;userName&quot;</span> <span style="color: #66cc66;">/</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
	Captcha: <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;captchaCode&quot;</span> <span style="color: #66cc66;">/</span>&gt;&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;hidden&quot;</span> <span style="color: #000066;">name</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;captchaId&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;?php echo $captchaID ?&gt;</span></span>&quot; /&gt;
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">img</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;?php echo $imagesHttpPath . '/' . $captchaID ?&gt;</span></span>.png&quot; alt=&quot;&quot; /&gt;<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">br</span> <span style="color: #66cc66;">/</span>&gt;</span>
	<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">input</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;submit&quot;</span> <span style="color: #000066;">value</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;Отправить&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">form</span>&gt;</span>
&nbsp;
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">body</span>&gt;</span>
<span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">html</span>&gt;</span></pre></td></tr></table></div>

<p>Поле captchaCode предназначено для введения текста с защитного изображения. В скрытом поле captchaId передаем ID сессии на скрипт, осуществляющий валидацию формы.</p>
<h2>Валидатор формы. Проверка captcha кода</h2>
<p>Здесь все также просто. По уже знакомой схеме подключаем нужную библиотеку, в данном случае для работы с сессиями, получаем данные нужной сессии и выполняем проверку введенного с изображения кода.</p>
<p><b>target.php</b></p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #990000;">set_include_path</span><span style="color: #009900;">&#40;</span>
    PATH_SEPARATOR <span style="color: #339933;">.</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'DOCUMENT_ROOT'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/libs'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">require_once</span> <span style="color: #0000ff;">'Zend/Session/Namespace.php'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$sessionData</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Zend_Session_Namespace<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Zend_Form_Captcha_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'captchaId'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$iterator</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$sessionData</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getIterator</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'captchaCode'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$iterator</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'word'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'We have a problem with u, guy...'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Welcome, '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'userName'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'!'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>О дополнительных параметрах, которые можно задать для генерируемого изображения Captcha, вы можете прочитать в официальном руководстве по <strong>адептерам к Zend_Captcha</strong>. Их там осталось немного.</p>
<p>Если подобрать хорошие шрифты, установить приличный уровень шума, то получится хорошая протекция от спама в формах. Главное, не забывайте, что помимо роботов, вашу форму захотят заполнить и люди. Не делайте код с картинки нечитаемым. Больше всего раздражает, когда невозможно разобрать символы на каптче, а следовательно правильно их ввести.</p>
<p>Также выкладываю архив со скриптами, о которых здесь шла речь.</p>
<blockquote><p><a href='http://inroot.ru/2011-03/captcha-zend-captcha-image-in-use.html/zend_captcha_image_source' rel='attachment wp-att-475'>Zend_Captcha_Image_source</a></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://inroot.ru/2011-03/captcha-zend-captcha-image-in-use.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

