月別アーカイブ: 2015年7月

PHPでDropBoxの共有フォルダにファイルをアップロードして、リンクを張る方法

LAN環境内でサーバーやNASに置いたファイルを共有することは、よく行われていると思います。それは、たとえば、一覧データを記録したExcelファイルから、詳細データを記録した別のExcelファイルにリンクする形で実現されていたり、クライアント/サーバーシステムから、関連するファイルを参照できるようになっているかもしれません。
Webアプリだと、どうでしょうか。Webアプリからローカルのファイルシステムにアクセスすることはセキュリティ面から、不可なことです。でも、Webアプリだって、設計データやプレゼン資料、詳細なデータを記録したExcelファイルにリンクを張って、アクセスしたいときがあります。
そんなとき、思い付くのがクラウドにデータを置いて、共有する方法です。
ここではPHPでDropbox Core APIを使って、共有フォルダにExcelファイルをアップロードして、リンクを張り、共有メンバーで編集できるようにする方法を紹介します。
Excelファイルを参照するだけなら、Webサーバーにアップロードして、ダウンロードできるようにすればいいだけなのですが、共同編集できるようにするには、Dropboxなどの共有機能が必要になります。便利な機能なんですが、その割にはDropboxの日本語化された情報が少ないようです。

では、始めましょう。まず、Dropboxにログインして、共有のリンクをクリックして共有フォルダを作っておきましょう。
cap01
ここでは、shareという名前で共有フォルダを作成しましたが、共有フォルダを作成する過程で共有するユーザーを招待する画面が表示されますので、招待したい人のメールアドレスを入力します(招待する人はDropboxユーザーでなくてはなりません)。後で、オプションをクリックして招待することもできます。

次に、Core APIのダウンロードに進みます。
cap02
Core APIのページで、PHPのSDKをInstall SDKをクリックしてダウンロードします。
cap03
ダウンロードしたファイルの中に、libフォルダがあります。このフォルダごとPHPのプロジェクトフォルダに移動して、フォルダ名をdropbox-sdkにリネームします。
たとえば、PHPのプロジェクトのフォルダ名がCard2Dboxだったら、
Card2Dbox\dropbox-sdkになります。そして、phpのプログラムはCard2Dbox直下に作成します。

プログラムを作成する前に、Dropboxアプリを作成する必要があります。App Consoleに移動しましょう。
cap04
create appボタンをクリックしてappを作成します。
cap05
ラジオグループによる選択がいくつかあります。Dropbox API appはCore APIを使うことを意味します。
My app needs access to files already on Dropboxにチェックを付けることで、先ほど作成した共有フォルダへのアクセスが可能になります。My app only needs access to files it createsにチェックを付けると、アプリ内のフォルダにしかアクセスできないAppになります。
ファイルのタイプでは、All file typesを選択します。app nameを入力して、Create appをクリックしてください(画像にあるfile2Dboxは使用されていたので、file2Dbox2に変更しました)。

次の画面ではOAuth2のアクセストークン(access token)を取得します。
cap06
access tokenとapp nameをPHPのプログラムで使いますので、エディタなどにコピペしておきましょう。

ここまで来たら、あとはPHPプログラムの作成です。
まず、ローカルファイルを選択するためのフォームを作ります。
(fileform.html)

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Dropbox file upload</title>
</head>
<body>
<h1>Dropbox file upload</h1>

<form action="upload.php" method="POST" enctype="multipart/form-data">
    <dl>
        <dt><label for="file"></label>File</dt>
        <dd><input type="file" id="file" name="file"></dd>
        <dd><input type="submit" value="Upload the file to my Dropbox!"></dd>
    </dl>
</form>
</body>
</html>

fileform.htmlでは、submitボタンが押されたら、upload.phpを実行します。

(upload.php)

<?php
    require_once "dropbox-sdk/Dropbox/autoload.php";
    use \Dropbox as dbx;
    
    if (isset($_FILES['file'])) {
        $accessToken = "KSk5FDq0uYYAAAAAAAAIFMvsmxe4n08W0_(以降省略)";	
        $clientIdentifier = "file2Dbox2/1.0";

        $dbxClient = new dbx\Client($accessToken, $clientIdentifier);
        try {
            print_r($_FILES['file']);
            $f = fopen($_FILES['file']['tmp_name'], "rb");
            $result = $dbxClient->uploadFile("/share/".$_FILES['file']['name'], dbx\WriteMode::add(), $f);
            fclose($f);
        } catch (Exception $e) {
            $label = ($uploader && $e->getCode() & $uploader::FLAG_DROPBOX_GENERIC) ? 'file uploar' : 'Exception';
            $error = sprintf("[%s] #%d %s", $label, $e->getCode(), $e->getMessage());
            echo '<span style="color: red">Error: ' . htmlspecialchars($error) . '</span>';
        }
        
    }
?>

upload.phpが、Dropboxへのファイルのアップロード処理です。まず、autoload.phpを読み込みます。次に、先ほど取得した$accessTokenとapp nameを記した$clientIdentifierを引数にClientオブジェクトを作成します。
そして、uploadFileメソッドに、これも先ほど作成した/shareフォルダを指定してアップロードを実行します。
これで、共有フォルダにファイルをアップロードすることができます。

こんどは、アップロードしたファイルのリンクを作成します。
(list.php)

<?php
    require_once "dropbox-sdk/Dropbox/autoload.php";
    use \Dropbox as dbx;
    $accessToken = "KSk5FDq0uYYAAAAAAAAIFMvsmxe4n08W0_(以降省略)";
    $clientIdentifier = "file2Dbox2/1.0";

    $dbxClient = new dbx\Client($accessToken, $clientIdentifier);
    $metadata = $dbxClient->getMetadataWithChildren("/share");

    if ($metadata === null) {
    } else {
        $children = $metadata['contents'];
        if ($children !== null && count($children) > 0) {
            foreach ($children as $child) {
                $download_url=$dbxClient->createShareableLink($child['path']);
                $name = dbx\Path::getName($child['path']);
                echo '<a href="'.$download_url.'">'.$name.'</a><br>';
            }
        }
    }  

getMetadataWithChildrenメソッドでshareフォルダのMetadataを配列として取得します。配列の構造は以下のページを参照してください。
https://www.dropbox.com/developers/core/start/php
そして、$metadata['contents']からpathを取得します。pathからリンクを作成します。createShareableLinkメソッドを使うとダウンロードではなく、開くリンクを作成できます。Path::getNameメソッドは/を除いたファイル名を返します。
cap07
実行すると、アップロードしたファイルのリンクが表示されます。クリックすると、
cap08
プレビュー表示されて、右側に当初表示されたダウンロードボタンがややあって、開くに変わります。
開くをクリックすると、Excelで直接、編集することができます。

共有フォルダにファイルを作成したり、作成済みのファイルを編集したりすると、共有メンバーにメールが飛ぶので、更新されたことがわかります。

Android Tips

1.android.content.res.resources$notfoundexceptionの例外が出るとき
 たとえば、Google developer consoleでMapを使おうとプロジェクトを作っておきながら、
Google Maps Android APIを有効にしていないとき(実は最近やりました)。

2.Activity間やActivityとService間で変数を共有したいとき
Applicationを継承するクラスを作成する。
【定義】
import android.app.Application;

public class AppGlobal extends Application {
// グローバルに扱いたい変数
public double Lat = 0.0;
public double Lon = 0.0;
}
【使うとき】
private AppGlobal appglobal;

if (appglobal.Lat == 0)
などと。