eRIZ's weblog

PHP, webdesign, Linux, Windows i inne, bo nie samym chlebem człowiek żyje

Zdalne publikowanie notek w WordPressie – XML-RPC w PHP

Jak wygląda życie zwykłego użytkownika WordPressa…? Otwarcie przeglądarki, logowanie, napisanie notki, publikacja. Zaraz, a gdyby np. skorzystać w tym celu z jakiejś zewnętrznej aplikacji? Owszem, jest tego w pęczki, nie ma sensu wynajdywanie koła na nowo. Jednak protokół, z którego korzystają zewnętrzne aplikacje, może być wykorzystany także w naszych bibliotekach oraz z poziomu samego PHP.

Pomysł na dzisiejszy wpis podsunął mi ^lukjarz. ;]

zdalne publikowanie?

Już od bardzo dawna w WordPressie została wprowadzona opcja publikowana przez specjalnie założoną skrzynkę mailową. Przyznam szczerze, że nie przyglądałem się jej szczegółowo, ale główna idea polega na publikowaniu treści każdego listu, który na nią dotrze. Jeśliby chcieć regularnie publikować z poziomu jakiegoś większego skryptu, to jest to jednak rozwiązanie okrężne, które – w dodatku – wymaga skorzystania z dodatkowego pośrednika. Jeśli padnie poczta, to klops -nie da się publikować wpisów.

Niektórzy szukają jakichś materiałów po prostu po terminie API. Niestety, w większości wyników są opisane funkcje WordPressa dla wtyczek. Owszem, na upartego można by taką napisać i np. pobierać treść z jakiegoś pliku co jakiś czas. Tylko po co tak kombinować…? Poza tym – rozwiązanie jest bardziej obejściem, ponieważ można bezpośrednio „nakazać” silnikowi blogowemu publikację notki.

XML-RPC

Właściwie, to od samego (dobrze pamiętam?) początku istnienia WordPress zawierał odpowiedni moduł do obsługi zapytań XML-RPC. Pewnie wielu z Was się zastanawiało, co to za tajemniczy plik xmlrpc.php odbiegający od typowej konwencji nazw wp-cośtam. Co to jest XML-RPC? Jest to pseudoprotokół działający po HTTP, którego składnia jest oparta na XML-u oraz nazwach funkcji obsługującego silnika. Skrypt korzystający z odpowiedniej biblioteki jest w stanie pracować jako serwer oraz klient – nie ma ograniczeń; to wywołanie oraz sposób napisania danej aplikacji określa, co i jak ma zostać wykonane. Dialog klienta z serwerem można porównać do zdalnego wywołania funkcji z danego języka programowania. Warstwa XML-RPC dba o to, aby odpowiednio zakodować nazwę metody oraz przesyłane informacje.

Na jednej ze stron Codexu silnika jest dostępny rozdział opisujący metody, które można wywołać za pośrednictwem XML-RPC w WordPressie. Tak naprawdę twórcy postanowili wykorzystać kilka popularnych „dialektów” w celu zwiększenia kompatybilności z już istniejącymi aplikacjami/bibliotekami służacymi do publikacji treści bez pośrednictwa przeglądarki. Aby w pełni wykorzystać możliwości WP, developerzy postanowili utworzyć dodatkowe funkcje, których nie udostępniają inne silniki. Są to zazwyczaj funkcje dotyczące obsługi komentarzy, autorów, kategorii, czy metody umożliwiające przesyłanie plików. Jeśli nazwy metod różnią się tylko nazwami API (inny prefiks), developerzy zalecają korzystanie z funkcji umieszczonych w przestrzeni nazw wp..

komunikacja

Owszem, można by było bezpośrednio dołączyć do skryptu biblioteki WP, ale czy to ma sens? Po co śmiecić skrypty, niepotrzebnie zżerać pamięć? Poza tym, nie ma możliwości dodania wpisów na innym fizycznym serwerze. Więc idealnym rozwiązaniem jest XML-RPC.

