CakePHP2×WordPressでなんとかリレーション組んで記事とタグを表示させる

みなさんこんにちは!!

以前CakePHPとWordPressでアプリを組んだのでリレーションとか色々書いていこうと思います。 WordPressではデータを入力、保存するのみで、主なデータ表示はCakePHPで行いました。

WordPressのデータをCakePHPで取得するために設定する

CakePHPとWordPressはインストール済み、また記事は何個か入っている、タグも何個か設定してある前提でやっていきます。

今回やるのは「記事からその記事に結びついているタグを表示する」ことと「タグからそのタグが結びついている記事を表示する」ことです。 自分でもちょっとおかしいと思うところは結構ありますw

WordPressのデータベースの構造は以下を見ればわかります。 http://wpdocs.sourceforge.jp/データベース構造

CakePHPではきつそうな部分が混ざってますがそこはスルーしましょう。 ここでやりたいことは記事に対するタグを引っ張ってくることです。

それではやっていきましょう。 いじっていくテーブルは、wp_postswp_term_relationshipswp_term_taxonomywp_termsの4つです。 なのでそれに対応するModelを作っていきます。

wp_postswp_term_relationshipsを持っているので以下のように書きます。

Posts.php

App::uses('AppModel', 'Model');

class Post extends AppModel {

    public $primaryKey = 'ID';

    public $useTable = 'wp_posts';

    public $name = 'Post';

    public $tablePrefix = 'wp_';

    public $hasMany = array(
        'TermRelationship' => [
            'className' => 'TermRelationship',
            'foreignKey' => 'object_id'
        ]
    );
}

wp_term_relationshipsはこんな感じです。ちょっとつっこみたいのはよくわかる。。。

TermRelationship.php

App::uses('AppModel', 'Model');

class TermRelationship extends AppModel {

    public $useTable = 'wp_term_relationships';

    public $name = 'TermRelationship';

    public $tablePrefix = 'wp_';

    public $belongsTo = [
        'TermTaxonomy' => [
            'className' => 'WpTermTaxonomy',
            'foreignKey' => 'term_taxonomy_id',
        ]
    ];
}   

wp_term_taxonomy

TermTaxonomy.php

App::uses('AppModel', 'Model');
class WpTermTaxonomy extends AppModel {

    public $name = 'TermTaxonomy';

    public $useTable = 'wp_term_taxonomy';

    public $primaryKey = 'term_taxonomy_id';

    public $tablePrefix = 'wp_';

    public $belongsTo = [
        'WpTerm' => [
            'className' => 'WpTerm',
            'foreignKey' => 'term_id'
        ]
    ];

}

そして最後。wp_terms

Term.php

App::uses('AppModel', 'Model');

class Term extends AppModel {

    public $name = 'Term';

    public $primaryKey = 'term_id';

    public $tablePrefix = 'wp_';

    public $displayField = 'name';

    public $hasOne = [
        'TermTaxonomy' => [
            'className' => 'TermTaxonomy',
            'foreignKey' => 'term_taxonomy_id'
        ]
    ];

}

これで設定完了です!お疲れ様です!

動作確認・実際に表示してみる

それでは最後に動作確認をしてみましょう。 たくさんのRelationを使うときはContainableBehaviorが便利なのでAppModelで読み込んでおきましょう。

AppModel.php

App::uses('Model', 'Model');

class AppModel extends Model {

    public $actsAs = ['Containable'];

}

動作確認です。まずは記事からタグを引っ張りだす!

PostsController.php

App::uses('AppController', 'Controller');

class PostsController extends AppController {

    public function index(){
        $articles = ClassRegistry::init('Post')->find('all', 
            ['contain' => [
                'TermRelationship' => [
                    'TermTaxonomy' => [
                        'Term'
                    ]
                ]
            ]
        );
        debug($articles);
    }
}

階層の深い部分にありますがタグが一覧表示されていると思います!

ここまでわかれば簡単!タグから記事を表示しましょう。 PostsController.php

App::uses('AppController', 'Controller');

class PostsController extends AppController {

    public function index(){
        $tags = ClassRegistry::init('Term')->find('all', 
            ['contain' => [
                'TermTaxonomy' => [
                    'TermRelationship' => [
                        'Post'
                    ]
                ]
        );
        debug($tags);
    }
}

最後に

いかがでしたでしょうか。 少し無理やりでしたが、目標は達成出来たかと思います。 CakePHPのリレーションは「_id」がついているものを勝手につなげますが、それを利用したものと言えます。 もっと綺麗に実装出来そうですが、実際に実装していく場合は、findの条件の部分を覆い隠せば綺麗になると思います。

覆い隠す場合は以下の記事が参考になるかもしれません。

findせずにconditionsを返す、DRYなCakePHPのModel実装のススメ

CakePHPerなら持っておかねば!