<?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>В лабиринте извилин &#187; PHP</title>
	<atom:link href="http://www.charnad.com/blog/category/programming/php-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.charnad.com</link>
	<description>Блог-центр им. CharnaD</description>
	<lastBuildDate>Thu, 01 Jul 2010 20:50:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Symfony Tips: #1</title>
		<link>http://www.charnad.com/blog/symfony-tips-1/</link>
		<comments>http://www.charnad.com/blog/symfony-tips-1/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 15:50:21 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[admin generator]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[symfony tips]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1178</guid>
		<description><![CDATA[Бывает, что находишь какое-то решение в Гугле, а потом когда я сталкиваешься с похожей ситуацией - второй раз уже не можешь найти. Поэтому я буду записывать моменты, которые мне были полезны и могут понадобиться еще, будет что-то вроде рубрики Symfony tips. Как вообще убрать фильтры в admin generator? config: filter: class: false Как повесить иконку [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" />Бывает, что находишь какое-то решение в Гугле, а потом когда я сталкиваешься с похожей ситуацией - второй раз уже не можешь найти. Поэтому я буду записывать моменты, которые мне были полезны и могут понадобиться еще, будет что-то вроде рубрики Symfony tips.</p>
<p><strong>Как вообще убрать фильтры в admin generator?</strong></p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">config:
  filter:
    class: false</pre></div></div>

</p>
<p><strong>Как повесить иконку своему кастомному object_action?</strong></p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#sf_admin_container</span> ul li<span style="color: #6666ff;">.sf_admin_action_</span>#<span style="color: #cc00cc;">#ACTION_NAME</span>## a
<span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">/images/icons/icon.png</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span> <span style="color: #cc66cc;">0</span> <span style="color: #cc66cc;">0</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

</p>
<p><strong>Как недопустить ввода пустой строки в админке?</strong></p>

<div class="wp_syntax"><div 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> configure<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;">validatorSchema</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setOption</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'trim'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p><strong>Fatal error: Call to undefined function include_component()</strong><br />
Вы, скорее всего, указали в settings.yml standart_helpers, и забыли добавить в список Partial.</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">all: 
  .settings: 
    standard_helpers:       [I18N, Partial]</pre></div></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-tips-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Symfony: выборочная I18n для объектов Doctrine [Перевод]</title>
		<link>http://www.charnad.com/blog/symfony-vyborochnaya-i18n-dlya-obektov-doctrine/</link>
		<comments>http://www.charnad.com/blog/symfony-vyborochnaya-i18n-dlya-obektov-doctrine/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 00:44:59 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[I18n]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[перевод]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1085</guid>
		<description><![CDATA[Мне потребовалось сделать мультиязычный сайт аж на 5 языках. В целом тут нет ничего сложного, кроме того, что пользователю надо будет заполнять 5 форм на разных языках. Логичный вывод - сделать обязательным только один язык, например английский. Остальные заполняются по желанию, а для незаполненных показывается на том же английском. Промучившись некоторое время с рецептами от [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" />Мне потребовалось сделать мультиязычный сайт аж на 5 языках. В целом тут нет ничего сложного, кроме того, что пользователю надо будет заполнять 5 форм на разных языках. Логичный вывод - сделать обязательным только один язык, например английский. Остальные заполняются по желанию, а для незаполненных показывается на том же английском. Промучившись некоторое время с рецептами от Календаря Адвента, и не добившись успеха, я нашел пост [<a href="http://www.miximum.fr/tutos/449-optional-translation-form-for-i18n-objects-with-symfony-and-doctrine#comment-14308">Optional translation form for I18n objects with Symfony and Doctrine</a>], который мне помог. Я считаю, что полезным будет сделать его перевод. Так же я добавлю некоторые свои комментарии. (Перевод вольный, эстеты идут лесом)<span id="more-1085"></span></p>
<p>Некоторые люди утверждают, что Symfony - это подарок богов. Другие считают, что это преувеличение. Но как ни крути, в версиях 1.3/1.4 добавилось много нового и полезного, что может сэкономить вам вермя.<br />
Представим проект, где есть разные заметки (новости, интервью, и т.д.). И они могут быть на разных языках. И это довольно просто сделать с actAs: I18n. Но есть небольшая сложность: переводы должны быть опциональны, чтобы можно было написать статью только на французском, английском или немецком.
</p>
<p>Некоторые материалы по теме: <a href="http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine">раз</a>, <a href="http://symfonyguide.wordpress.com/2009/09/28/symfony-forms-saving-process/">два</a>, <a href="http://vousavezchoisi.com/img/formsdiagram.png">три</a>, <a href="http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms#chapter_06_ignoring_embedded_forms">четыре</a>, <a href="http://www.ze-technology.com/2009/06/05/tests-fonctionnels-avec-symfony-gerer-lidentification/">пять</a>.</p>
<h3>Итак, начнем со схемы.</h3>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">Article:
  actAs:
    Timestampable: ~
    I18n:
      fields: [ title, body ]
      actAs:
        Sluggable: { fields: [ title ], uniqueBy: [ lang, title ] }
&nbsp;
  columns:
    title: { type: string(255), notnull: true }
    body: { type: clob, notnull: true }
    author: { type: string(255), notnull: false }
&nbsp;
News:
  inheritance:
    extends: Article
    type: concrete</pre></div></div>

<p>А так же фикстуры:</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;">News:
  n1:
    author: 'Lenta.ru'
    Translation:
      ru:
        title: 'Нет вестей с Титана'
        body: |
          Титан – это шестой и самый крупный спутник Сатурна.
&nbsp;
  n2:
    author: 'Bash.org'
    Translation:
      en:
        title: '#921792'
        body: |
          &lt;Thomas&gt; if women think they arent meant to cook
          &lt;Thomas&gt; why do they have milk and eggs inside them?</pre></div></div>

<p>Загружаем все это добро в базу данных:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">php symfony doctrine:build <span style="color: #660033;">--all</span> <span style="color: #660033;">--and-load</span>
php symfony generate:app backend
php symfony doctrine:generate-admin backend News</pre></div></div>

<p>Загляните в только что построенный модуль админки. Нажмите кнопку "редактировать" и оп.. а где все наши переводы? Если вы еще не в курсе, actAs:I18n разделяет таблицу на 2 части, в первой содержатся общие поля, не зависящие от перевода, а во второй те, которые требуют перевода.</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">mysql&gt; SELECT * FROM news;
+----+-------------+---------------------+---------------------+
| id | author      | created_at          | updated_at          |
+----+-------------+---------------------+---------------------+
|  1 | Lenta.ru    | 2010-01-29 12:14:46 | 2010-01-29 12:14:46 | 
|  2 | Bash.org    | 2010-01-29 12:14:46 | 2010-01-29 12:14:46 | 
+----+-------------+---------------------+---------------------+
&nbsp;
mysql&gt; SELECT id, lang, title FROM news_translation;
+----+------+-----------------------------------------------------+
| id | lang | title                                               |
+----+------+-----------------------------------------------------+
|  1 | ru   | Титан – это шестой и самый крупный спутник Сатурна. | 
|  2 | en   | &lt;Thomas&gt; if women think they arent meant to cook ...| 
+----+------+-----------------------------------------------------+</pre></div></div>

<p>Чтобы нам было доступно редактирование переводов - надо воспользоваться функцией embedI18n.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/NewsForm.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> NewsForm <span style="color: #000000; font-weight: bold;">extends</span> BaseNewsForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * @see ArticleForm
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><span style="color: #009900;">&#40;</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;">embedI18n</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'ru'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'en'</span><span style="color: #009900;">&#41;</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></div></div>

<p>Вуа ля. Редактировать можно!
</p>
<h3>Немного приберемся</h3>
<p>Наш код сейчас не так хорош, как мог бы быть:<br />
Каждый раз, когда мы будем добавлять новый тип статьи - нам надо будет менять метод configure;<br />
Каждый раз, когда мы будем добавлять/удалять новый язык для статей - нам надо будет менять все формы.</p>
<p>К счастью, с Symfony 1.3, наследование форм повторяет наследование моделей. Смотрите, NewsForm наследует BaseNewsForm, которая в свою очередь наследует ArticleForm.</p>

<div class="wp_syntax"><div class="code"><pre class="yml" style="font-family:monospace;"># config/app.yml
all:
  cultures:
    enabled:
      ru: Russian
      en: English</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/NewsForm.class.php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Revert the changes we added there</span>
<span style="color: #000000; font-weight: bold;">class</span> NewsForm <span style="color: #000000; font-weight: bold;">extends</span> BaseNewsForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * @see ArticleForm
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">configure</span><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>
&nbsp;
<span style="color: #666666; font-style: italic;">// lib/form/doctrine/ArticleForm.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> ArticleForm <span style="color: #000000; font-weight: bold;">extends</span> BaseArticleForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * Available languages
   *
   * @var array $languages
   **/</span>
  protected <span style="color: #000088;">$langages</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<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;">languages</span> <span style="color: #339933;">=</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_cultures_enabled'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$langs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedI18n</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$langs</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</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;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabel</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$label</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: #009900;">&#125;</span></pre></div></div>

<p>Перезагрузите теперь страницу. Вы можете теперь добавлять/удалять языки независимо от количества типов статей.</p>
<h3>Редактируем переводы</h3>
<p>
Давайте теперь попробуем нашу форму для статей. Когда вы попробуете редактировать какую-нибудь новость, то... постыдная неудача. Нельзя сохранить, потому что нет английского или русского перевода. Давайте добавим условие, что если в форме есть пустые поля - мы эти формы не сохраняем.<br />
Для этого мы перекроем метод doBind.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/ArticleForm.class.php</span>
<span style="color: #000000; font-weight: bold;">class</span> ArticleForm <span style="color: #000000; font-weight: bold;">extends</span> BaseArticleForm
<span style="color: #009900;">&#123;</span>
  <span style="color: #009933; font-style: italic;">/**
   * Available languages
   *
   * @var array $languages
   **/</span>
  protected <span style="color: #000088;">$langages</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<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;">languages</span> <span style="color: #339933;">=</span> sfConfig<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'app_cultures_enabled'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$langs</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_keys</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embedI18n</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$langs</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</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;">widgetSchema</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setLabel</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Cleans and binds values to the current form
   *
   * Ignore i18n forms when all their fields are empty
   *
   * @see sfForm::doBind
   **/</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> doBind<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embeddedI18nFormIsEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</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: #990000;">unset</span><span style="color: #009900;">&#40;</span>
          <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
          <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doBind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #009933; font-style: italic;">/**
   * Check if every fields, except for id and lang, are empty
   **/</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> embeddedI18nFormIsEmpty<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</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: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$key</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'lang'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
        <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span> <span style="color: #339933;">!==</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В перекрытом методе doBind, мы проверяем каждую I18n форму, и, если надо делаем ей unset. Теперь все сохраняется как надо, однако же...</p>
<p>Загляните в базу данных, вас там ждет сюрприз.</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;">mysql<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> id<span style="color: #66cc66;">,</span> lang<span style="color: #66cc66;">,</span> slug <span style="color: #993333; font-weight: bold;">FROM</span> news_translation;
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+------------------------------------------------------+</span>
<span style="color: #66cc66;">|</span> id <span style="color: #66cc66;">|</span> lang <span style="color: #66cc66;">|</span> slug                                                 <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+------------------------------------------------------+</span>
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> en   <span style="color: #66cc66;">|</span>                                                      <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">1</span> <span style="color: #66cc66;">|</span> ru   <span style="color: #66cc66;">|</span> Титан – это шестой и самый крупный спутник Сатурна<span style="color: #66cc66;">.</span>  <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">|</span>  <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">|</span> en   <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">&lt;</span>Thomas<span style="color: #66cc66;">&gt;</span> <span style="color: #993333; font-weight: bold;">IF</span> women think they arent meant <span style="color: #993333; font-weight: bold;">TO</span> cook <span style="color: #66cc66;">...</span> <span style="color: #66cc66;">|</span> 
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">----+------+------------------------------------------------------+</span></pre></div></div>

<p>Где-то в процессе сохранения, Symfony создала пустой объект перевода. И вот решение для этой проблемы.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// lib/form/doctrine/ArticleForm.class.php</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Add this at the beginnig of the class:</span>
  <span style="color: #009933; font-style: italic;">/**
   * I18n ignored forms
   **/</span>
  protected <span style="color: #000088;">$I18nFormsIgnored</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: #666666; font-style: italic;">// update the doBind method:</span>
  <span style="color: #009933; font-style: italic;">/**
   * Unset i18n forms values when every field is empty
   **/</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> doBind<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span> <span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">languages</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$label</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">embeddedI18nFormEmpty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</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;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">I18nFormsIgnored</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$lang</span><span style="color: #339933;">;</span>
        <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span>
          <span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
          <span style="color: #000088;">$this</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span>
        <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doBind</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// And override the doUpdateObject method:</span>
  <span style="color: #009933; font-style: italic;">/**
   * Updates the values of the object with the cleaned up values.
   *
   * @param  array $values An array of values
   *
   * @see sfFormDoctrine::doUpdateObject()
   */</span>
  protected <span style="color: #000000; font-weight: bold;">function</span> doUpdateObject<span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span>
  <span style="color: #009900;">&#123;</span>
    parent<span style="color: #339933;">::</span><span style="color: #004000;">doUpdateObject</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">I18nFormsIgnored</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$lang</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span>
      <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">object</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">Translation</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$values</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$lang</span><span style="color: #009900;">&#93;</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></div></div>

<p>На этот раз все сохраняется как надо!
</p>
<p>(Здесь я пропускаю абзац про убирание поля Slug. Там есть сложность с тем, что формы перевода не наследуются. Если вам интересно - посмотрите в оригинальной статье. Я считаю, что основное здесь - как раз перекрытие методов doBind и doUpdateObject.<br />
Тесты, приведенные автором можно посмотреть у него в статье, а можно <a href="http://pastie.org/995806">тут</a> и <a href="http://pastie.org/995807">тут</a>).</p>
<p>На этом все. Надеюсь вам пригодится мой перевод.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-vyborochnaya-i18n-dlya-obektov-doctrine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Исходники судоку</title>
		<link>http://www.charnad.com/blog/isxodniki-sudoku/</link>
		<comments>http://www.charnad.com/blog/isxodniki-sudoku/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 19:30:46 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[sources]]></category>
		<category><![CDATA[sudoku]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=1005</guid>
		<description><![CDATA[Я уже давно обещал выложить исходные коды судоку (поиграйте в судоку, если еще не играли). Я думал, что со временем исправлю код, сделаю лучше, но нет ни времени, ни желания. Поэтому лучше я выложу как есть, а вы уж сами улучшайте. Посмотреть код. Далее в посте будут комментарии. Что касается алгоритма, то здесь все работает [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/> Я уже давно обещал выложить исходные коды судоку (<a href="http://www.charnad.com/blog/sudoku-na-php-i-jquery/">поиграйте в судоку</a>, если еще не играли). Я думал, что со временем исправлю код, сделаю лучше, но нет ни времени, ни желания. Поэтому лучше я выложу как есть, а вы уж сами улучшайте. <a href="http://pastie.org/private/0hqk6m0flopmpp1eurtjrg">Посмотреть код</a>. Далее в посте будут комментарии.<span id="more-1005"></span></p>
<p>Что касается алгоритма, то здесь все работает так. У нас есть поле 9х9, соответственно начнем мы с</p>

<div class="wp_syntax"><div 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> generate<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;">error_counter</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$row</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">9</span><span style="color: #339933;">;</span> <span style="color: #000088;">$row</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$col</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$col</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">9</span><span style="color: #339933;">;</span> <span style="color: #000088;">$col</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></pre></div></div>

<p>$error_counter служит нам для защиты от тупиков. Сейчас вы увидите о чем речь.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">&gt;</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">retry_after</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Row will be incremented to 0</span>
    <span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$col</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">reset</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sudoku</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$col</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getNum</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #666666; font-style: italic;">//Вычисляем какие цифры подходят в текущую клетку</span>
    <span style="color: #000088;">$fit</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fit</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span><span style="color: #339933;">,</span> <span style="color: #000088;">$col</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$percents</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>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #000088;">$numbers</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$number</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$percents</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$number</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">percentage</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$number</span><span style="color: #339933;">,</span> <span style="color: #000088;">$row</span><span style="color: #339933;">,</span> <span style="color: #000088;">$col</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fit</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">//Here we get all numbers, that are most possible</span>
    <span style="color: #000088;">$available</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>
    <span style="color: #000088;">$max</span> <span style="color: #339933;">=</span> <span style="color: #990000;">max</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_values</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$percents</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$fit</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$number</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$percents</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$number</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #000088;">$max</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$available</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$number</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Вот тут и происходит вся магия. Сначала вычисляем какие числа могут встать в клетку (смотрим, чтобы по вертикали, горизонтали и в малом квадрате такой не было). Далее для каждого из этих чисел запускается мутная функция percentage. Она вычисляет, какой шанс у числа попасть в эту клетку. Допустим у нас осталось 4 свободные клетки и 4 числа. При этом первое число может попасть в 1 клетку из 4х, второе в две, третье в три, четвертое во все. Эта функция просто делит количество клеток куда число может попасть на количество пустых клеток. Таким образом, выпадет число, у которого меньше всего шансов попасть в другие клетки. При равенстве берем случайное.
</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//It can turn that sudoku generation isn't going well</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$available</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sudoku</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$cell</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$cell</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNum</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$row</span><span style="color: #339933;">--;</span>
    <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span><span style="color: #339933;">++;</span>
    <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В переменной available хранятся те самые числа, которые могут попасть в текущую клетку и имеют наивысшую вероятность попасть. Если вдруг оказывается, что никакое число не может попасть, а ряд еще не закончился - то мы сбрасываем текущий ряд и начинаем генерировать его заново. Ну а если сбрасывается ряд (по умолчанию) 30 раз, тогда, как я уже говорил, перегенерируется вся головоломка.
</p>
<p>
<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">error_counter</span> <span style="color: #339933;">&gt;</span> <span style="color: #000000; font-weight: bold;">self</span><span style="color: #339933;">::</span><span style="color: #004000;">retry_after</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">break</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">sudoku</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$col</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setNum</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$available</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$available</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Тут все просто, если надо сбросить головоломку - идем в начало и сбрасываем. А если все в порядке - берем случайное число, если их несколько.<br />
Ну а все остальное по-моему достаточно просто и понятно.</p>
<p>That's all folks.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/isxodniki-sudoku/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP: эксклюзивный счетчик в Shared Memory</title>
		<link>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/</link>
		<comments>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:41:14 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[shared memory]]></category>
		<category><![CDATA[unix]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=992</guid>
		<description><![CDATA[Я надеюсь что вы уже прочитали вводную статью про многопоточность в PHP, или вам это просто не требуется. Теперь я расскажу про счетчик, который будет доступен для потоков приложения, при этом доступ к нему будет эксклюзивным. Разделяемая память - особая область памяти, которая доступа ВСЕМ процессам операционной системы. Доступ к определенному сегменту можно получить с [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Я надеюсь что вы уже прочитали вводную статью про <a href="http://www.charnad.com/blog/mnogopotochnost-na-php/">многопоточность в PHP</a>, или вам это просто не требуется. Теперь я расскажу про счетчик, который будет доступен для потоков приложения, при этом доступ к нему будет эксклюзивным.</p>
<p><span id="more-992"></span></p>
<p>Разделяемая память - особая область памяти, которая доступа ВСЕМ процессам операционной системы. Доступ к определенному сегменту можно получить с помощью двух параметров: имени существующего файла и одного символа, который будет ключом System V IPC. Это нужно для того, чтобы несколько сегментов могли быть выделены основываясь на одном и том же файле. Звучит пока очень туманно, но сейчас я приведу пример, и надеюсь все станет понятно.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$t_key</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$shmid</span> <span style="color: #339933;">=</span> <span style="color: #990000;">shmop_open</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$t_key</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'c'</span><span style="color: #339933;">,</span> <span style="color: #208080;">0755</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">64</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">shmop_write</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shmid</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">shmop_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$shmid</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Первой командой, специальной функцией ftok мы получили ключ, по которому будем получать доступ к сегменту разделяемой памяти. Первым параметром мы передали ему имя файла скрипта, а вторым букву 'g'. Почему 'g'? А просто так, можно взять любой символ.<br />
Во второй строке мы собственно открываем доступ к сегменту памяти. Первый параметр - наш ключ, второй параметр 'c' - флаг указывающий на то, что мы создаем сегмент памяти, при том, если он уже существуем - он открывается на чтение/запись. Третий параметр - права на доступ, четвертый - размер в байтах.<br />
В третьей строке мы записываем туда единицу, последний параметр - смещение.<br />
И наконец закрываем сегмент.<br />
Теперь по адресу, который определяется файлом скрипта и буквой 'g' в сегменте размером 64 байта лежит единица, и ее может достать любой процесс.</p>
<p>Теперь представим, что у нас программа работает в 50 потоков, она обрабатывает файл строчка за строчкой. Мы не хотим, чтобы программа два раза обрабатывала одну строку, поэтому кладем в разделяемую память номер строки, которая была обработана последней. И каждый процесс перед тем, как считать строчку берет из разделяемой памяти номер последней обработанной строки, прибавляет единицу, записывает обратно в разделяемую память и идет обрабатывать эту строчку. Следующий процесс возьмет уже строчку с номером на один больше. Все хорошо, все радуются, работает быстро. Однако случается так, что два процесса одновременно решили взять значение из памяти и взяли одинаковое значение и записали одинаковое. А представьте, что сразу 50 процессов одновременно считают значение. В общем дело ясное, что нам надо ограничить доступ к памяти одним процессом.</p>
<p>Как раз для таких случаев придуманы семафоры. Семафор (semaphore) - это такая сущность, которая позволяет ограниченному количеству процессов одновременно получать "зеленый свет" на выполнение чего-либо. Семафор, у которого такое количество равно 1 называется мьютексом (mutex). Именно мьютекс позволит нам не допускать в наш сегмент памяти больше одного процесса и остановит анархию.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$sem</span> <span style="color: #339933;">=</span> <span style="color: #990000;">sem_get</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">ftok</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'g'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">sem_acquire</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//тут может быть только один процесс</span>
<span style="color: #990000;">sem_release</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$sem</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Мы получаем ключ для семафора точно таким же образом, как и для разделяемой памяти. Третий параметр - автоматическое "отпускание" семафора, если поток, который был впущен завершился. Те потоки, которые попытаются получить доступ к семафору, будут блокированы до тех пор, пока семафор не освободится. Это похоже на очередь в туалет. Один внутри, остальные снаружи. Один выходит, другой заходит и закрывается, другие продолжают ждать.
</p>
<p>Таким образом, создав ячейку памяти и создав семафор мы получаем счетчик, который позволит нам обрабатывать файл построчно не боясь, что одна строка будет обработана два раза. Для использования этого принципа я сделал класс Counter, который работает в моем многопоточном приложении. Взять его можно <a href="http://pastebin.org/86576">вот здесь</a>. А тут я приведу пример использования:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Ноль это наше начальное состояние счетчика</span>
<span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span>_new<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//Порождаем потомков</span>
<span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> PROCESS_AMOUNT<span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<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;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Error spawning new process'</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #666666; font-style: italic;">//Родительский процесс у нас ничего не будет делать</span>
    <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</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>
        <span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #666666; font-style: italic;">//TOTAL_LINES - количество строк в файле</span>
        <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$counter</span> <span style="color: #339933;">&lt;</span> TOTAL_LINES<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #666666; font-style: italic;">//Берем значение счетчика и увеличиваем его на 1</span>
            <span style="color: #000088;">$counter</span> <span style="color: #339933;">=</span> Counter<span style="color: #339933;">::</span><span style="color: #004000;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'g'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #666666; font-style: italic;">//Обарабатываем файл</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>
</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Многопоточность на PHP</title>
		<link>http://www.charnad.com/blog/mnogopotochnost-na-php/</link>
		<comments>http://www.charnad.com/blog/mnogopotochnost-na-php/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 12:05:36 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ipc]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=988</guid>
		<description><![CDATA[Хочу рассказать вам про многопоточные приложения, взаимодействие процессов (IPC) и применение всего этого на PHP. В качестве примера мы возьмем счетчик с эксклюзивным доступом, доступный для всех процессов. Что такое многопоточность? Это способ разделения программы на отдельные сущности (процессы и треды(threads)) для обеспечивания параллельности выполнения. Зачем это нужно? Для ускорения работы. Ведь открывая какой-нибудь сайт [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Хочу рассказать вам про многопоточные приложения, взаимодействие процессов (IPC) и применение всего этого на PHP. В качестве примера мы возьмем счетчик с эксклюзивным доступом, доступный для всех процессов.</p>
<p><span id="more-988"></span></p>
<p>Что такое многопоточность? Это способ разделения программы на отдельные сущности (процессы и треды(threads)) для обеспечивания параллельности выполнения. Зачем это нужно? Для ускорения работы. Ведь открывая какой-нибудь сайт вы не хотите ждать пока сервер последовательно откроет его всем, кто запросил его до вас. Вы хотите сразу, поэтому сервер выделяет отдельный процесс или поток для обработки вашего запроса. </p>
<p>Сначала немного про многопточность в PHP. PHP не многопоточный язык, PHP не умеет работать с тредами. Однако мы можем использовать системные вызовы операционной системы для создания процессов. Это как если бы мы просто запускали PHP-CLI несколько раз. Основная команда pcntl_fork разделяет выполнение программы на 2 части: родительскую и дочернюю, при этом эта команда вернет идентификатор процесса. Если вернулся -1, значит произошла ошибка, если 0, значит мы в дочернем потоке, если число - значит в родительском. </p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</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;">$pid</span> <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Произошла ошибка'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// Мы в родительском потоке</span>
     pcntl_wait<span style="color: #009900;">&#40;</span><span style="color: #000088;">$status</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Ждем выполнения потомка</span>
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
     <span style="color: #666666; font-style: italic;">// Мы в потоке потомке</span>
     <span style="color: #666666; font-style: italic;">// Делаем что-нибудь</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>В этом примере мы разделили программу на 2 части. В родительском процессе мы ожидаем завершения дочернего, чтобы тот доложил об успешном завершении. В противном случае он останется висеть в системе, как процесс-зомби. А если мы хотим не 2 потока, а больше? Тогда вызываем pcntl_fork несколько раз.</p>
<p>Приведу пример, как можно использовать pcntl_fork для "демонизации" процесса. Демон (daemon) - процесс выполняющийся в фоновом режиме. Это бывает очень удобно для программ, которые выполняются долгое время и не требуют прямого общения с пользователем. В Windows службы - аналог демонов в *nix системах. Итак, у вас есть программа на PHP, выполняющаяся в командной строке и вы хотите, чтобы она работала в фоне. Конечно, вы всегда можете сделать так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">nohup</span> php script.php <span style="color: #000000; font-weight: bold;">&amp;</span></pre></div></div>

<p>Это запустит вашу программу в фоновом режиме, а весь вывод будет перенаправлять в nohup.out. Более того, программа не завершится с выходом пользователя из системы. Но для демонов более правильный вариант создать процесс-потомок, закрыть родительский процесс (да-да, почти как зомби), только мы еще назначим наш дочерний поток "лидером сессии", то есть он сам сможет порождать дочерние потоки.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//Demonization</span>
<span style="color: #000088;">$child_pid</span> <span style="color: #339933;">=</span> pcntl_fork<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Если мы получили дочерний id, </span>
<span style="color: #666666; font-style: italic;">// то мы в родительском потоке</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$child_pid</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #990000;">exit</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">//Здесь мы уже в потомке, а родитель был закрыл</span>
<span style="color: #990000;">posix_setsid</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Таким образом мы получим независимо выполняющуюся программу. Завершить ее можно командой kill pid, где pid - идентификатор процесса. Тот самый, который возвращается в родительский поток и представляет собой целое неотрицательное число, уникальное в системе.
</p>
<p>Возникает вопрос, зачем же нужны threads, если есть процессы? Дело в том, что треды выполняются в том же контексте, что и породивший его процесс, то есть все треды имеют общие ресурсы, например открытые файлы. Закрыв файловый дескриптор в одном треде, вы получите ошибку в другом, если попытаетесь прочитать этот файл с тем же дескриптором. В свою очередь процессам нужен особый способ обмениваться данными, если вы хотите открыть один и тот же файл в разных процессах. Для такого общения есть множество инструментов. Один из основных - сигналы.</p>
<p>Сигналы - это системные вызовы, влияющие на поведение процессов. Сигнал может завершить, приостановить, или послать особый сигнал, определенный пользователем. Помимо сигналов есть разделяемая память (shared memory) и семафоры (semaphores). Более подробно о них, и вообще об устройстве posix совместимых операционных систем советую вам поискать в интернете. Это было краткое введение в тему, для подготовки к следующей статье про <a href="http://www.charnad.com/blog/php-eksklyuzivnyj-schetchik-v-shared-memory/">счетчик в shared memory</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/mnogopotochnost-na-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ошибка PDO Invalid Argument и Unix socket</title>
		<link>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/</link>
		<comments>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 14:56:32 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[pdo]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=910</guid>
		<description><![CDATA[Такая ошибка возникла у меня после перехода на PHP 5.3. Решение я нашел на http://stackoverflow.com, можете там посмотреть, чтобы узнать про эту ошибку более подробно. Выглядит она вот так: Warning: PDO::__construct&#40;&#41; &#91;pdo.--construct&#93;: &#91;2002&#93; Invalid argument &#40;trying to connect via unix://&#41; in /home/blah-blah-blah.php on line 9 &#160; Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" style="float:left;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/php.gif" alt=""/></p>
<p>Такая ошибка возникла у меня после перехода на PHP 5.3. Решение я нашел на http://stackoverflow.com, можете там посмотреть, чтобы узнать про эту ошибку более подробно. Выглядит она вот так:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">Warning: PDO::__construct<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span>pdo.--construct<span style="color: #7a0874; font-weight: bold;">&#93;</span>: <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #000000;">2002</span><span style="color: #7a0874; font-weight: bold;">&#93;</span> Invalid argument <span style="color: #7a0874; font-weight: bold;">&#40;</span>trying to connect 
via unix:<span style="color: #000000; font-weight: bold;">//</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php on line <span style="color: #000000;">9</span>
&nbsp;
Fatal error: Uncaught exception <span style="color: #ff0000;">'PDOException'</span> with message <span style="color: #ff0000;">'SQLSTATE[HY000] [2002]
Invalid argument'</span> <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php:<span style="color: #000000;">9</span> Stack trace: <span style="color: #666666; font-style: italic;">#0</span>
<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>blah-blah-blah.php<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000;">9</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>: PDO-<span style="color: #000000; font-weight: bold;">&gt;</span>__construct<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #ff0000;">'mysql:host=localhost;dbname=db'</span>, <span style="color: #ff0000;">'USER'</span>, 
<span style="color: #ff0000;">'PASSWORD'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #666666; font-style: italic;">#1 {main} thrown in /home/blah-blah-blah.php on line 9</span></pre></div></div>

<p>Решается она так: вместо localhost, при написании DSN для PDO пишите 127.0.0.1. А так же стоит указать путь к сокету MySQL в php.ini: pdo_mysql.default_socket=/var/run/mysqld/mysql.sock</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/oshibka-pdo-invalid-argument-unix/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: Получить строку по номеру</title>
		<link>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/</link>
		<comments>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 13:59:25 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[*nix]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=884</guid>
		<description><![CDATA[Мне нужно было получать строку из файла по порядковому номеру. То есть первую, десятую, 390815-ую, и т.д. Сначала мне хватало цикла fgets, который прокручивал до нужной строки. На строке 500000 такой способ у меня занимал уже почти минуту, что явно плохо. Stream_get_line был совем не быстрее, а даже медленнее процентов на 30. Первый из костылей, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" title="PHP" src="http://static.php.net/www.php.net/images/php.gif" alt="" width="120" height="67" />
<p>Мне нужно было получать строку из файла по порядковому номеру. То есть первую, десятую, 390815-ую, и т.д. Сначала мне хватало цикла fgets, который прокручивал до нужной строки. На строке 500000 такой способ у меня занимал уже почти минуту, что явно плохо. Stream_get_line был совем не быстрее, а даже медленнее процентов на 30.</p>
<p>Первый из костылей, пришедших мне в голову был fseek до значения в 500000 строк (посчитал байты), а оттуда уже крутил fgets. Но так как у меня идет обработка до 100 тысяч строк в сутки, то через пару дней опять пришлось высчитывать смещение для fseek. Опять же, требовался другой выход. И я его таки нашел.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> getFileLine<span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$line</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">exec</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;head -n <span style="color: #006699; font-weight: bold;">$line</span> <span style="color: #006699; font-weight: bold;">$file</span> | tail -n 1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Head берет N первых строк файла, tail N последних. Все гениальное просто. 1 миллионная строка берется из файла за 1.027 сек, 40 миллионная - 30 секунд, что очевидно быстрее прокручивания fgets.  (Конечно, если не прыгать fseek до 40 миллионной записи и считывать 40000001-ую)</p>
<p>Конечно, решение ограничено *nix системами, но т.к. моя система и без того использует pcntl_fork, она уже была привязана к никсам, так что хуже мне не стало.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-poluchit-stroku-po-nomeru/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Судоку на PHP и jQuery</title>
		<link>http://www.charnad.com/blog/sudoku-na-php-i-jquery/</link>
		<comments>http://www.charnad.com/blog/sudoku-na-php-i-jquery/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 16:06:22 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[js]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=800</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><iframe frameborder="0" width="480" height="500" align="center" src="http://dev.charnad.com/sudoku" scrolling="no"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/sudoku-na-php-i-jquery/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Kohana и Formo</title>
		<link>http://www.charnad.com/blog/kohana-i-formo/</link>
		<comments>http://www.charnad.com/blog/kohana-i-formo/#comments</comments>
		<pubDate>Sat, 11 Jul 2009 00:10:27 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[formo]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[kohana]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=609</guid>
		<description><![CDATA[Я взялся за изучение фреймворка Kohana. Подкупил меня размер - чуть меньше мегабайта. Я давно хотел найти быстрый и легкий фреймворк для небольших разработок. Пока я не настолько его изучил, чтобы делать глобальные выводы, но могу рассказать о процессе изучения. О том как установить Kohana легко найти в интернете. Вкратце: скачать, распаковать, запустить install, удалить [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/kohana_logo.png" alt=""/>Я взялся за изучение фреймворка Kohana. Подкупил меня размер - чуть меньше мегабайта. Я давно хотел найти быстрый и легкий фреймворк для небольших разработок. Пока я не настолько его изучил, чтобы делать глобальные выводы, но могу рассказать о процессе изучения.<span id="more-609"></span></p>
<p>О том как установить Kohana легко найти в интернете. Вкратце: скачать, распаковать, запустить install, удалить install. Про то, как убрать index.php из адреса тоже пару слов всего: переименовать example.htaccess в .htaccess и убрать index.php из $config['index_page'] в конфиге.</p>
<p>Собственно постороение приложения на Кохане я начал с того, что захотел переписать на этом фреймворке скриптик по удаленному управлению сайтами. И первая задача - формочка добавления сайта в БД. И тут возникли первые проблемы. Компоненты для построения форм, которые описаны в туториалах: Forge и Formation. Я выбрал Formation, скачал, установил. Не работает, выдает ошибки. Гуглил, читал форумы, боролся. От безысходности постучался в аську к одному парню, который имел дело с Коханой и получил ответ, что Forge и Formation блин уже deprecated. Как вам такое? На сайте я не видел об этом ни слова. Может не там искал?</p>
<p>
Ладно, пошел я дальше искать модуль для создания формочек. Посоветовали мне Morf. Зашел на страничку проекта. А там такой тухляк.. полгода код не обновляется, висит один тикет и еще два закрыто. Понятно все, не надо нам добра такого. В общем остался последний модуль на который были все надежды - Formo.</p>
<p>Formo завелся сразу, подключился без особых хлопот.  Только вот одна проблема, форму мне выводит с помощью P и DIV, а мне проще в TABLE запихать. Стал искать способы заставить генерить форму по-другому. Модифицировал объект, менял настройки - фиг. Нашел в мануале статью по темплейтам, переделал под темплейт. Не работает. Оказалось пример приведен с использованием шаблонизаторов, коими я не пользуюсь. В итоге кое-как заставил генериться форму как надо.</p>
<p>С валидацеий тоже номер. Искал как в валидацию передать $_POST, чтобы сверить с установками. Оказалось, что Formo сама жрет POST. Так же сама делает repopulation, основываясь на имени таблицы и hidden инпуте. Пока этого не знаешь - пугаешься и мучаешься, когда узнаешь - становится просто и легко. После чего за два дня доделал простейший CRUD.</p>
<p>Общие впечатления о фреймворке на этот момент:<br />
1. Наименования классов xxx_Core, когда вызываются они new xxx(); ломает автокомплит из-за чего надо совать IDE отдельный файлик, где прописаны "class xxx extends xxx_Core {}".<br />
2. Документация местами ужасна. Референс мануал нормальный, референс есть референс. Но вот тьюториалов мало, документация модулей слабая, коммьюнити маленькое. В общем въезжать тяжело.<br />
3. Местами все все-таки достаточно просто. За 10 минут добавил себе пару нужных хелперов, за полчаса написал плагин к Formo. И то, и другое я выложу чуть попозже.<br />
4. Дурацкие сообщения об ошибках. Если я ошибся и сунул не тот параметр, который ожидается - вылезает Fatal error где-то в глубине ядра. О том, что это я ошибся в параметре, а не Кохана концы отбрасывает можно только догадываться.<br />
5. ORM успел посмотреть на уровне CRUD одной таблицы. Удобно.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/kohana-i-formo/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Symfony: плагин sfPropelToggler 1.0.0b</title>
		<link>http://www.charnad.com/blog/symfony-plagin-sfpropeltoggler-100b/</link>
		<comments>http://www.charnad.com/blog/symfony-plagin-sfpropeltoggler-100b/#comments</comments>
		<pubDate>Sat, 16 May 2009 11:58:36 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[sfPropelToggler]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[togglers]]></category>
		<category><![CDATA[переключатели]]></category>
		<category><![CDATA[плагин]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=511</guid>
		<description><![CDATA[Не так давно я писал про тогглеры (переключатели) в Symfony. Вчера я поработал над ними и существенно упростил их принцип работы, теперь они доступны в качестве плагина. Сразу же дам ссылку, вы можете их скачать в виде PEAR package и просто zip-архив. Дальше я расскажу как этим плагином пользоваться. Вообще, по правилам PEAR все инструкции [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt=""/>Не так давно я писал про <a href="http://www.charnad.com/blog/symfony-pereklyuchateli/">тогглеры (переключатели) в Symfony</a>. Вчера я поработал над ними и существенно упростил их принцип работы, теперь они доступны в качестве плагина. Сразу же дам ссылку, вы можете их скачать в виде <a href="http://www.charnad.com/files/sfpropeltoggler/sfPropelTogglerPlugin-1.0.0b.tgz">PEAR package</a> и просто <a href="http://www.charnad.com/files/sfpropeltoggler/sfPropelTogglerPlugin-1.0.0b.zip">zip-архив</a>. Дальше я расскажу как этим плагином пользоваться.<span id="more-511"></span></p>
<p>Вообще, по правилам PEAR все инструкции написаны в README. Но там по-английски. А тут я приведу русскую инструкцию. Итак.<br />
1. Надо или установить плагин, как PEAR пакет, или распаковать архив в папку plugins. Папка с плагином должна называться sfPropelTogglerPlugin. После этого вызовите команду symfony 'plugin:publish-assets' чтобы картинки из плагина скопировались в папку web/sfPropelTogglerPlugin. Если ничего не скопировалось - проверьте название папки плагина.<br />
2. В settings.yml вашего приложения впишите в пункт enabled_modules: [default, sfPropelToggler]. Если вы этого не сделаете - будет выскакивать ошибка о том, что модуль не активирован.<br />
3. В том файле, где будете подключать тогглер напишите</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">use_helper<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Toggler'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>4. Собственно сам переключатель может быть вставлен 2мя способами. Первый:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> toggler<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'table_name'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'field'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'field_name'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$item</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> <span style="color: #0000ff;">'state'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$item</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getState</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Где table -имя таблицы, field - поле, id - первичный ключ записи, а state - текущее состояние переключателя.<br />
Второй способ через объект:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">echo</span> object_toggler<span style="color: #009900;">&#40;</span><span style="color: #000088;">$object</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'field_name'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Где object - объект Пропела, а field_name - поле, которе будем переключать.
</p>
<p>На этом этапе у вас все должно заработать. Если же нет - спрашивайте в комментариях.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-plagin-sfpropeltoggler-100b/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Symfony: порядок записей в таблице</title>
		<link>http://www.charnad.com/blog/symfony-poryadok-zapisej-v-tablice/</link>
		<comments>http://www.charnad.com/blog/symfony-poryadok-zapisej-v-tablice/#comments</comments>
		<pubDate>Sat, 02 May 2009 10:17:27 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[работа]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=488</guid>
		<description><![CDATA[Этим постом я отвечаю на вопрос в комментариях о том, как я реализовал стрелки вверх и вниз для категорий. Перейдем к делу У меня в базе данных введен в таблице специальный столбик, называемый order_num. Он как раз и определяет порядковый номер записи в таблице. По нажатию на кнопке вверх (я называю эту процедуру promote), порядковый [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt=""/>Этим постом я отвечаю на вопрос в комментариях о том, как я реализовал стрелки вверх и вниз для <a href="http://www.charnad.com/blog/symfony-kategorii-i-podkategorii/">категорий</a>. Перейдем к делу<span id="more-488"></span></p>
<p>У меня в базе данных введен в таблице специальный столбик, называемый order_num. Он как раз и определяет порядковый номер записи в таблице. По нажатию на кнопке вверх (я называю эту процедуру promote), порядковый номер текущей записи меняется местами с порядковым ближайшим большим порядковым номером. Обратная процедура (demote) меняет с ближайшим меньшим.</p>
<p>Обращу ваше внимание на то, что этот пример сделан не для категорий а для контентных страниц (что сути не меняет), к тому же учитывается parent_id, то есть можно менять порядок внутри категории не затрагивая другие.</p>
<p><strong>Promote:</strong></p>

<div class="wp_syntax"><div 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> executePromote<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$page_id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getRequestParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'page_id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$connection</span> <span style="color: #339933;">=</span> Propel<span style="color: #339933;">::</span><span style="color: #004000;">getConnection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$promoting_RS</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$connection</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT order_num, parent_id FROM static_pages WHERE page_id='<span style="color: #006699; font-weight: bold;">{$page_id}</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$promoting</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$promoting_RS</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span>PDO<span style="color: #339933;">::</span><span style="color: #004000;">FETCH_ASSOC</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$promoting_num</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$promoting</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'order_num'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$promoting_parent</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$promoting</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'parent_id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$promoting_num</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">2</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;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'static_pages/index'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$demoting_num_RS</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$connection</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;SELECT MAX(order_num) AS order_num, page_id FROM static_pages WHERE parent_id='<span style="color: #006699; font-weight: bold;">{$promoting_parent}</span>' AND order_num &lt; '<span style="color: #006699; font-weight: bold;">{$promoting_num}</span>' GROUP BY NULL&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$demoting</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$demoting_num_RS</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span>PDO<span style="color: #339933;">::</span><span style="color: #004000;">FETCH_ASSOC</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$demoting_num</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$demoting</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'order_num'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;UPDATE static_pages SET order_num = CASE
   WHEN page_id = '&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$page_id</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;' THEN '&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$demoting_num</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;'
   WHEN parent_id='<span style="color: #006699; font-weight: bold;">{$promoting_parent}</span>' AND order_num='<span style="color: #006699; font-weight: bold;">{$demoting_num}</span>' THEN '&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$promoting_num</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;'
   END
   WHERE page_id = &quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$page_id</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot; OR (parent_id=<span style="color: #006699; font-weight: bold;">{$promoting_parent}</span> AND order_num=<span style="color: #006699; font-weight: bold;">{$demoting_num}</span>)&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$connection</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</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;">redirect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'static_pages/index'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">return</span> sfView<span style="color: #339933;">::</span><span style="color: #004000;">NONE</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

</p>
<p>Мы берем id из запроса, потом запросом ищем максимальный order_num, который меньше текущего, и потом запросом меняем их местами. Не забудьте ставить WHERE в UPDATE. На основе этого, думаю demote легко дописать самому. <br /> P.S> Поле не должно быть UNIQUE, я так и не придумал как одним запросом менять значения между собой в UNIQUE поле. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-poryadok-zapisej-v-tablice/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Symfony: переключатели</title>
		<link>http://www.charnad.com/blog/symfony-pereklyuchateli/</link>
		<comments>http://www.charnad.com/blog/symfony-pereklyuchateli/#comments</comments>
		<pubDate>Fri, 24 Apr 2009 14:20:35 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[togglers]]></category>
		<category><![CDATA[переключатели]]></category>
		<category><![CDATA[работа]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=482</guid>
		<description><![CDATA[Давно я не брал в руки шашек. То есть не писал про symfony. А разработка продолжается. Сайт фактически готов, остаются мелкие доделки, доработка напильником и все такое. О "переключателях" или "тогглерах"(togglers), или не знаю как еще их назвать я уже давно хотел написать. Ну вот и пришло время, получайте. Итак что же за переключатели такие? [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" /> Давно я не брал в руки шашек. То есть не писал про symfony. А разработка продолжается. Сайт фактически готов, остаются мелкие доделки, доработка напильником и все такое. О "переключателях" или "тогглерах"(togglers), или не знаю как еще их назвать я уже давно хотел написать. Ну вот и пришло время, получайте.<span id="more-482"></span></p>
<p>Итак что же за переключатели такие? Допустим у нас есть сайт, а у него база данных, а в базе данных таблица, а в таблице поле, которое принимает только 2 значения - 0 и 1. Такие поля делаются типа TINYINT(1). Берем пример из жизни. Одно такое поле отвечает за то, разрешено ли пользователю входить в систему или нет. И если вдруг надо нам попереключать часть пользователей, то надо залезать в свойства каждого и менять, потом сохранять. А мне захотелось жить красивее и придумал я переключатели.</p>
<p><img style="margin-right: 10px;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/togglers/overview.png" alt="Список пользователей"/></p>
<p>Вот так примерно выглядит список пользователей. Зеленая галочка и красный крестик и есть переключатели. Что сделать чтобы переключить пользователя? Просто кликнуть на них! По клику отправляется AJAX запрос, меняет поле в базе данных и по результатам меняет картинку. Красиво, удобно, быстро. А теперь о том, как это сделано.</p>
<p>Для каждого пользователя в таблице нам надо вставить партиал (partial), который будет отображать картинку. Для формирования таблицы мы foreach перебираем пользователей и вот код partial для переключателя.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt;div id=&quot;active_<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$user</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</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> include_partial<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'activity'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$user</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'state'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$user</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'is_active'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;/div&gt;</pre></div></div>

<p>Как видно в него мы передаем 2 параметра, это id пользователя и его текущий статус. В самом партиалле находится следующий код:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> 
<span style="color: #000088;">$field</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'IsActive'</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;div align=&quot;center&quot; id=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$field</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'_'</span><span style="color: #339933;">.</span><span style="color: #000088;">$id</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
<span style="color: #000000; font-weight: bold;">&lt;?php</span>
include_component<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'main'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'toggler'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
  <span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'table'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'sfGuardUser'</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'state'</span> <span style="color: #339933;">=&gt;</span> sfGuardUserPeer<span style="color: #339933;">::</span><span style="color: #004000;">retrieveByPK</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getIsActive</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
  <span style="color: #0000ff;">'field'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$field</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;/div&gt;</pre></div></div>

<p>Здесь $field - имя поля в базе данных. В партиалле создается div с названием $field_$id, куда будет присылаться ответ. Ну а дальше вызывается компонент main/toggler, который и будет собственно переключать. Компоненту мы передаем id пользователя, имя таблицы, текущее состояние и имя поля.
</p>
<p>На этом подключение переключателя к модулю завершено. То есть вам надо всего лишь вызвать partial из шаблона, а в partiall'e подправить названия поля и таблицы. Все очень просто и быстро. Ну а собственно что в компоненте main/toggler? А там вот что:<br />
<strong>components.class.php</strong></p>

<div class="wp_syntax"><div 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> executeToggler<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//i just call _toggler.php partial</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p><strong>_toggler.php</strong></p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$update</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$field</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'_'</span><span style="color: #339933;">.</span><span style="color: #000088;">$id</span><span style="color: #339933;">;</span>
sfApplicationConfiguration<span style="color: #339933;">::</span><span style="color: #004000;">getActive</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">loadHelpers</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Javascript'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$image_name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$state</span><span style="color: #009900;">&#41;</span>? <span style="color: #0000ff;">'active.png'</span> <span style="color: #339933;">:</span> <span style="color: #0000ff;">'inactive.png'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> link_to_remote<span style="color: #009900;">&#40;</span>image_tag<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/images/icons/admin/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$image_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span> <span style="color: #009900;">&#40;</span>
   <span style="color: #0000ff;">'url'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'main/toggle?id='</span><span style="color: #339933;">.</span><span style="color: #000088;">$id</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&amp;table='</span><span style="color: #339933;">.</span><span style="color: #000088;">$table</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&amp;field='</span><span style="color: #339933;">.</span><span style="color: #000088;">$field</span><span style="color: #339933;">,</span>
   <span style="color: #0000ff;">'update'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$update</span>
<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Мы формируем $update - поле, куда вернем ответ. А в виде ответа мы возвращаем... переключатель. Нам надо подгрузить хелпер Javascript (обратите внимание, что надо с большой буквы писать, иначе ничего не получится. симфони требует соблюдения регистра). И с помощью хелпера генерим аяксовую ссылку на экшен, который уже и будет переключать.</p>
<p>Что же получается? Итак общая картинка такая. Мы подключаем partial, который вызывает компонент, который генерит шаблон выдавая нам аяксовую ссылку на действие (action). А экшен переключает нам поле, и рендерит тот же самый компонент.</p>

<div class="wp_syntax"><div 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> executeToggle<span style="color: #009900;">&#40;</span>sfWebRequest <span style="color: #000088;">$request</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</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: #339933;">-&gt;</span><span style="color: #004000;">isXmlHttpRequest</span><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: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderText</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Error. XMLHttpRequests only.'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000088;">$id</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$table</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'table'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$field</span> <span style="color: #339933;">=</span>  <span style="color: #000088;">$request</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'field'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$peer</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">normalizeName</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$table</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'Peer'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$method</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ReflectionMethod<span style="color: #009900;">&#40;</span><span style="color: #000088;">$peer</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'retrieveByPK'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$object</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$method</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">invoke</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">NULL</span><span style="color: #339933;">,</span> <span style="color: #000088;">$id</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$setter</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'set'</span><span style="color: #339933;">.</span><span style="color: #990000;">ucfirst</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$getter</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'get'</span><span style="color: #339933;">.</span><span style="color: #990000;">ucfirst</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$setter</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$state</span> <span style="color: #339933;">=</span> <span style="color: #339933;">!</span><span style="color: #000088;">$object</span><span style="color: #339933;">-&gt;</span><span style="color: #000088;">$getter</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #b1b100;">return</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">renderPartial</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'main/toggler'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'id'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$id</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'state'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$state</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'table'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$table</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'field'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$field</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
protected <span style="color: #000000; font-weight: bold;">function</span> normalizeName<span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/[^a-zA-Z0-9]/'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">' '</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ucwords</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$name</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">' '</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">return</span> <span style="color: #000088;">$name</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Принимаем только аяксовые запросы, из запроса получаем таблицу, поле и имя Propel Peer-класса для управления таблицей. Имя таблицы мы "нормализуем", т.к. симфони не использует, например, подчеркиваний в названии Peer-классов. Ну а дальше, с помощью рефлексии мы вызываем метод для того, чтобы получить объект, над которым производим действия. Геттеры и сеттер имеют стандартные названия и их рефлексить нам не надо. После чего в ответ рендерим тот же самый компонент, который вернет нам картинку с аяксовой ссылкой на то же самое действие.
</p>
<p>Я догадываюсь, что это не так просто понять. Если будет совсем не в моготу - задавайте вопросы в комментариях.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-pereklyuchateli/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Апдейт класса wp-poster</title>
		<link>http://www.charnad.com/blog/apdejt-klassa-wp-poster/</link>
		<comments>http://www.charnad.com/blog/apdejt-klassa-wp-poster/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 09:47:36 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-poster]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=447</guid>
		<description><![CDATA[Долго-долго не было апдейтов, но вот пора настала. Изменилось в общем-то немного. По-прежнему надо дописать FAQ и Manual, по-прежнему куча нереализованных фишек.. но движение какое-то есть. Рассказывать мне особо нечего, просто повешу ссылку. http://www.charnad.com/wp-poster/ Прошу писать мне идеи, багрепорты и предложения.]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/code_wp_poster.png" alt="wp-poster" />Долго-долго не было апдейтов, но вот пора настала. Изменилось в общем-то немного. По-прежнему надо дописать FAQ и Manual, по-прежнему куча нереализованных фишек.. но движение какое-то есть. Рассказывать мне особо нечего, просто повешу ссылку.</p>
<p><a href="http://www.charnad.com/wp-poster/">http://www.charnad.com/wp-poster/</a></p>
<p>Прошу писать мне идеи, багрепорты и предложения.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/apdejt-klassa-wp-poster/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Symfony: теги</title>
		<link>http://www.charnad.com/blog/symfony-tegi/</link>
		<comments>http://www.charnad.com/blog/symfony-tegi/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 15:24:00 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=416</guid>
		<description><![CDATA[Продолжаю серию постов про разработку на симфони. На этот раз задача состояла в том, чтобы сделать администрирование тегов. Задача:" все теги можно редактировать на одной странице, теги можно только редактировать и удалять, если тег после редакции совпадает с уже существующим - они склеиваются". Ну что ж, поехали. Почти сразу у меня возникла идея использовать input_in_place_editor. [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt=""/>Продолжаю серию постов про разработку на симфони. На этот раз задача состояла в том, чтобы сделать администрирование тегов. Задача:" все теги можно редактировать на одной странице, теги можно только редактировать и удалять, если тег после редакции совпадает с уже существующим - они склеиваются". Ну что ж, поехали.<span id="more-416"></span></p>
<p>Почти сразу у меня возникла идея использовать input_in_place_editor. То есть табличка, в ней теги, тыкаешь на ячейку, появляется поле редактирования, изменения происходят аяксово. С самим in_place_editor возникло немало сложностей из-за его опций. Сделать табличку и насовать в каждую ячейку по эдитору несложно. Не забудьте, надо облачить это все в див, который будет обновляться. Мы же хотим показывать сохраненный тег.</p>
<p>Первое, с чем мне пришлось столкнуться - эффект затухания. Это очень красиво, когда наводишь на элемент, который можно редактировать, фон загорается цветом, и медленно затухает, когда уводишь мышку. Изначально фон загорается желтым, а так как админка у меня выдержана в цветах Админ-генератора, то есть синем, то и цвет надо поменять. Однако, изменив цвет на <span style="background-color: white;">'#eef'</span>, я обломался. Затухания не было. Фон сначала загорался, а потом через время менял свой цвет на изначальный. И только позже, случайно я догадался расписать цвет полностью на <span style="background-color: white;">'#efefff'</span>.</p>
<p>Следующим моментом стало изменение текстов сохранения. То есть тот текст, который написан на элементе пока идет аякс запрос. Нашел опцию, поставил значение, и... ничего не работает. Оказалось, что некоторые опции (а они задаются ассоциативным массивом) надо задавать особенно. Например опцию 'save_text' надо не просто заключать в кавычки (потому что это строка), а еще и добавлять кавычки внутри самой строки. Иначе это дело парсится без кавычек. Тупизм, неужели создаетли Protoype'а не могли сами ставить кавычки? Приходится теперь писать так:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #0000ff;">'savingText'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'\'Сохранение...\''</span></pre></div></div>

</p>
<p>Кнопочку удаления так же сделал дивом, но это просто. Position: relative, height: 0px, align: right; Надо заметить, что на время редактирования тега, кнопочку надо скрывать, иначе она уезжает вниз и портит вид. А делается это с помощью опции 'onEnterEditMode'. Вот так:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #0000ff;">'onEnterEditMode'</span> <span style="color: #339933;">=&gt;</span> 
<span style="color: #0000ff;">&quot;function(form, value) { $('delete_&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$tag</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tag_id'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;').hide(); }&quot;</span></pre></div></div>

</p>
<p>Ну и наконец, сделать надо было системку, которая находит дубликаты тегов. А сделал я так: при сохранении тега, я нахожу ВСЕ теги с таким названием. Если такой тег один (которы мы только что сохранили), то все прекрасно, а если нет, тогда в цикле генерим 2 запроса. Один UPDATE, другой DELETE. UPDATE'ом, все товары, которые были привязаны к дубликату тега перепривязываем к самому первому найденному. Он в итоге остается у нас единственным. А DELETE'ом, удаляем дубликаты. Вот так вот:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">add</span><span style="color: #009900;">&#40;</span>TagsPeer<span style="color: #339933;">::</span><span style="color: #004000;">TITLE</span><span style="color: #339933;">,</span> <span style="color: #000088;">$value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$duplicates</span> <span style="color: #339933;">=</span> TagsPeer<span style="color: #339933;">::</span><span style="color: #004000;">doSelect</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//В качестве итогового тега берем самый первый</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$duplicates</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$original</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$duplicates</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$query_update</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;UPDATE tags_bouquets SET tag_id='{<span style="color: #006699; font-weight: bold;">$original-&gt;getTagId</span>()}' WHERE tag_id IN(&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$query_delete</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;DELETE FROM tags WHERE tag_id IN (&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$pass_first</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$duplicates</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$duplicate</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pass_first</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$pass_first</span> <span style="color: #339933;">=</span> <span style="color: #009900; font-weight: bold;">false</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: #000088;">$query_update</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$duplicate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTagId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">','</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$query_delete</span> <span style="color: #339933;">.=</span> <span style="color: #000088;">$duplicate</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getTagId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</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>
  <span style="color: #000088;">$query_delete</span> <span style="color: #339933;">=</span> <span style="color: #990000;">rtrim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query_delete</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">');'</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$query_update</span> <span style="color: #339933;">=</span> <span style="color: #990000;">rtrim</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$query_update</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">');'</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$conn</span> <span style="color: #339933;">=</span> Propel<span style="color: #339933;">::</span><span style="color: #004000;">getConnection</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$conn</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'BEGIN; '</span><span style="color: #339933;">.</span><span style="color: #000088;">$query_update</span><span style="color: #339933;">.</span><span style="color: #000088;">$query_delete</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'COMMIT;'</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;">getUser</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setFlash</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'notice_duplicated'</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: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

</p>
<p>Результат на картинке. Легкая синева - это как раз затухание фона, я специально мышкой повозил.<br />
<img src="http://www.charnad.com/blog/wp-content/uploads/pictures/flower_tags.png" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-tegi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Symfony: категории и подкатегории</title>
		<link>http://www.charnad.com/blog/symfony-kategorii-i-podkategorii/</link>
		<comments>http://www.charnad.com/blog/symfony-kategorii-i-podkategorii/#comments</comments>
		<pubDate>Fri, 06 Mar 2009 09:39:40 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[работа]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=394</guid>
		<description><![CDATA[Этот пост не совсем про симфони. На самом деле я опишу, как реализовывал категории и подкатегории для сайта над которым тружусь уже около месяца. Но так как сам сайт создается на symfony, то без нее тут никуда. Задача стояла примерно такая: для удобной навигации и поиска по товарам их нужно отнести к различным категориям и [...]]]></description>
			<content:encoded><![CDATA[<p><img class="oppic" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt=""/>Этот пост не совсем про симфони. На самом деле я опишу, как реализовывал категории и подкатегории для сайта над которым тружусь уже около месяца. Но так как сам сайт создается на symfony, то без нее тут никуда. Задача стояла примерно такая: для удобной навигации и поиска по товарам их нужно отнести к различным категориям и подкатегориям. Количество как первых, так и вторых может быть бесконечно. Единственное ограничение - уровень вложенности, он равен двум. В тех.задании категории и подкатегории были описаны двумя таблицами. Я думаю, что если бы последовал этому - я бы сэкономил пару-тройку часов, однако же, мне пришла в голову идея сделать все в одной таблице. Ведь по сути эти сущности ничем не отличаются, только что подкатегории имеют родительские категории.</p>
<p><span id="more-394"></span></p>
<p>По моему плану в поле, обозначающем предка в базе данных у всех должен стоять id родительской категории, а у собственно родительских - 0. Сказано - сделано, создана таблица, заполнена тестовыми данными. Заказчик обрисовал в ТЗ форму редактирования примерно так:</p>
<div><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/categories_task.png" alt="" align="center" /></div>
<p>Стрелочки вверх и вниз редактируют порядок категорий. Плюсики - добавление категории или подкатегории.</p>
<p>Обрисовав примерную форму в Admin Generator'e в симфони, я скопировал все сгенерированные файлы в папку модуля, удалил generator.yml, то есть дальше модуль был полностью под моим контролем. Конечно, симфони генерит много необязательного кода, чтобы его убрать требуется время. Например мне сейчас совсем не нужна интернационализация, поэтому я старательно убрал все __() функции и подключения хелперов. Так же сократил количество файлов, мне не нужны были партиаллы header, footer, а некоторые я просто объединил. В итоге у меня оказалось всего 3 партиалла и 2 файла темплейтов.</p>
<p>Тут, собственно, и начинается самое интересное. Чтобы не переписывать шаблоны полностью, я не хотел терять функционала Propel'a и доставал все значения из базы именно им. Но вот тут возник вопрос: "Как вывести массив объектов, возвращенных Пропелом, так, чтобы подкатегории шли сразу за своей категорией?". Решение я придумал довольно быстро - нужно было построить дерево. И вот что я сделал:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$tree</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>
<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$element</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   <span style="color: #000088;">$parentId</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getParentId</span><span style="color: #009900;">&#40;</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;">$parentId</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$tree</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'root'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$element</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getCatId</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$element</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: #000088;">$tree</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'branches'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$parentId</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$element</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Поясню. Если в массиве встречается элемент, у которого $parentId == 0, значит это родительская категория и мы кладем ее среди корневых элементов в $tree['root'][-ид-категории-]. Если же $parentId не 0, значит это подкатегория, и мы кладем ее в одну из веток $tree['branches']['-ид-родителя'][]. Поэтому теперь в темплейте, я могу писать 2 вложенных foreach. Во внешнем я перебираю $tree['root'], а во внутреннем $tree['branches'][-ид-текущего-родителя-]. Код приводить не буду - там много лишних деталей, суть же, надеюсь, я передал достаточно понятно.<br />
Отступ для подкатегорий, кстати, делается так:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#sf_admin_container</span> <span style="color: #6666ff;">.sf_admin_subcat_row_0</span> td<span style="color: #3333ff;">:first-child </span><span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">20px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#sf_admin_container</span> <span style="color: #6666ff;">.sf_admin_subcat_row_1</span> td<span style="color: #3333ff;">:first-child </span><span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">padding-left</span><span style="color: #00AA00;">:</span> <span style="color: #933;">20px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
<span style="color: #cc00cc;">#sf_admin_container</span> <span style="color: #6666ff;">.sf_admin_subcat_row_0</span> td <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#eef</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>То есть применяем padding-left: 20px только для :first-child.</p>
<p>Следующим трудным моментом стало редактирование/сохранение/создание категорий. Дело все в том, что в данном модуле используется одна форма для редактирования существующих категорий или создания новой и используется функция get..OrCreate (.. - название модели). Так делается в админ генераторе по умолчанию. Идея эта хороша, однако тут мне надо было обрабатывать создание новой категории особенным способом. Если в запросе создания передается cat_id, значит мы создаем подкатегорию, а эта cat_id будет родительской, а если не передаем, значит создается родительская категория. Все было хорошо до тех пор, пока мне не пришлось передавать тот самый параметр cat_id. Проблема была в том, что он терялся среди редиректов и сабмитов. Поэтому при запросе на создание я делал setFlash('force_create', $cat_id). Причем тут 'force_create'? При том, что если я хочу создать категорию и передаю id - симфони ловит его и пытается послать меня не подкатегорию создавать, а родительскую редактировать. Потому что так работает get..OrCreate. Мне пришлось ее редактировать, чтобы при hasFlash('force_create') она создавала новую категорию. Ну и потом при сохранении я достаю этот Flash и вставляю как родительский id. Звучит, наверное, просто, но нервов пришлось потратить много, пока разобрался почему терялся id, как его не терять и как избежать конфликтов. Трудно все-таки, когда одна функция создает категории, подкатегории и редактирует существующие.</p>
<p>На этом приключения еще не закончились. Нужно было сделать управление порядком категорий и подкатегорий. Тут я позаимствовал код, который использовался для создания порядка в статических страницах и модифицировал с учетом того, что порядковый номер может быть одинаковый. Ведь у нас может быть первая подкатегория во многих категориях. В итоге я пришек к такому запросу, который апдейтил сразу оба значения</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$query</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;UPDATE categories SET order_num = CASE
       WHEN cat_id = '&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$cat_id</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;' THEN '&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$demoting_num</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;'
       WHEN parent_id='<span style="color: #006699; font-weight: bold;">{$promoting_parent}</span>'
          AND order_num='<span style="color: #006699; font-weight: bold;">{$demoting_num}</span>' THEN '&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$promoting_num</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;'
       END
       WHERE cat_id IN (&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$cat_id</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;)
          OR (parent_id=<span style="color: #006699; font-weight: bold;">{$promoting_parent}</span> AND order_num=<span style="color: #006699; font-weight: bold;">{$demoting_num}</span>)&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Вот так весело прошел день моей работы. В результате я получил вот такую симпатичную формочку</p>
<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/categories_result.png" alt="" /></p>
<p>Если вам понравился этот рассказ - пожалуйста, обязательно напишите комментарий. Дайте мне знать, что вам хочется чтобы я писал что-то подобное еще. Ну или не пишите, если не хотите, чтобы я продолжал.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-kategorii-i-podkategorii/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Symfony: динамический роутинг</title>
		<link>http://www.charnad.com/blog/symfony-dinamicheskij-routing/</link>
		<comments>http://www.charnad.com/blog/symfony-dinamicheskij-routing/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 12:31:07 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=388</guid>
		<description><![CDATA[Продолжаю посты про symfony. Сегодня сделаем динамический роутинг. То есть будем добавлять правила роутинга из php, минуя routing.yml. Это нужно, например, если вы хотите делать страницы вида http://site.com/page1, где page1 может быть создана, может быть удалена и прочее. Дело в том, что указать какой-то общий шаблон нельзя, потому что иначе он будет конфликтовать с дефолтным [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin-right: 10px;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" align="left" /><br />
Продолжаю посты про symfony. Сегодня сделаем динамический роутинг. То есть будем добавлять правила роутинга из php, минуя routing.yml. Это нужно, например, если вы хотите делать страницы вида http://site.com/page1, где page1 может быть создана, может быть удалена и прочее. Дело в том, что указать какой-то общий шаблон нельзя, потому что иначе он будет конфликтовать с дефолтным /:module. Что делать? А вот что. <span id="more-388"></span><br />
Идею я подсмотрел на одном из забугорных блогов, за что большое <a href="http://www.dfwtek.com/blog/129-dynamic-routes-in-symfony12.html">автору</a> спасибо. </p>
<p>Собственно для тех, кто не хочет ждать, а хочет кода - кладем это дело в frontendConfiguration.php:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> frontendConfiguration <span style="color: #000000; font-weight: bold;">extends</span> sfApplicationConfiguration <span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> configure<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;">dispatcher</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'routing.load_configuration'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'registerRoutes'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'listenToRoutingLoadConfigurationEvent'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">class</span> registerRoutes <span style="color: #009900;">&#123;</span>
  static <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> listenToRoutingLoadConfigurationEvent<span style="color: #009900;">&#40;</span>sfEvent <span style="color: #000088;">$event</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000088;">$routing</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$event</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getSubject</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$criteria</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Criteria<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">clearSelectColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$criteria</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">addSelectColumn</span><span style="color: #009900;">&#40;</span>StaticPagesPeer<span style="color: #339933;">::</span><span style="color: #004000;">LINK_NAME</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$pages</span> <span style="color: #339933;">=</span> StaticPagesPeer<span style="color: #339933;">::</span><span style="color: #004000;">doSelectStmt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$criteria</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$pages</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">fetch</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$routing</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prependRoute</span><span style="color: #009900;">&#40;</span>
      <span style="color: #0000ff;">'static_'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">,</span>
      <span style="color: #000000; font-weight: bold;">new</span> sfRoute<span style="color: #009900;">&#40;</span>
       <span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">,</span>
      <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
          <span style="color: #0000ff;">'module'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'main'</span><span style="color: #339933;">,</span> 
          <span style="color: #0000ff;">'action'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'static'</span><span style="color: #339933;">,</span> 
          <span style="color: #0000ff;">'page'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #666666; font-style: italic;">//with slash</span>
     <span style="color: #000088;">$routing</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prependRoute</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'static_'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'_with_slash'</span><span style="color: #339933;">,</span>
        <span style="color: #000000; font-weight: bold;">new</span> sfRoute<span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">'/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'/'</span><span style="color: #339933;">,</span>
          <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'module'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'main'</span><span style="color: #339933;">,</span> 
          <span style="color: #0000ff;">'action'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'static'</span><span style="color: #339933;">,</span> 
          <span style="color: #0000ff;">'page'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span>
     <span style="color: #009900;">&#41;</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: #009900;">&#125;</span></pre></div></div>

<p>Тут я из базы выбираю поля link_name, и создаю правила на их основе. Каким образом это дело крепится к инициализации роутов - я не знаю. На остальные вопросы отвечу в комментариях.</p>
<hr />
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/symfony-dinamicheskij-routing/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Документация Symfony</title>
		<link>http://www.charnad.com/blog/documentacia-symfony/</link>
		<comments>http://www.charnad.com/blog/documentacia-symfony/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 09:35:44 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=367</guid>
		<description><![CDATA[Сейчас по долгу службы я работаю над движком для одного сайта. И сделать я его решил с использованием фреймворка, о котором слышал много хорошего. Я говорю о Symfony. Заниматься копипастом хвалебных речей с других сайтов я не буду, сам писать подобное так же не буду. Скажу только, что поначалу мне было трудно разобраться. Я даже [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin-right: 10px;" src="http://www.charnad.com/blog/wp-content/uploads/pictures/symfony_logo.gif" alt="" align="left" />
<p>Сейчас по долгу службы я работаю над движком для одного сайта. И сделать я его решил с использованием фреймворка, о котором слышал много хорошего. Я говорю о Symfony. Заниматься копипастом хвалебных речей с других сайтов я не буду, сам писать подобное так же не буду. Скажу только, что поначалу мне было трудно разобраться. Я даже хотел все бросить и писать на своей простой MVC системке, но в итоге не бросил. Упорно читал мануалы, стал понимать принципы построения приложения с использованием симфони. Собственно тут я хочу лишь выложить ссылки, которые могут помочь тем, кто будет изучать symfony.</p>
<p>Конечно, ссылка номер 1 это ссылка на главный сайт: <a href="http://www.symfony-project.org/">http://www.symfony-project.org/<br />
</a>Там большое количество документации, которые стоит осилить. Я пожалел времени, начал рубить сплеча, однако сейчас все равно пришел к тому, что надо читать мануалы и я их читаю. И всем придется, кто хочет понять всю мощь этого фреймворка.</p>
<p>
Ссылка номер 2 - это ссылка на главный гайд "симфонистов" <a href="http://www.symfony-project.org/book/1_2/">The Book</a> (<a href="http://www.symfony-project.org/get/pdf/book-1.2-en.pdf">PDF</a>). Книга на английском. Методично рассказывается о всех сторонах фреймворка.</p>
<p>
Ссылка номер 3 - это практическое руководство, так называемые <a href="http://www.symfony-project.org/askeet/1_0/en/">Askeet</a> (<a href="http://www.symfony-project.org/get/pdf/askeet-1.0-en.pdf">PDF</a>) и <a href="http://www.symfony-project.org/jobeet/1_2/Propel/en/">Jobeet</a> (<a href="http://www.symfony-project.org/get/pdf/jobeet-1.2-propel-en.pdf">PDF</a>). Они обе используют <a href="http://propel.phpdb.org/trac/">Propel</a> в качестве ORM вендора (на есть вариант и для Doctrine). Имейте ввиду, что Askeet был написан для Symfony 1.0, а Jobeet для 1.2. В сети есть <a href="http://symfony.artsofte.ru/theme/list/title/Переводы">переводы</a> некоторых глав на русский.
</p>
<p>Это то, что стоит читать в первую очередь. Возможно я найду время перевести некоторые главы на русский, но не обещаю. Удачи вам в изучении.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/documentacia-symfony/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP: Случайное слово в тексте</title>
		<link>http://www.charnad.com/blog/php-sluchajnoe-slovo-v-tekste/</link>
		<comments>http://www.charnad.com/blog/php-sluchajnoe-slovo-v-tekste/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 11:08:37 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[работа]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=333</guid>
		<description><![CDATA[Я подумал, что было бы неплохо писать некоторые мелкие скриптики, которые я использую в своей работе. На сегодня скрипт, который случайное слово в тексте делает ссылкой. Я не буду расписывать как вам сделать форму и прочие мелочи, это, я думаю, вы и сами сможете. Далее собственно код.   Считаем, что вы проверили все данные из формы, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="PHP" src="http://static.php.net/www.php.net/images/php.gif" alt="" width="120" height="67" />Я подумал, что было бы неплохо писать некоторые мелкие скриптики, которые я использую в своей работе. На сегодня скрипт, который случайное слово в тексте делает ссылкой. Я не буду расписывать как вам сделать форму и прочие мелочи, это, я думаю, вы и сами сможете. Далее собственно код. <br />
<span id="more-333"></span><br />
 Считаем, что вы проверили все данные из формы, сделали все, что нужно, мы имеем в итоге текст ($text) и URL ($site), на который будет ссылаться слово.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//самая главная строка. берем слова от 4х букв кириллицей</span>
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/b[а-яА-Я]{4,}?b/'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$matches</span><span style="color: #339933;">,</span> PREG_OFFSET_CAPTURE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$matches</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #666666; font-style: italic;">//тут выдаем ошибку. можете сделать по-своему, например через trigger_error</span>
  <span style="color: #000088;">$errors</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Отсутствуют слова, которые можно сделать ссылкой.&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">continue</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #666666; font-style: italic;">//берем случайное слово и его позицию в тексте</span>
<span style="color: #000088;">$r</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$matches</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$word</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$position</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//разбиваем на куски: до слова, само слово и кусок после слова</span>
<span style="color: #000088;">$before_word</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$position</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$after_word</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$text</span><span style="color: #339933;">,</span> <span style="color: #000088;">$position</span> <span style="color: #339933;">+</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$word</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&lt;a href=&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$site</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;&gt;&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$matches</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$r</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;&lt;/a&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">//а потом склеиваем обратно</span>
<span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$before_word</span><span style="color: #339933;">.</span><span style="color: #000088;">$word</span><span style="color: #339933;">.</span><span style="color: #000088;">$after_word</span><span style="color: #339933;">;</span></pre></div></div>

<p>Все очень просто) Если у вас не находятся слова, хотя они есть, возможно вам нужно выставить локаль на русскую. Сделать это можно так</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">setlocale</span><span style="color: #009900;">&#40;</span>LC_ALL<span style="color: #339933;">,</span> <span style="color: #0000ff;">'ru_RU.CP1251'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Upd: прошу заметить, что для UTF кириллицы \b не подходит. Надо использовать последовательность \p{xx}. Смотреть тут: http://www.php.net/manual/en/regexp.reference.unicode.php</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/php-sluchajnoe-slovo-v-tekste/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Класс wp-poster</title>
		<link>http://www.charnad.com/blog/class-wp-poster/</link>
		<comments>http://www.charnad.com/blog/class-wp-poster/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 11:17:44 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wp-poster]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=179</guid>
		<description><![CDATA[Внимание! Этот пост устарел, новую информацию по классу смотреть тут:Апдейт класса wp-poster. Публикую класс для работы с WordPress через XML-RPC. На самом деле я не работаю с XML-RPC напрямую, более того, так не делает даже сам Вордпресс. Мы вместе с Вордпрессом используем класс IXR_Client. Существует множество разных API для постинга в блоги, такие как WordPress [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.charnad.com/blog/wp-content/uploads/pictures/code_wp_poster.png" alt="wp-poster" style="float: left; margin: 2px;"/><br />
<span style="color: #FF0000;">Внимание! Этот пост устарел, новую информацию по классу смотреть тут:</span><a href="http://www.charnad.com/blog/apdejt-klassa-wp-poster/">Апдейт класса wp-poster</a>.</p>
<p>Публикую класс для работы с WordPress через XML-RPC. На самом деле я не работаю с XML-RPC напрямую, более того, так не делает даже сам Вордпресс. Мы вместе с Вордпрессом используем класс IXR_Client. Существует множество разных API для постинга в блоги, такие как WordPress API , Blogger API, MetaWeblog API, MovableType API. В общем мой класс это реализация шаблона Фасад для упрощения использования этих API. </p>
<p>Эта версия - глубокая альфа, однако, она вполне рабочая. Что будет с ней дальше - фиг знает. Мне могут дать на работе задание совершенно не связанное с Вордпрессом и все, я уже не буду успевать работать над классом. Но пока все идет хорошо)</p>
<p>Сам класс можно скачать вот тут: <a href="http://www.charnad.com/stuff/wp-poster/wp-poster.zip">wp-poster.zip</a>. В комплекте идет требуемый IXR_Client.</p>
<p>Далее написано как его использовать:</p>
<p> <span id="more-179"></span></p>
<p>Вот простой пример использования моего класса.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #b1b100;">require</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/classes/wp_poster.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">require</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/classes/ixr_client.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$poster</span> <span style="color: #339933;">=</span> wp_poster<span style="color: #339933;">::</span><span style="color: #004000;">getInstance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$blog</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> wp_blog<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://site.ru/blog/xmlrpc.php'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'admin'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'password'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</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: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'description'</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: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_text_more'</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: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_allow_comments'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span> <span style="color: #0000ff;">'closed'</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// open|closed</span>
<span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_keywords'</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: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'categories'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'категория1,кат2'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'published'</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;">$post</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> wp_post<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$poster</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">post</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$blog</span><span style="color: #339933;">,</span> <span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Пара замечаний: &lt;ВАЖНО><strong>Вордпресс принимает UTF-8!</strong>&lt;/ВАЖНО>, так же категории не создаются автоматически, это не баг, это фича. Я позже сделаю мануал где опишу как создавать категории. (Это уже можно делать, если хотите поковыряйте код моего класса). Так же обратите внимание, что категории идут массивом, а теги строкой. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/class-wp-poster/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>Как проверить существует ли сайт</title>
		<link>http://www.charnad.com/blog/kak-proverit-sushhestvuet-li-sajt/</link>
		<comments>http://www.charnad.com/blog/kak-proverit-sushhestvuet-li-sajt/#comments</comments>
		<pubDate>Tue, 25 Nov 2008 11:03:34 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[curl]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[тесты]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=143</guid>
		<description><![CDATA[Мне потребовалось узнать, существуют ли сайты, которые есть в списке. Список большой (достали список всех доменов *.com на осень 2007, там около 55 миллионов доменов). Все конечно проверять нет смысла, но вот первые тысяч 10-100 нужно. Объемы понятное дело огромные, поэтому алгоритм тут будет играть большую роль. Мне на ум пришли три метода: curl, fopen [...]]]></description>
			<content:encoded><![CDATA[<p>Мне потребовалось узнать, существуют ли сайты, которые есть в списке. Список большой (достали список всех доменов *.com на осень 2007, там около 55 миллионов доменов). Все конечно проверять нет смысла, но вот первые тысяч 10-100 нужно. Объемы понятное дело огромные, поэтому алгоритм тут будет играть большую роль. Мне на ум пришли три метода: curl, fopen и get_headers. Поэтому я и решил проверить кто из них справится с задачей быстрее.</p>
<p><span id="more-143"></span></p>
<p>Далее написал код, который собственно и производит вычисления.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">ob_implicit_flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Выводить по мере поступления данных</span>
<span style="color: #990000;">error_reporting</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">//Буду варнинги, но нам их не надо</span>
<span style="color: #990000;">set_time_limit</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//Исполнять до победного конца</span>
&nbsp;
<span style="color: #000088;">$handle</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'dotcom_list'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'r'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//исходный файл</span>
&nbsp;
<span style="color: #000088;">$time_start</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span> and <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
<span style="color: #000088;">$buffer</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4096</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$site</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://www.'</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$buffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.com'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Checking:'</span><span style="color: #339933;">.</span><span style="color: #000088;">$site</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'... '</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$curl</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_init</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$site</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curl</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curl</span><span style="color: #339933;">,</span> CURLOPT_FOLLOWLOCATION<span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_exec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">curl_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$curl</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sites/'</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$buffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.txt'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a+'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">' Done!'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$time_end</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$time</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$time_end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$time_start</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Обработано: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$i</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' за '</span><span style="color: #339933;">.</span><span style="color: #000088;">$time</span><span style="color: #339933;">.</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$time_start</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span> and <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
<span style="color: #000088;">$buffer</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4096</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$site</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://www.'</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$buffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.com'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Checking:'</span><span style="color: #339933;">.</span><span style="color: #000088;">$site</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'... '</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$site_handler</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$site</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'r'</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;">$site_handler</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fread</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$site_handler</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1024</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$site_handler</span><span style="color: #009900;">&#41;</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: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sites/'</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$buffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.txt'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a+'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">' Done!'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$time_end</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$time</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$time_end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$time_start</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Обработано: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$i</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' за '</span><span style="color: #339933;">.</span><span style="color: #000088;">$time</span><span style="color: #339933;">.</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$time_start</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">feof</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #009900;">&#41;</span> and <span style="color: #000088;">$i</span> <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
<span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
<span style="color: #000088;">$buffer</span> <span style="color: #339933;">=</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">fgets</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$handle</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4096</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$site</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'http://www.'</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$buffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.com'</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Checking:'</span><span style="color: #339933;">.</span><span style="color: #000088;">$site</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'... '</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$headers</span> <span style="color: #339933;">=</span> <span style="color: #990000;">get_headers</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$site</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$headers</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$file</span> <span style="color: #339933;">=</span> <span style="color: #990000;">fopen</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'sites/'</span><span style="color: #339933;">.</span><span style="color: #990000;">strtolower</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$buffer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'.txt'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'a+'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fwrite</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #339933;">,</span> <span style="color: #000088;">$response</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">fclose</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$file</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">' Done!'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$time_end</span> <span style="color: #339933;">=</span> <span style="color: #990000;">microtime</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$time</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$time_end</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$time_start</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'Обработано: '</span><span style="color: #339933;">.</span><span style="color: #000088;">$i</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' за '</span><span style="color: #339933;">.</span><span style="color: #000088;">$time</span><span style="color: #339933;">.</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>И вот собственно результаты:<br />
10 сайтов:<br />
curl: Обработано: 10 за 15.06<br />
fopen: Обработано: 10 за 70.10<br />
get_headers: Обработано: 10 за 69.23</p>
<p>50 сайтов:<br />
curl: Обработано: 50 за 123.23<br />
fopen: Обработано: 50 за 288.16<br />
get_headers: Обработано: 50 за 249.84</p>
<p>100 сайтов:<br />
curl: Обработано: 100 за 195.53<br />
fopen: Обработано: 100 за 480.05<br />
get_headers: Обработано: 100 за 527.04</p>
<p>Вывод: curl! curl! curl!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/kak-proverit-sushhestvuet-li-sajt/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Книжку купил =)</title>
		<link>http://www.charnad.com/blog/knizhku-kupil/</link>
		<comments>http://www.charnad.com/blog/knizhku-kupil/#comments</comments>
		<pubDate>Mon, 24 Nov 2008 13:40:34 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Обо мне]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[книга]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=137</guid>
		<description><![CDATA[Купил я книжку "Профессиональное программирование на PHP" за авторством Джорджа Шлосснейгла. Это моя первая книжка по PHP, вторая книжка вообще по программированию. Вообще пдф-ка у меня была, просто с компа читать не очень удобно. В последнее время я книги больше с КПК читал, а с него пдф вообще читать невозможно. Так что вот. По ходу [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" src="http://www.bookvoed.ru/view_images_h.php?code=266268&amp;tip=2" alt="" width="150" height="228" /> Купил я книжку "Профессиональное программирование на PHP" за авторством Джорджа Шлосснейгла. Это моя первая книжка по PHP, вторая книжка вообще по программированию. Вообще пдф-ка у меня была, просто с компа читать не очень удобно. В последнее время я книги больше с КПК читал, а с него пдф вообще читать невозможно. Так что вот. По ходу прочтения буду описывать наиболее интересные вещи, встретившиеся мне в книжке.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/knizhku-kupil/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Постим в WordPress через XML-RPC ч.2. Категории, теги.</title>
		<link>http://www.charnad.com/blog/postim-v-wordpress-cherez-xml-rpc-ch2-kategorii-tegi/</link>
		<comments>http://www.charnad.com/blog/postim-v-wordpress-cherez-xml-rpc-ch2-kategorii-tegi/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 07:46:00 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=131</guid>
		<description><![CDATA[Внимание! Этот пост устарел, новую информацию по классу для постинга смотреть тут:Апдейт класса wp-poster. Я уже писал о том, как публиковать записи в WordPress по протоколу XML-RPC. Теперь я продолжу эту тему, добавив некоторые подробности и детали. В предыдущем посте я посылал довольно простую структуру, сегодня мы усложним задачу добавив теги и категории. Собственно код: [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #FF0000;">Внимание! Этот пост устарел, новую информацию по классу для постинга смотреть тут:</span><a href="http://www.charnad.com/blog/apdejt-klassa-wp-poster/">Апдейт класса wp-poster</a>.</p>
<p>Я уже  <a href="http://www.charnad.com/blog/publikuem-v-blog-na-wordpress-cherez-xml-rpc/">писал</a> о том, как публиковать записи в WordPress по протоколу XML-RPC. Теперь я продолжу эту тему, добавив некоторые подробности и детали.</p>
<p><span id="more-131"></span><br />
В предыдущем посте я посылал довольно простую структуру, сегодня мы усложним задачу добавив теги и категории. Собственно код:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$objects</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$object</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IXR_Client<span style="color: #009900;">&#40;</span><span style="color: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'script'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cp1251'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #339933;">,</span><span style="color: #000088;">$object</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'description'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cp1251'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #339933;">,</span><span style="color: #000088;">$object</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'announce'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_text_more'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cp1251'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #339933;">,</span><span style="color: #000088;">$object</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'content'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_allow_comments'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cp1251'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'closed'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// open|closed</span>
    <span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_keywords'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cp1251'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #339933;">,</span>getSomeTags<span style="color: #009900;">&#40;</span><span style="color: #000088;">$object</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tags'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #990000;">mt_rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">4</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$someCats</span> <span style="color: #339933;">=</span> <span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'cp1251'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'utf-8'</span><span style="color: #339933;">,</span> getSomeCats<span style="color: #009900;">&#40;</span><span style="color: #000088;">$object</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'categories'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'categories'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span><span style="color: #000088;">$someCats</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Получаем список категорий. Если для поста заданы несуществующие категории - создаем их.
     */</span>
    <span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;metaWeblog.getCategories&quot;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$siteinfo</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: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</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;">$res</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$cat</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$cats_array</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$cat</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'categoryName'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000088;">$diff</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_values</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">array_diff</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'categories'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cats_array</span><span style="color: #009900;">&#41;</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: #339933;">!</span><span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$diff</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #990000;">strlen</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$diff</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</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: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$diff</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$cat</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #000088;">$cat_structure</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$cat</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;wp.newCategory&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$siteinfo</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: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cat_structure</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: #339933;">!</span><span style="color: #000088;">$result</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                    <span style="color: #990000;">die</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">iconv</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;cp1251&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;utf-8&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;Категория '<span style="color: #006699; font-weight: bold;">{$cat}</span>' не создана! &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getErrorMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</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: #009900;">&#125;</span> <span style="color: #666666; font-style: italic;">// если все категории есть - создавать не надо</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #009933; font-style: italic;">/**
     * Постим
     */</span>
    <span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;metaWeblog.newPost&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$siteinfo</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: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content_struct</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</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;">$result</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$responces</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'OK'</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;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$responces</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #b1b100;">elseif</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getErrorMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #000088;">$responces</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':'</span><span style="color: #339933;">,</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getErrorMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</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: #000088;">$responces</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getErrorMessage</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
<span style="color: #000088;">$responce</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'&lt;br&gt;'</span><span style="color: #339933;">,</span><span style="color: #000088;">$responces</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$responce</span><span style="color: #339933;">;</span></pre></div></div>

<p>Теперь собственно пояснения.</p>
<h4>Собираем данные</h4>
<p>Во первых у нас есть массив siteinfo:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">14</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;id&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;23&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;name&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;allstell&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;url&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">19</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;http://site.ru/&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;script&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">29</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;http://site.ru/xmlrpc.php&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;username&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;admin&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;password&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">16</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;password&quot;</span> 
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>А так же массив объектов - постов, которые будем посылать в вордпресс:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;uid&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;915&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;title&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Название поста&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;announce&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Краткий анонс текста, показывается до 'Читать далее...'&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;content&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">24</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;Полный текст, показывается после нажатия 'Читать далее'&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;tags&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">52</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;теги, еще теги, много тегов&quot;</span> 
    <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">&quot;categories&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=&gt;</span> string<span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">34</span><span style="color: #009900;">&#41;</span> <span style="color: #0000ff;">&quot;категория1, категория2, категория3&quot;</span> 
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Перебирая в цикле массив объектов, мы копируем нужные значения в $content_struct. Будьте внимательны, <b>теги передаются строкой, а категории массивом</b>. Я много нервов потерял полагая, что категории передаются так же строкой, как и теги.<br />
Вы наверняка заметили, что используются 2 функции для выборки тегов и категорий getSomeTags и getSomeCats. Они очень простые, но я приведу их код:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
* Получает строку с тегами и отдает $amount случайных
*
* @param string $str
* @param string $amount
* @return string
*/</span>
<span style="color: #000000; font-weight: bold;">function</span> getSomeTags<span style="color: #009900;">&#40;</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span> <span style="color: #000088;">$amount</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$array</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</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;">$amount</span> <span style="color: #339933;">&gt;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$str</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000088;">$keys</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array_rand</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #339933;">,</span> <span style="color: #000088;">$amount</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">&lt;</span><span style="color: #000088;">$amount</span><span style="color: #339933;">;</span> <span style="color: #000088;">$i</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$output</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$array</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span><span style="color: #000088;">$keys</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">return</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">','</span><span style="color: #339933;">,</span><span style="color: #000088;">$output</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Функция getSomeCats работает абсолютно так же. (По секрету говоря она просто вызывает функцию getSomeTags, то есть является алиасом.) То есть мы разбиваем строку в массив по запятым (будьте внимательны, в своем коде я беру теги из базы, где они уже форматированы в виде "тег1,тег2,тег 3". То есть между началом/концом тега и запятой пробелов нет. Из массива тегов выбираем случайно несколько и обратно собираем в строку. Обратите внимание, на <b>$array[(int)$keys[$i]]. Если тут не преобразовывать в int, то будет выдавать ошибку</b>. Скорее всего это костыль, вероятно есть более правильные решения, но у меня не хватает времени искать еще варианты.</p>
<h4>Категории</h4>
<p>Если постить и при этом указать несуществующую категорию, то пост уйдет в "Без категории". Поэтому нужно категории создавать.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$res</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;metaWeblog.getCategories&quot;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000088;">$siteinfo</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: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Мы получаем все категории, после чего с помощью <a href="http://ru2.php.net/array_diff">array_diff</a> выбираем категории указанные в siteinfo, но отсутствующие в списке категорий с сайта. И конечно же потом перебираем все категории, которые нужно создать.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$cat_structure</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'name'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$cat</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;wp.newCategory&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$siteinfo</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: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$cat_structure</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Теперь категории создаются, и мы можем постить)</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;metaWeblog.newPost&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$siteinfo</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: #000088;">$siteinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'password'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content_struct</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>На этом пока все. Надеюсь я выкрою время и напишу класс для упрощения этих задач.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/postim-v-wordpress-cherez-xml-rpc-ch2-kategorii-tegi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Публикуем в блог на wordpress через XML-RPC</title>
		<link>http://www.charnad.com/blog/publikuem-v-blog-na-wordpress-cherez-xml-rpc/</link>
		<comments>http://www.charnad.com/blog/publikuem-v-blog-na-wordpress-cherez-xml-rpc/#comments</comments>
		<pubDate>Mon, 17 Nov 2008 20:17:05 +0000</pubDate>
		<dc:creator>CharnaD</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[xml-rpc]]></category>

		<guid isPermaLink="false">http://www.charnad.com/?p=119</guid>
		<description><![CDATA[Если кому-нибудь хочется постить в свой блог не заходя в него, то вот вам решение. Требуется файл из стандартной поставки вордпресса wp-includes/class-IXR.php //создаем экземпляр объекта $client = new IXR_Client&#40;'http://www.url.com'&#41;; // массив параметров поста $content_struct&#91;'title'&#93; = 'название'; $content_struct&#91;'description'&#93; = 'описание, до ссылки _читать далее_'; $content_struct&#91;'mt_text_more'&#93; ='содержание будет доступно после ссылки _читать далее_'; &#160; $result = $client-&#62;query&#40;&#34;metaWeblog.newPost&#34;, [...]]]></description>
			<content:encoded><![CDATA[<p>Если кому-нибудь хочется постить в свой блог не заходя в него, то вот вам решение. Требуется файл из стандартной поставки вордпресса wp-includes/class-IXR.php</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">//создаем экземпляр объекта</span>
<span style="color: #000088;">$client</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IXR_Client<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.url.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// массив параметров поста</span>
<span style="color: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'title'</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: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'description'</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: #000088;">$content_struct</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'mt_text_more'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span><span style="color: #0000ff;">'содержание будет доступно после ссылки _читать далее_'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$result</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;metaWeblog.newPost&quot;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'0'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'логин'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'пароль'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content_struct</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'1'</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;">$result</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$responce</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'OK'</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: #000088;">$responce</span> <span style="color: #339933;">=</span> <span style="color: #990000;">implode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">':'</span><span style="color: #339933;">,</span><span style="color: #000088;">$client</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">getResponse</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$responce</span><span style="color: #339933;">;</span></pre></div></div>

<p>Вот так просто.<br />
 (<a href="http://www.charnad.com/blog/postim-v-wordpress-cherez-xml-rpc-ch2-kategorii-tegi/">второй пост на эту же тему</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.charnad.com/blog/publikuem-v-blog-na-wordpress-cherez-xml-rpc/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