Najważniejszym elementem jest biblioteka, która będzie kodowała dane do formatu żądania XML-RPC. Można ją napisać samodzielnie (jest dostępna specyfikacja formatu) albo skorzystać z wielu gotowych. PHP posiada natywne rozszerzenie, które można dokompilować, ale jego użycie jest jednak nieintuicyjne. Będzie jednak szybsze (gdyż jest częścią interpretera).

Z racji tego, iż natywne rozszerzenie XML-RPC nie jest wszędzie dostępne, można posłużyć się biblioteką XML-RPC for PHP. Jest ona aktualizowana, co w przypadku niektórych jest sporym problemem. Dodatkowo, w paczce znajduje się obszerna dokumentacja oraz przykłady.

Ja skorzystam z tego, co daje WordPress. W katalogu wp-includes znajduje się plik class-IXR.php. To właśnie ona się nam przyda. Skupię się na samej publikacji wpisu, o to głównie przecież chodzi. [;

Pierwszym krokiem jest uaktywnienie XML-RPC w WordPressie. Wystarczy otworzyć opcje, publikacja i włączyć protokoły publikowania XML-RPC. Zacznijmy od szkieletu naszego prostego skryptu. Sprawdzimy nim, czy nasz skrypt prawidłowo się komunikuje z WordPressem:

query('demo.sayHello')){
echo $q->getErrorCode().': '.$q->getErrorMessage();
}

echo $q->getResponse();
?>

Powyższy kod powinien zwrócić Hello, co oznacza, że komunikacja z WP przebiega prawidłowo. I teraz kilka słów wyjaśnień, pomimo że kod do zbyt skomplikowanych nie należy. ;) W konstruktorze klasy IXR_Client wstawiamy URL do pliku xmlrpc.php naszego bloga. Główną funkcją, która powoduje wykonanie danego żądania jest query. Jako pierwszy parametr przyjmuje ona nazwę metody udostępnianej przez serwer. Pozostałe (opcjonalne parametry), to jej argumenty. Są one opisane w dokumentacji, wystarczy je po prostu podać po przecinku. Przy większości wywołań funkcji WP będziemy podawali co najmniej 4 parametry – nazwę metody, identyfikator bloga, login i hasło do panelu. Jeśli nie mamy kilku dzienników skonfigurowanych dla jednego skryptu (WordPress Multi User), będzie to po prostu dowolna wartość. Listę blogów oraz ich identyfikatory uzyskamy wywołując wp.getUsersBlogs. Wówczas bez identyfikatora, rzecz jasna. [;

Sprawdźmy autoryzację, wyświetlmy kategorie używane na blogu. Dane zwrócone przez tę metodę przydadzą się do wstawiania nowej notki.

query('wp.getCategories', 1, 'admin', '*********')){
echo $q->getErrorCode().': '.$q->getErrorMessage();
}

var_dump($q->getResponse());
?>

W odpowiedzi otrzymamy np. to:

array
0 =>
array
'categoryId' => string '1' (length=1)
'parentId' => string '0' (length=1)
'description' => string 'Uncategorized' (length=13)
'categoryName' => string 'Uncategorized' (length=13)
'htmlUrl' => string 'http://127.0.0.2/php/wordpress/?cat=1' (length=37)
'rssUrl' => string 'http://127.0.0.2/php/wordpress?feed=rss2&cat=1' (length=50)

prosta publikacja

Ok, komunikacja działa, nazwy też mamy, pora na właściwą publikację. Skorzystamy z protokołu opracowanego na potrzeby Blogger Google’a.

query('blogger.newPost', 'asd', 1, 'admin', '*******', 'hello World!', true)){
echo $q->getErrorCode().': '.$q->getErrorMessage();
}

var_dump($q->getResponse());
?>

Parametr przed identyfikatorem bloga, to „zgłoszenie” aplikacji. Jest to wymagane tylko dla macierzystej usługi i w naszym przypadku może to być dowolny ciąg znaków. Powyższy kod dodaje notkę o treści hello World!, bez tytułu i innych metadanych. Aby dodać tytuł, kategorię, czy ustawić zajawkę, skorzystamy z metaWeblogApi, a dokładniej metody metaWeblog.newPost. Jeśli chodzi o jej parametry, to wystarczą typowe – nazwa metody, ID bloga, login, hasło, dane notki oraz status wpisu (czy publikować, czy zapisać jako brudnopis).

