WordPressプラグインを作ってみた(Personality Insightsによる記事の分析)

こんにちは、HACKNOTEのJunya.kです。
IBM WatsonのAPIとして提供されているPersonality Insightsを利用できる、WordPressのプラグイン機能を実装してみました。

WordPress環境構築

ある程度記事を書いてあるWebサイトに適用する場合のほうが多いと思いますが、一応書いておきます。
既存のWebサイトに適用するつもりの方は読み飛ばして下さい。

1.LAMP環境の構築

まずはLAMP(Linux,Apache,MySQL,PHP)環境を構築します。Amazon Linux 2であれば以下のコマンドで構築することができます。

$ ssh -i [公開鍵].pem ec2-user@[IPアドレス]
[ec2-user@ ~]$ sudo su -
[root@ ~]# amazon-linux-extras install php7.2
[root@ ~]# yum localinstall https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y
[root@ ~]# yum-config-manager --disable mysql80-community
[root@ ~]# yum-config-manager --enable mysql57-community
[root@ ~]# yum install -y httpd php mysql-community-server
[root@ ~]# systemctl start httpd mysqld
[root@ ~]# systemctl enable mysqld httpd
Created symlink from /etc/systemd/system/multi-user.target.wants/mysqld.service to /usr/lib/systemd/system/mysqld.service.
Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service.

これでLAMP環境が構築されました。WordPress用のMySQLデータベースを作成します。
デフォルトのパスワードを確認します。

# cat /var/log/mysqld.log | grep "localhost"
2018-08-07T01:47:41.008720Z 1 [Note] A temporary password is generated for root@localhost:[ここがパスワード]

データベースを整備していきます。

# mysql -uroot -p
[初期パスワードを入力]
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Defaultp@ssw0rd';
mysql> CREATE DATABASE wpa001;
mysql> CREATE USER wpa001@localhost IDENTIFIED BY 'Hogehoge@1234';
mysql> GRANT ALL ON wpa001.* TO wpa001@localhost IDENTIFIED BY 'Hogehoge@1234';
mysql> FLUSH PRIVILEGES;

2.WordPressインストール

WordPressをインストールしていきます。

[root@ ~]# cd /var/www/html/
[root@ html]# wget https://ja.wordpress.org/latest-ja.tar.gz
[root@ html]# tar -xzvf latest-ja.tar.gz
[root@ html]# rm latest-ja.tar.gz

ドキュメントルートの変更をします。

[root@ html]# vim /etc/httpd/conf/httpd.conf 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
# DocumentRoot: The directory out of which you will serve your
# documents. By default, all requests are taken from this directory, but
# symbolic links and aliases may be used to point to other locations.
#
DocumentRoot "/var/www/html/wordpress"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Webブラウザからサーバーに接続すればWordPressのインストールができるはずです。作成したユーザ情報、データベース情報を入力し、インストールします。
このとき、テーブル接頭辞に気をつけてください。あとでSQL文を発行する時に指定します。ここではwp00_としました。
詳しくはこの記事を参考にしてください。
以上でWordPress環境の構築が完了です。

Personality Insightsの利用

Personality Insightsの利用には利用の登録が必要です。
以下の記事にしたがって登録をしてください。
APIからPersonality insightsを使ってWordPressの投稿データを分析してみた

プラグイン作成

まずはデータベースがどのようになっているか見てみましょう。

[root@ ~]# mysql -uroot -p
Enter password: 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| wpa001             |
+--------------------+
5 rows in set (0.00 sec)

mysql> USE wpa001;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SHOW TABLES;
+-------------------------+
| Tables_in_wpa001        |
+-------------------------+
| wp00_commentmeta        |
| wp00_comments           |
| wp00_links              |
| wp00_options            |
| wp00_postmeta           |
| wp00_posts              |
| wp00_term_relationships |
| wp00_term_taxonomy      |
| wp00_termmeta           |
| wp00_terms              |
| wp00_usermeta           |
| wp00_users              |
+-------------------------+
12 rows in set (0.00 sec)

mysql> SHOW COLUMNS FROM wp00_posts;
+-----------------------+---------------------+------+-----+---------------------+----------------+
| Field                 | Type                | Null | Key | Default             | Extra          |
+-----------------------+---------------------+------+-----+---------------------+----------------+
| ID                    | bigint(20) unsigned | NO   | PRI | NULL                | auto_increment |
| post_author           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| post_date             | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_date_gmt         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content          | longtext            | NO   |     | NULL                |                |
| post_title            | text                | NO   |     | NULL                |                |
| post_excerpt          | text                | NO   |     | NULL                |                |
| post_status           | varchar(20)         | NO   |     | publish             |                |
| comment_status        | varchar(20)         | NO   |     | open                |                |
| ping_status           | varchar(20)         | NO   |     | open                |                |
| post_password         | varchar(255)        | NO   |     |                     |                |
| post_name             | varchar(200)        | NO   | MUL |                     |                |
| to_ping               | text                | NO   |     | NULL                |                |
| pinged                | text                | NO   |     | NULL                |                |
| post_modified         | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_modified_gmt     | datetime            | NO   |     | 0000-00-00 00:00:00 |                |
| post_content_filtered | longtext            | NO   |     | NULL                |                |
| post_parent           | bigint(20) unsigned | NO   | MUL | 0                   |                |
| guid                  | varchar(255)        | NO   |     |                     |                |
| menu_order            | int(11)             | NO   |     | 0                   |                |
| post_type             | varchar(20)         | NO   | MUL | post                |                |
| post_mime_type        | varchar(100)        | NO   |     |                     |                |
| comment_count         | bigint(20)          | NO   |     | 0                   |                |
+-----------------------+---------------------+------+-----+---------------------+----------------+
23 rows in set (0.00 sec)

