DirectCloud の API クライアントを作って Laravel で使えるようにする

DirectCloud というクラウドストレージサービスがあるのですが、比較的リーズナブルな料金でファイル単位の世代バックアップができたり、SSO ログインができたりして、オンプレの NAS をリプレースしたい方には割とおすすめです。そのまま使うのでも十分なのですが、API を公開しているので、PHP で API クライアントを作り、さらに Laravel で使えるように Flysystem のドライバを作ってみました。

API クライアント

インストール

インストールは Composer で行います

composer require gn-office/directcloud-api

使い方

use GNOffice\DirectCloud\Client;

$client = new Client([$service, $service_key, $code, $id, $password]);
// or
$client = new Client([$service, $service_key, $access_key]);
// or
$client = new Client($access_token);

//create a folder
$client->createFolder($node, $name);

//list a folder
$client->getList($node);

API の利用にはアクセストークンが必要なため、API リファレンスに記載の通り、あらかじめ必要な設定を行ってください。クライアントを作成したら、利用したいメソッドを選んで実行するだけなのですが、DirectCloud の API 特有の概念として、フォルダのノードとファイルの識別コードがあり、API の実行時にこれらを指定する必要があります。一般的なフォルダのパスの形式からノードを取得するのも割と面倒なので、直接 API クライアントを使うよりも、次に紹介する Flysystem のアダプタを使ったほうが便利かもしれません。

Flysystem アダプタ

インストール

こちらも Composer でインストールします。API クライアントも一緒にインストールされます。

composer require gn-office/flysystem-directcloud

使い方

Laravel 以外で使う場合は、以下のような感じになります。

use League\Flysystem\Filesystem;
use GNOffice\DirectCloud\Client;
use GNOffice\FlysystemDirectCloud\DirectCloudAdapter;

$client = new Client([$service, $service_key, $code, $id, $password]);
// or
$client = new Client([$service, $service_key, $access_key]);

$adapter = new DirectCloudAdapter($client);

$filesystem = new Filesystem($adapter);

// ファイルの書き込み
try {
    $filesystem->write($path, $contents, $config);
} catch (FilesystemException | UnableToWriteFile $exception) {
    // handle the error
}

// フォルダ内のフォルダ・ファイルの一覧の取得
try {
    $listing = $filesystem->listContents($path, $recursive);

    /** @var \League\Flysystem\StorageAttributes $item */
    foreach ($listing as $item) {
        $path = $item->path();

        if ($item instanceof \League\Flysystem\FileAttributes) {
            // handle the file
        } elseif ($item instanceof \League\Flysystem\DirectoryAttributes) {
            // handle the directory
        }
    }
} catch (FilesystemException $exception) {
    // handle the error
}

Laravel で使う場合には、app\Providers\AppServiceProvider.php

<?php

namespace App\Providers;

use GNOffice\DirectCloud\Client as DirectCloudClient;
use GNOffice\FlysystemDirectCloud\DirectCloudAdapter;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use League\Flysystem\PathPrefixing\PathPrefixedAdapter;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Storage::extend('directcloud', function (Application $app, array $config) {
            $adapter = new DirectCloudAdapter(new DirectCloudClient([
                $config['service'],
                $config['serviceKey'],
                $config['accessKey']
            ]));

            if (! empty($config['prefix'])) {
                $adapter = new PathPrefixedAdapter($adapter, $config['prefix']);
            }

            return new FilesystemAdapter(
                new Filesystem($adapter, $config),
                $adapter,
                $config
            );
        });
    }
}

を追記したうえで、config\filesystems.php

<?php

return [
    'disks' => [
        'directcloud' => [
            'driver'     => 'directcloud',
            'service'    => env('DIRECTCLOUD_SERVICE'),
            'serviceKey' => env('DIRECTCLOUD_SERVICE_KEY'),
            'accessKey'  => env('DIRECTCLOUD_ACCESS_KEY'),
        ],
    ],
];

を追加し、 .env に必要な情報を追加してください。あとは、

use Illuminate\Support\Facades\Storage;

$file = $request->file('image');
$disk = Storage::disk('directcloud');
$disk->putFileAs('path/to', $file, $file->getClientOriginalName());

みたいな感じでファイルを操作することができます。

パッケージとして公開しているものの、テストが書けていなくてお恥ずかしい限りですが、そのあたりはおいおいということで。。

この記事を書いた人
グッドネイバー

“ Webに悩むお客さまの「よき隣人」でありたい ” をモットーに、Web システム開発(主に Laravel)、Web マーケティング支援の仕事をしています。お仕事のご依頼・ご相談はこちらからお気軽にどうぞ。