Najważniejsza jest w tym przypadku konstrukcja, którą nazwałem danymi notki. Nie jest to nic innego, jak tablica asocjacyjna, która zawiera kilka kluczy. ;] Struktura posiada prawie identyczną konstrukcję, co pole wpisu w specyfikacji RSS 2.0 poszerzone o kilka pól. Koniec owijania w bawełnę, pora publikować.

'Hello World!', //tytuł
'description' => 'to będzie wstęp...', //zajawka
'mt_text_more' => 'treść wpisu', //treść
'categories' => array('Uncategorized'), //nazwy kategorii jako elementy tablicy
'mt_keywords' => array('tag1', 'tag2', 'tag'), // tagi
//'dateCreated' => date(DATE_RFC822, mktime(0, 0, 0, 1, 1, 2000)), //data publikacji wpisu
//'wp_password' => 'hasuo', //hasło wpisu
//'mt_allow_pings' => true, //zezwalać na pingbacki?
//'mt_allow_comments' => true, //a na komentarze?
);

if(!$q->query('metaWeblog.newPost', 1, 'admin', '*********', $note, true)){
echo $q->getErrorCode().': '.$q->getErrorMessage();
}

var_dump($q->getResponse());
?>

Jak zwykle, metoda getResponse po pomyślnym dodaniu notki, zwróci ID wpisu. Wpis został opublikowany. ;]

PS: niestety, nie udało mi się zmusić WordPressa do ustawienia konkretnej daty publikacji wpisu. Z komunikatów wynika, że jest jakiś błąd w WordPressie.

po publikacji

Przydałoby się jeszcze pobrać link do notki:

query('metaWeblog.getPost', 3, 'admin', '******')){
echo $q->getErrorCode().': '.$q->getErrorMessage();
}

var_dump($q->getResponse());
?>

Gdzie 3, to ID notki. Wartość zwrócona przez getResponse to tablica, która zawiera kilka ciekawych informacji. Ale jakich? To już zadanie domowe. [;

Podpowiem tylko, że w celu pobrania bezpośredniego linka do notki wystarczy:

getResponse();
echo $d['permaLink'];
?>

epilog

WordPress jest ciekawą platformą do publikacji różnego rodzaju treści. Tak naprawdę, z silnika blogowego zrodził się potwór, który na wielu polach nie ustępuje CMS-om z prawdziwego zdarzenia, takim jak np. Drupal, czy Joomla. Tylko od zestawu wtyczek i inwencji użytkownika zależy, co i jak będzie publikowane, a WordPress zadba o resztę.

PS. Wiem, że ostatnio rzadko publikuję, ale jak już pisałem – zmajstrowanie notki nieco czasu zabiera. Na tę poświęciłem parę godzin ze względu na testy oraz właściwie brak rzetelnej dokumentacji protokołu. Swoją drogą, przygotowuję coś specjalnego, myślę że warto poczekać. [;

14 komentarzy

dopisz swój :: trackback :: RSS z komentarzami

RSS z komentarzami :: trackback

Skomentuj

Możesz używać znaczników XHTML. Dozwolone są następujące tagi: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">

Wszystkie komentarze przechodzą przez moderację oraz filtry antyspamowe. Nie zostanie opublikowany komentarz, jeśli:

  • Jego treść obraża kogokolwiek.
  • W treści znajdują się wulgaryzmy i słownictwo ogólnie uznane za nieprzyzwoite.
  • Mam wątpliwości co do autora wpisu (Wszelkie anonimy są kasowane - niezależnie od zawartości - wpisz prawdziwy e-mail. Jeśli usunąłem, Twoim zdaniem, komentarz niesłusznie - daj znać). Zdarza się, iż sprawdzam kim jest komentujący.
  • Zawiera jakąkolwiek formę reklamy.

Warning: Undefined variable $user_ID in /usr/home/er1zpl/domains/eriz.pcinside.pl/public_html/weblog/wp-content/themes/inBlueDiary/comments.php on line 112

Szufladka