Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl
czyli… "czy dałoby się…"
Jeden serwis "Matka"
Wiele serwisów "Dzieci" (to też WordPressy)
Kilka minut opóźnienia
i inne drobne szczególiki
…
Każde "dziecko" odpytuje co parę minut "matkę"
Musimy nauczyć "dzieci" odpytywać
Ale jak?
Wtyczka, JSON API, XML-RPC, …
Od wersji 3.5 jest domyślnie włączone
Jest dość wydajne (requesty szybsze niż WordPress)
Jest używane, więc pewnie działa
Wysyłanie wpisu do "dzieci"
Sprawdź stan wpisu opublikowanego przez "dziecko"
Odśwież wpis
$client = new WP_HTTP_IXR_CLIENT( $url .'/xmlrpc.php' );
$result = $client->query( 'wp.newPost', array(0, $login, $password,
array(
'post_status' => $post->post_status,
'post_type' => $post->post_type,
'post_title' => $post->post_title,
...
'post_date_gmt' => new IXR_Date( strtotime($post->post_date_gmt) ),
'sticky' => is_sticky($post->ID),
'terms_names' => array(
'category' => $this->get_post_terms($post->ID, 'category'),
'post_tag' => $this->get_post_terms($post->ID, 'post_tag'),
),
'custom_fields' => $this->get_post_custom_fields($post->ID),
)
) );
if ( $result ) return $client->getResponse(); // id wstawionego wpisu
$client = new WP_HTTP_IXR_CLIENT( $url .'/xmlrpc.php' );
$result = $client->query( 'wp.getPost', array(
0,
$login,
$password,
$post_id
) );
if ( $result )
return $client->getResponse(); // wpis
$client = new WP_HTTP_IXR_CLIENT( $url .'/xmlrpc.php' );
$result = $client->query( 'wp.editPost', array(0, $login, $password,
$remote_post_id,
array(
'ID' => $remote_post_id,
'post_status' => $post->post_status,
...
'post_modified_gmt' => new IXR_Date( strtotime($post->post_modified_gmt) ),
'terms_names' => array(
'category' => $this->get_post_terms($post->ID, 'category'),
'post_tag' => $this->get_post_terms($post->ID, 'post_tag'),
),
'custom_fields' =>
$this->get_post_CFs($post->ID, $remote_post['custom_fields']),
)
) );
Podpinamy się pod filtr post_save
if ( wpis był już wysłany ) {
pobierz zdalny wpis
if ( zdalny nie był modyfikowany ) {
odśwież zdalny wpis
}
} else {
wyślij wpis i zapisz ID zdalnego
}
Co jeśli:
Wysłanie wpisu do wszystkich "dzieci" może potrwać
W post_save
zapisujemy jedynie zadania do wykonania później
Ustawiamy zadanie do wykonania co k
-minut
Za każdym razem pobieramy najnowsze taski z kolejki i je wykonujemy
Po wykonaniu każdego taska, zapamiętujemy jako wykonane
WP Cron może próbować wykonać wiele instancji jednocześnie
Czyli mógłby wysłać dany wpis kilka razy
transient
- czyli zmienna tymczasowa
Ustawiamy na początku przetwarzania i usuwamy na koniec
Jeśli przetwarzanie się nie skończy - to transient
i tak się odblokuje
if ( get_transient( 'nazwa_zmiennej' ) )
nic nie rób
set_transient( 'nazwa_zmiennej', '1', 20*60 );
przetwarzanie
delete_transient( 'nazwa_zmiennej' );
Umożliwia operowanie na:
Wpisach, Taksonomiach, Mediach, Komentarzach, Opcjach, Użytkownikach.
Jest szybsze niż cały WP, więc ułatwia ataki brute force, mające na celu uzyskanie dostępu do strony
Całe XML-RPC
add_filter('xmlrpc_enabled', '__return_false');
Poszczególne metody
function remove_xmlrpc_pingback_ping( $methods ) {
unset( $methods['pingback.ping'] );
return $methods;
}
add_filter( 'xmlrpc_methods', 'remove_xmlrpc_pingback_ping' );
Krzysiek Dróżdż
krzysiek@wpmagus.pl
WPmagus.pl