TwitterAPIでホームタイムラインのツイートを取得して表示する

ホームタイムライン過去から遡って目に付いたツイートにリプしたらその直後にもっと情報量の多いツイートが流れていたことを知ってしまった時の顔してる。
はっ、自分のホームタイムラインのツイート上から30個くらい取ればダミー文章の出来上がりっ

概要

例えば、製品やユーザなどのデータに画像ファイルを関連付けたい時、OctoberCMSでは簡単にそのデータの管理ページに画像ファイルのアップロード・表示・管理機能が追加できる。意外にもドキュメントではまとまった説明がなかったのでここに記載する。

Screen Shot 2018-01-01 at 19.22.31.png

ステップ

  1. Configを設定
  2. モデルにリレーションを定義
  3. CRUD画面にファイルアップロードウィジェットを追加

前提

テーブル、モデル、CRUD画面は既に作成済み。

Configを設定する

まだ設定していない場合は config/filesystem.php にdisksを設定する。デフォルトで存在するが、下記に注意。

  • localを使用する場合、指定ディレクトリにweb serverユーザの書き込み権限がある。
  • s3などクラウドを使用する場合はクラウドサーバへの書き込みが可能な状態。

下記の例ではenv()を使用しているが、直書きでも問題ない。

config/filesystems.php
    'disks' => [

        'local' => [
            'driver' => 'local',
            'root'   => storage_path('app'),
        ],

        's3' => [
            'driver' => 's3',
            'key'    => env('AWS_ACCESS_KEY_ID'),
            'secret' => env('AWS_SECRET_ACCESS_KEY'),
            'region' => env('AWS_REGION'),
            'bucket' => env('AWS_S3_BUCKET'),
            'visibility' => 'public',
        ],
    ],

そして、ファイルアップロード関連の設定は config/cms.php のstorage.uploadsで行う。

config/cms.php
    'storage' => [

        'uploads' => [
            'disk'   => 'local',
            'folder' => 'uploads',
            'path'   => '/storage/app/uploads',
        ],

        // S3へを指定する場合は`path`はバケットへのURLを指定する必要がある
//        'uploads' => [
//            'disk'   => 's3',
//            'folder' => 'uploads',
//            'path'   => 'https://s3-ap-southeast-1.amazonaws.com/my-bucket/uploads',
//        ],

        ...
    ],

対象データのモデルにリレーションを定義する

OctoberCMSでは添付ファイルの情報は別のテーブルに保存される。ここで説明するようにOctoberCMSの添付ファイルのドキュメントに従えば、添付ファイルの情報は既存のsystem_filesテーブルに保存されるので、新たにテーブルを作成したり修正したりする必要はない。

対象のモデルクラスにattachOneまたはattachManyを追加する。下記の例ではProductというモデルクラスに$attachManyフィールドを設けてattachManyリレーションを定義している。リレーション名がimageでリレーションのモデルクラスをSystemModelsFileとしている。

models/Product.php
    public $attachMany = [
        'images' => 'SystemModelsFile'
    ];

CRUD画面にファイルアップロードウィジェットを追加する

BuilderプラグインのCRUD画面作成画面からでFileUpload controlを追加する。
Screen_Shot_2018-01-01_at_19_48_42.png

追加したウィジェットの設定でField nameをモデルクラスで定義したリレーション名に設定する。上記の場合、imagesになる。

ファイルが画像の場合は、Builderで生成されたyamlファイル(デフォルトでは<plugin_name>/models/<model_name>/fields.yaml)を開いて追加したフィールドのmodeimageにすると、サムネイルを表示してくれる。

fields:
    name:
        label: 'cocci.utility::backend.common.field.name.label'
        oc.commentPosition: ''
        span: auto
        required: true
        type: text
    display_name:
        label: 'cocci.utility::backend.common.field.display_name.label'
        oc.commentPosition: ''
        span: auto
        required: true
        type: text
    description:
        label: 'cocci.utility::backend.common.field.description.label'
        size: large
        oc.commentPosition: ''
        span: auto
        type: textarea
    images:
        label: Images
        oc.commentPosition: ''
        mode: image
        useCaption: true
        thumbOptions:
            mode: crop
            extension: auto
        span: auto
        type: fileupload

バグ対処方法

2018/1/1現在(build 431)、OctoberCMSにバグらしきものがあり、storage.uploads.diskが効かない。代わりにfilesystem.phpのdefaultが適用されてしまっている。が、修正されるまで比較的簡単・安全な方法で回避できる。

上記の説明ではSystemModelsFileをリレーションモデルに使用しているが、このクラスを拡張して修正を仕込む。1行目のnamespaceだけ適宜変更すれば下記を丸コピーでよい。

myplugin/models/File.php
<?php namespace PikanjiMypluginModels;

use Config;
use File as FileHelper;
use Storage;

class File extends SystemModelsFile
{
    /**
     * Returns true if storage.uploads.disk in config/cms.php is "local".
     * @return bool
     */
    protected function isLocalStorage()
    {
        return Config::get('cms.storage.uploads.disk') == 'local';
    }

    /**
     * Copy the local file to Storage
     * @return bool True on success, false on failure.
     */
    protected function copyLocalToStorage($localPath, $storagePath)
    {
        $disk = Storage::disk(Config::get('cms.storage.uploads.disk'));
        return $disk->put($storagePath, FileHelper::get($localPath), ($this->isPublic()) ? 'public' : null);
    }
}

そして、このクラスをattachOne/Manyで指定したSystemModelsFileの代わりに指定する。これで、storage.uploads.diskで指定した先にアップロードしたファイルが保存されるはずだ。

この修正は、SystemModelsFileのベースクラスOctoberRainDatabaseAttachFileのメソッドisLocalStoragecopyLocalToStorageをオーバーライドしている。元のメソッドはcms.storage.uploads.diskではなくfilesystem.defaultを見てしまっているからだ。

この問題はこのissueで報告しており、pull requestも出しているので、早く取り込んでもらいたい。

[紹介元] PHPタグが付けられた新着投稿 – Qiita TwitterAPIでホームタイムラインのツイートを取得して表示する

  • コメント

    1. 匿名希望
      2018/01/20(土) 01:03:54

      ホームタイムライン過去から遡って目に付いたツイートにリプしたらその直後にもっと情報量の多いツイートが流れていたことを知ってしまった時の顔してる。

    2. 匿名希望
      2018/01/20(土) 01:03:54

      はっ、自分のホームタイムラインのツイート上から30個くらい取ればダミー文章の出来上がりっ

    記事に戻る

関連記事