:-)
  • PHP 21.11.2008

    Внимание! Этот пост устарел, новую информацию по классу для постинга смотреть тут:Апдейт класса wp-poster.

    Я уже писал о том, как публиковать записи в WordPress по протоколу XML-RPC. Теперь я продолжу эту тему, добавив некоторые подробности и детали.


    В предыдущем посте я посылал довольно простую структуру, сегодня мы усложним задачу добавив теги и категории. Собственно код:

    foreach ($objects as $object) {
        $client = new IXR_Client($siteinfo['script']);
     
        $content_struct['title'] = iconv('cp1251', 'utf-8',$object['title']);
        $content_struct['description'] = iconv('cp1251', 'utf-8',$object['announce']);
        $content_struct['mt_text_more'] = iconv('cp1251', 'utf-8',$object['content']);
        $content_struct['mt_allow_comments'] = iconv('cp1251', 'utf-8','closed'); // open|closed
        $content_struct['mt_keywords'] = iconv('cp1251', 'utf-8',getSomeTags($object['tags'],mt_rand(4,5)));
        $someCats = iconv('cp1251', 'utf-8', getSomeCats($object['categories'],2));
        $content_struct['categories'] = explode(',',$someCats);
        /**
         * Получаем список категорий. Если для поста заданы несуществующие категории - создаем их.
         */
        $res = $client->query("metaWeblog.getCategories", 0, $siteinfo['username'], $siteinfo['password']);
        if ($res) {
            foreach ($client->getResponse() as $cat) {
                $cats_array[] = $cat['categoryName'];
            }
            $diff = array_values(array_diff($content_struct['categories'], $cats_array));
            if (!empty($diff) && strlen($diff[0])) {
                foreach ($diff as $cat) {
                    $cat_structure = array('name' => $cat);
                    $result = $client->query("wp.newCategory", '0', $siteinfo['username'], $siteinfo['password'], $cat_structure);
                    if (!$result) {
                        die(iconv("cp1251","utf-8","Категория '{$cat}' не создана! ").$client->getErrorMessage());
                    }
                }
            } // если все категории есть - создавать не надо
        }
        /**
         * Постим
         */
        $result = $client->query("metaWeblog.newPost", '0', $siteinfo['username'], $siteinfo['password'], $content_struct, '0');
        if ($result) {
            $responces[] = 'OK';
        } else {
            if (is_array($client->getResponse())) {
                $responces[] = implode(':', $client->getResponse());
            }
            elseif (is_array($client->getErrorMessage())) {
                $responces[] = implode(':',$client->getErrorMessage());
            } else {
                $responces[] = var_dump($client->getErrorMessage());
            }
        }
     
    }
    $responce = implode('<br>',$responces);
    echo $responce;

    Теперь собственно пояснения.

    Собираем данные

    Во первых у нас есть массив siteinfo:

    array(14) { 
        ["id"]=> string(2) "23" 
        ["name"]=> string(8) "allstell" 
        ["url"]=> string(19) "http://site.ru/" 
        ["script"]=> string(29) "http://site.ru/xmlrpc.php" 
        ["username"]=> string(5) "admin" 
        ["password"]=> string(16) "password" 
    }

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

    array(10) { 
        ["uid"]=> string(3) "915" 
        ["title"]=> string(7) "Название поста" 
        ["announce"]=> string(12) "Краткий анонс текста, показывается до 'Читать далее...'" 
        ["content"]=> string(24) "Полный текст, показывается после нажатия 'Читать далее'" 
        ["tags"]=> string(52) "теги, еще теги, много тегов" 
        ["categories"]=> string(34) "категория1, категория2, категория3" 
    }

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

    /**
    * Получает строку с тегами и отдает $amount случайных
    *
    * @param string $str
    * @param string $amount
    * @return string
    */
    function getSomeTags($str, $amount) {
        $array = explode(',',$str);
        if ($amount > count($array)) {
            return $str;
        }
        $keys = array_rand($array, $amount);
     
        for ($i = 0; $i<$amount; $i++) {
            $output[] = $array[(int)$keys[$i]];
        }
    return implode(',',$output);
    }

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

    Категории

    Если постить и при этом указать несуществующую категорию, то пост уйдет в "Без категории". Поэтому нужно категории создавать.

    $res = $client->query("metaWeblog.getCategories", 0, $siteinfo['username'], $siteinfo['password']);

    Мы получаем все категории, после чего с помощью array_diff выбираем категории указанные в siteinfo, но отсутствующие в списке категорий с сайта. И конечно же потом перебираем все категории, которые нужно создать.

    $cat_structure = array('name' => $cat);
    $result = $client->query("wp.newCategory", '0', $siteinfo['username'], $siteinfo['password'], $cat_structure);

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

    $result = $client->query("metaWeblog.newPost", '0', $siteinfo['username'], $siteinfo['password'], $content_struct, '0');

    На этом пока все. Надеюсь я выкрою время и напишу класс для упрощения этих задач.

    Tags: , ,

  • Comments are closed.