Edited at

WordPress APIで画像を登録しようとしたらハマったが多少解決したので共有

More than 1 year has passed since last update.

WordPress APIってご存知ですか?

APIを使ってWordPressの記事を操作出来ます。

Oauthなどの認証が必要ですが、記事の新規投稿等も出来ます。

記事の投稿はチュートリアル通り出来ましたし、カテゴリの登録はその流れで出来ました。

また、記事の投稿にカスタムフィールドの更新も込みだとしても1点ハマるポイントはありましたが、

なんとか実装出来ました。

(カスタムフィールド名が日本語名だと閲覧は出来ても、更新はできません...)<中身は日本語でもOK

今回、画像を登録するにあたっては相当苦労させられましたが、Teratailでのご支援もいただき、まだまだ課題はあるけれどなんとか最低限の実装は出来ました。

そもそも実装例が英語も含めて探してPHP系では全然見つかりません...

Teratailではベストアンサーをつけてしまうと、結果等をまとめることができなかったので、こちらにまとめてノウハウを記載しようと思います。

ちなみにCakephpの2.9.x系をメインで書いていて、Wordpress側はversion4.8系です。

CakephpのOauthプラグインとして、Consuming OAuth-enabled APIs with CakePHPを使っていますが、プラグイン側をスクラッチで改良してます。。。

プラグインの使い方とかは別のところを見てください。。。


NewsController.php

$client = $this->createClient2();

$oauth_token="--------";//各自取得の上編集してね
$oauth_token_secret="-----";//各自取得の上編集してね
$result = $client->postMultipartFormData2($oauth_token,$oauth_token_secret,'https://xxx.net/wp-json/wp/v2/media',array('contents[]' =>$path),array("title" => "Title media","description" => "description media"));



OAuthClient.php


//書き換えたところだけ記載しています

public function postMultipartFormData2($accessTokenKey, $accessTokenSecret, $url, array $paths, array $postData = array()) {
$accessToken = new OAuthToken($accessTokenKey, $accessTokenSecret);
$request = $this->createRequest('POST', $url, $accessToken, array());
$authorization = str_replace('Authorization: ', '', $request->to_header());

return $this->doPostMultipartFormData2($url, $authorization, $paths, $postData);
}
//TwitterのAPIでこのプラグインを使っているので、2として書き換えています。
//ただそれだけです。ここはdoPostMultipartFormData2に投げるところがキモなので、そこだけ書き換えです。

private function doPostMultipartFormData2($url, $authorization, $paths,$data) {
// App::uses('String', 'Utility');
debug("aiueo");
App::uses('CakeText', 'Utility');
//$boundary = String::uuid();//CakePHP2.9なので、CakeTextに書き換えないとエラーが出るのでもともと下記のように書き換えています。
$boundary = CakeText::uuid();

$body = "--{$boundary}\r\n";

// foreach ($data as $key => $value) {
//$body .= "Content-Disposition: form-data; name=\"{$key}\"\r\n";
//$body .= "\r\n";
//$body .= "{$value}\r\n";
//$body .= "--{$boundary}\r\n";
// } //使えないので消しちゃいました

foreach ($paths as $key => $path) {
$filename=basename($path);
$nakami=file_get_contents($path);

$body .= "Content-Disposition: form-data; name=\"{$key}\"; attachment; filename=\"{$path}\"\r\n";
$body .= "\r\n";
$body .= file_get_contents($path)."\r\n";
$content_length = filesize($path);
$body .= "--{$boundary}--\r\n";
}

debug($body);
$socket = new HttpSocket();
$result = $socket->request(array('method' => 'POST',
'uri' => $url,
'header' => array(
'Authorization' => $authorization,
'cache-control' => "no-cache",
'Content-Disposition'=> "attachment; filename=\"{$filename}\"\r\n",
'Content-Type'=> "image/jpeg boundary={$boundary}",
'Content-Length'=> $content_length,
"caption" => "Titre media"
),
)
'body' => $nakami
));
$this->fullResponse = $result;

return $result;
}


とりあえずこのようにしたら画像のアップロードがきちんとできました。

が...登録するメディアのキャプションとかタイトルとかが記載できていません。

そこが今後の課題ですね。

そこも解決できたらまた書こうと思います。