wp00_postsというテーブルの中にpost_author(ユーザーID)やpost_content(本文)などの情報が入っていることが分かります。
この辺のデータを使ってPersonality Insightsに送るデータを作っていきます。

1.プラグインの作成

メニューに追加する形のプラグインを作成していきます。
プラグイン情報が入っている/var/www/html/wordpress/wp-content/pluginsにディレクトリを追加します。

[root@ ~]# cd /var/www/html/wordpress/wp-content/plugins/
[root@ pligins]# mkdir personality-insights
[root@ pligins]# cd personality-insights
[root@ personality-insights]# 

このディレクトリに以下のようにファイルを作成します。
最初に、プラグインの本体となるファイルです。
personalityinsights.php

//プラグイン情報
<?php
/*
  Plugin Name: Personality Insights
  Plugin URI:
  Description: Personality Insightsの表示
  Version: 1.0.0
  Author: TOWN
  Author URI:
  License: GPLv2
 */
?>

<?php
add_action('init', 'PersonalityInsights::init');

class PersonalityInsights
{
    static function init()
    {
        return new self();
    }

    function __construct()
    {
        if (is_admin() && is_user_logged_in()) {
            // メニュー追加
            add_action('admin_menu', [$this, 'set_plugin_menu']);
            add_action('admin_menu', [$this, 'set_plugin_sub_menu']);

        }
    }
    //メニューの設定
    function set_plugin_menu()
    {
        add_menu_page(
            'Personality Insights',           /* ページタイトル*/
            'Personality Insights',           /* メニュータイトル */
            'manage_options',         /* 権限 */
            'custom-index-banner',    /* ページを開いたときのURL */
            [$this, 'show_about_plugin'],       /* メニューに紐づく画面を描画するcallback関数 */
            'dashicons-format-gallery', /* アイコン see: https://developer.wordpress.org/resource/dashicons/#awards */
            99                          /* 表示位置のオフセット */
        );
    }
    function set_plugin_sub_menu()
    {

        add_submenu_page(                                                                                                                                  
            'custom-index-banner',  /* 親メニューのslug */                                                                                                 
            '設定',                                                                                                                                        
            '設定',                                                                                                                                        
            'manage_options',                                                                                                                              
            'custom-index-banner-config',                                                                                                                  
            [$this, 'show_config_form']);                                                                                                                  
    }
    //プラグイン本体                                                                                                                                                     
    function show_about_plugin()                                                                                                                           
    {                                                                                                                                                      
?>                                                                                                                                                         
      <h1>Personality Insights</h1>                                                                                                                        
      <p>Personality Insightsを利用します。</p>                                                                                                            
      <p>以下に分析したいユーザーのユーザーIDを入力し、「送信」を押してください。</p>                                                                            
      <form action="/wordpress/wp-content/plugins/personality-insights/getresult.php" method="post">                                                       
                  <input type="text" name="id" />
                  <br><input type="submit">

      </form>                                                                                                                                              

<?php                                                                                                                                                      
    }                                                                                                                                                      

} // end of class                                                                                                                                          

?>                                       

入力に対する操作を決定するファイルを作成します。
SQLデータベースに接続し、データベースに対して操作をします。
getresult.php

<?php
  //本文情報を格納するファイル
  $filename = '/var/www/html/wordpress/wp-content/plugins/personality-insights/maincontent.txt';

  //SQL接続
  $url = "localhost";
  $user = "root";
  $password = "Defaultp@ssw0rd";
  $database = "wpa001";

  $connect = mysqli_connect($url,$user,$password);
  $db = mysqli_select_db($connect,$database);

  //日本語化適用
  mysqli_query($connect,'SET NAMES utf8');

  $sql = "select * from wp00_posts";
  $result = mysqli_query($connect,$sql);

  //ユーザーIDが一致する場合のみ本文を追加
  while ($row = mysqli_fetch_assoc($result)) {
    if(htmlspecialchars($row["post_author"]) == $_POST['id']){
      //echo htmlspecialchars($row["post_content"]);
      $current = file_get_contents($filename);
      $current .= htmlspecialchars($row["post_content"]);
      file_put_contents($filename,$current);
    }
  }
  echo "\n";
  mysqli_free_result($result);
  mysqli_close($connect) or die("can't closed");

  //send.shを実行、Personality Insightsにデータ送信
  shell_exec("sh ./send.sh");

  //サイトに表示するためのテキストファイル
  $filename = '/var/www/html/wordpress/wp-content/plugins/personality-insights/final.txt';
  $content = file_get_contents($filename);
  echo $content;

  //send2.shを実行、final.txtを削除
  shell_exec("sh ./send2.sh");
?>

Personality Insightsにデータを送信し、ファイル管理をします。
send.sh

#!/bin/sh

curl -o final.txt -X POST -u "apikey:[自分のアカウントのAPI key]" --header "Content-Type: text/plain" --header "Content-Language: ja" --header "Accept: appl
ication/json" --data-binary "@/var/www/html/wordpress/wp-content/plugins/personality-insights/maincontent.txt" "https://gateway-tok.watsonplatform.net/personality-insights/a
pi/v3/profile?version=2017-10-13&consumption_preferences=true&raw_scores=true" |jq

rm -f maincontent.txt

最後に生成されるfinal.txtを削除するためのスクリプトファイルをおきます。
send2.sh

#!/bin/sh

rm -f final.txt

(この部分に関してはもっとうまい方法があるような感じがします。)

2.プラグインの実行

上記のようにファイルを作成するとWordPressのプラグインのメニューに自分で作成したプラグインが表示されます。



有効化を選択するとメニューにPersonality Insightsが追加されます。



試しにユーザーIDが2である投稿に対して分析をしてみます。





結果が表示されました!