SharePoint上のファイルをPHPでダウンロードする方法

# 概要
SharePoint上で管理されているファイルをPHPでダウンロードする処理を作る際に
日本語の情報が少なかったので、手順を纏めました。

※SharePointにてサイトは作成されていることを想定した手順となります。

# クライアントの登録
システムからファイル情報、及びファイルの取得を行う際はREST-APIを使用します。
REST-APIを使用する際にトークンが必要となるため、トークン発行を行うためのクライアントの登録を行います。

基本的には下記の記事を参考にさせて頂きました。

https://qiita.com/samiii/items/cc47bb73a5e47645ce48


## クライアントIDを生成
1. 下記へ接続
`https://[テナント名].sharepoint.com/sites/[サイト名]/_layouts/15/AppRegNew.aspx`
[※サイトへアクセスできない場合](#サイトの操作権限が無いためサイトへアクセスできない場合)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629057/a9fb6aff-294d-1d59-8d08-4198dac7be6d.png)
2. 下記のテーブルに従って値を入力
3. 「作成」を押下

| 項目 | 値 |
|-----------|------------|
| クライアントID | 生成ボタン押下 |
| クライアント シークレート| 生成ボタン押下 |
| タイトル | 任意 |
| アプリドメイン | ※ローカル環境の場合は「localhost:80」など |
| リダイレクト先 | 存在しないURIでも可<br>例：「 https://localhost:80/hoge.php 」など |


## クライアントスコープ範囲の登録
1. 下記へ接続
`https://[テナント名].sharepoint.com/sites/[サイト名]/_layouts/15/AppInv.aspx`
[※サイトへアクセスできない場合](#サイトの操作権限が無いためサイトへアクセスできない場合)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629057/0cdd9b46-8395-e98e-b896-5c241846a4d0.png)
2. 作成したクライアントIDを「アプリID」へ入力し「参照」を押下
3. 「権限の要求XML」へ下記を入力
``` xml
<AppPermissionRequests AllowAppOnlyPolicy="true">
    <AppPermissionRequest Scope="http://sharepoint/content/sitecollection/tenant" Right="FullControl"/>
</AppPermissionRequests>
```
※作成したクライアントに対する操作範囲を設定します。
　その他の設定値は以下で確認できます。

https://learn.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/add-in-permissions-in-sharepoint#types-of-add-in-permissions-and-permission-scopes

4.「作成」を押下

## サイトの操作権限が無いためサイトへアクセスできない場合
サイトの操作権限が無いためサイトへアクセスできない状態となります。
アクセスするには権限を持つアカウントへ切り替えるか、権限を持つユーザが以下の対応を行ってください。

1. 下記へ接続
``` https://[テナント名]-admin.sharepoint.com/```
[※サイトへアクセスできるアカウントが無い場合](#SharePointの操作権限が無い場合)
2. 「サイト」<「アクティブなサイト」を選択
3. 一覧から該当するサイトを選択
4. 一覧ヘッダーにある「権限」<「その他の管理者の管理」を選択
5. 管理者の追加へアクセスできないアカウントを追加

## SharePointの操作権限が無い場合
サイト権限が付与できない場合はSharePointの管理者権限が与えられていないためとなります。
アクセスするには権限を持つユーザが下記の対応を行ってください。

1. 下記へ接続
``` https://admin.microsoft.com/AdminPortal/Home?#/users ```
2. 該当ユーザを選択
3. 「アカウント」< 「役割の管理」を選択
4. 「管理センターに対するアクセス許可」にチェックを入れる
5. 「SharePoint管理者」にチェックを入れる
6. 「保存」を押下



# PHPでファイルの取得処理を作成
PHPのcurl関数を使うことで、ファイルやフォルダの一覧をjson形式で取得することはできましたが
何故かファイルダウンロードのときだけ「403エラー」が出続けたため、代わりに「phpSPO」という
Office365用のPHPライブラリを使用することにしました。
※このライブラリも一部の動作に関しては正常に動作しないようですが、今回は関係ありませんでした。

## phpSPOをインストール

https://github.com/vgrem/phpSPO

※導入方法や簡単な記述はREADMEを参照

## PHPサンプル
下記コードをコピーして、必要な項目を変更することで取得が可能となります。

``` php:ファイル・フォルダの取得
<?php 

require('vendor/autoload.php');

use Office365\SharePoint\ClientContext;
use Office365\Runtime\Auth\ClientCredential;

$credentials = new ClientCredential("クライアントID", "クライアントシークレット");
$client = (new ClientContext("https://teikokushoin.sharepoint.com/sites/masterdata"))->withCredentials($credentials);
$targetFolderPath = "SharePointの格納先パス";
$saveFolder = "保存先";

//指定フォルダ内のファイルを取得
$data = $client->getWeb()->getFolderByServerRelativeUrl($targetFolderPath)->getFiles();

//指定フォルダ内のフォルダを取得
//$data = $client->getWeb()->getFolderByServerRelativeUrl($targetFolderPath)->getFolders();

$client->load($data);
$client->executeQuery();

echo('<pre>');
var_dump($data);
echo('</pre>');

?>
```

``` php:ダウンロード
<?php 

require('vendor/autoload.php');

use Office365\SharePoint\ClientContext;
use Office365\Runtime\Auth\ClientCredential;

$credentials = new ClientCredential("クライアントID", "クライアントシークレット");
$client = (new ClientContext("https://teikokushoin.sharepoint.com/sites/masterdata"))->withCredentials($credentials);
$saveFolder = 保存先のパスとファイル名;
$targetFilePath = 保存対象のフルパスとファイル名;

$fileContent = Office365\SharePoint\File::openBinary($client, $targetFilePath);
file_put_contents($saveFolder, $fileContent);

?>
```

以上