Laravel

LaravelからWordPressに記事投稿する方法

スポンサーリンク

Laravelからワードプレスに記事投稿できないのか?

Laravel(8.x)を使用して、
WordPressの記事投稿が効率化できないか調査していたら
下記記事を見つけました。

まさしく私がやりたかったことで、とっても参考になりました。

コピペでOKとのことだったのですが、
参考記事からLaravel、WordPressともにバージョンが上がったためなのか、
どうもLaravelとWordPressの連携が上手くいかず小一時間格闘しました。

LaravelからWordPressに記事を投稿する方法を紹介します。

開発環境環境:
Laravel: 8.6
WordPress: 5.8.1

WordPress側の作業

WordPressでRest APIが使用出来るかを確認する。

WordPress 4.7 から「WP REST API」がデフォルトで有効になっているので、
問題ないと思いますが、有効かどうかの確認方法を説明します。


SafariやChromeなどブラウザに下記をURLを入力します
※(ご自身のドメイン)の箇所は適宜変更してください。

https://(ご自身のドメイン)/wp-json/wp/v2/posts

入力するとブラウザで文字がいっぱい表示されれば、
問題なしです。

ヨシ!

アプリケーションパスワードの設定

参考にした記事では、
WordPressにプラグイン「Application Passwords」をインストールしていたのですが、
最近のバージョンでは不要です。

「ユーザー」 > 「アプリケーションパスワード」で、
プラグインをインストールしなくとも設定が可能です。

Laravel側の作業

.envファイルに変数追加

.envに下記3行を追加します。
※括弧内は適宜変更してください。

WP_API_USERNAME=(WordPressのログインユーザー名)
WP_API_PASSWORD="(アプリケーションパスワード)"
WP_API_URL=https://(ご自身のドメイン)/wp/wp-json/wp/v2/posts

コンフィグファイルの設定

config/services.phpに下記情報を追記します。

<?php

return [

    // 省略

    'wordpress' => [
        'username' => env('WP_API_USERNAME'),
        'password' => env('WP_API_PASSWORD'),
        'url' => env('WP_API_URL'),
    ],

];

余談ですが、
config/services.phpで’wordpress’を定義するメリットは、
1つのLaravelシステムから複数のWordPressに投稿する場合、
機能拡張がやり易い点です。

’wordpress’の他に例えば’wordpress2’を定義すれば良いです。
サンプルコードは以下の通りです。

    'wordpress2' => [
        'username' => env('WP_API_USERNAME2'),
        'password' => env('WP_API_PASSWORD2'),
        'url' => env('WP_API_URL2'),
    ],

この場合、末尾が2の変数定義(別のWordPressのユーザー、アプリケーションパスワード、ドメイン情報)が必要なので、
.envに変数の追加が必要になります。

App/ChannelsにWordPressChannelを生成。

App直下にChannelsフォルダー作成して、
WordPressChannel.phpを生成します。

<?php

namespace App\Channels;

use Illuminate\Notifications\Notification;

class WordPressChannel
{
    /**
     * Send the given notification.
     *
     * @param  mixed  $notifiable
     * @param  \Illuminate\Notifications\Notification  $notification
     * @return void
     */
    public function send($notifiable, Notification $notification)
    {
        $result = $notification->toWordpress($notifiable);
        // $resultには、投稿された結果が入っています
        //dump($result);
    }
}

Notificationの生成

下記コマンドを実行してNotificationを生成します。

php artisan make:notification WordPressNotification

app/Notifications/WordpressNotification.phpというファイルが作成されるので、
下記を貼り付けて置き換えます。

<?php

namespace App\Notifications;

use App\Channels\WordpressChannel;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class WordPressNotification extends Notification
{
    use Queueable;

    private $post_data;

    public function __construct($post_data)
    {
        $this->post_data = $post_data;
    }

    public function via($notifiable)
    {
        return [WordpressChannel::class];
    }

    public function toWordpress($notifiable) {

        $api_url = config('services.wordpress.url');
        $username = config('services.wordpress.username');
        $password = config('services.wordpress.password');

        $data = $this->post_data;

        $headers = [
            'Authorization: Basic ' . base64_encode($username .':'. $password),
            'Content-Type: application/json',
        ];

        //////////////////////////
        //CURL処理
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $api_url );
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');            // post
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));   // jsonデータを送信
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);             // リクエストにヘッダーを含める
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt($ch, CURLOPT_HEADER, true );
        
        $response = curl_exec($ch);

        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
        $header = substr($response, 0, $header_size);
        $body = substr($response, $header_size);

        $result = json_decode($body, true); 

        curl_close($ch);

        return $result;

    }

}

参考サイトではfile_get_contentsが使用されていたのですが、
「failed to open stream: HTTP request failed! HTTP/1.0 401 Unauthorized」が発生して上手くいかなかったので、
上記サンプルコードのようにcURLを使用するようにコードを書き換えました。

使用方法としては適宜BladeでもControllerでも良いのですが、
use App\Notifications\WordPressNotification;を行い、
下記のように配列にデータをセットして、
‘wordpress’のWordPressNotificationで内容を送信します。

    $post_data = [
        'title' => ”タイトル",
        'content' => "記事の本文",
        'status' => "draft",
        'date' => date('Y-m-d H:i:s'),
        'slug' => "laravel-m-wp-test"
    ];

    //WPに送信
    \Notification::route('wordpress', null)->notify(new WordPressNotification($post_data));

まとめ:キモはcURL

Notificationを使用したので、
色々なフォルダーやファイルが必要になって大袈裟になっていますが、
キモはcurl_execなので、cURLあたりの処理を抜粋して実装すれば、
もっとシンプルにできると思います。

とりあえず問題なく動いているので、
これで当方は本番運用しています。

こちらもCHECK

プログラムコードイメージ
プログラムコードの書き方TOP3。メンテしやすさが肝心!

スポンサーリンク 10年弱PG・SEとして大手メーカーに常駐して自社開発の部門システムの運用保守・開発・設計・コンサルをしていました。 大手企業に常駐10年以上のSEが10年以上仕事で心掛けていたこと …

続きを見る

スポンサーリンク

関連コンテンツ

ポチッ押して応援してください!

にほんブログ村 IT技術ブログへ

-Laravel