開発:ファイルAPI
Moodle 2.0 このページは、Moodle 2.0でのファイルストレージおよびアクセスの実装に関する、現在考えていることに関する概要ページです。作成中の仕様書です!
このページは、誰でも編集することができますので、誰でも間違いを訂正したり、このドキュメントを進化させることができます。あなたに質問、報告する問題または主要な変更に関する提案がある場合、ページコメント欄に追加するか、リポジトリフォーラム (英語)でディスカッションを開始してください。開発を開始する前、私たちは、それらのすべての意見をメインの仕様に取り込むよう努力します。
目的
- ファイルを直接Moodleに追加できるようにする (現在、私たちが追加しているように)。
- ファイルがどこから来たのか記憶する。
- ケイパビリティおよび他のローカルルールを使用して、モジュールにファイルアクセスのコントロールを与える。
- Moodle内のすべてのファイル処理に関して、一貫してシンプルにアプローチする。
オーバービュー
ファイルAPIは、Moodleコードが次の目的で使用するインターフェースのコアです:
- Moodle内にファイルを保存する
- Moodleユーザにファイルを表示する
ファイルAPIは「ユーザ」ファイルのみ提供します。また、ファイルAPIは、次のディレクトリのような、Moodleのdatarootディレクトリに作成されたローカルファイルおよびキャッシュを提供しません: temp、lang、cache、environment、filter、rss、search、sessions, upgradelogs等
APIは、いくつかの独立したパーツに分かれます:
- ファイル提供API
- file.php
- pluginfile.php
- userfile.php
- draftfile.php
- rssfile.php
- ファイル保存API
- 任意のアクセスコントロール
- 任意のリポジトリsync
- ファイル管理API
- ファイル閲覧
- ファイルリンク (エディタ統合)
- リポジトリからのアップロード
ファイル提供API
ファイルの提供に対応します - ブラウザがファイルをリクエストした場合、そのファイルをMoodleが返します。私たちには、3つのメインファイルがあります。サーバ上でスラッシュ (例 file.php/some/thing/xxx.jpg) を設定することが重要です。相対リンクを使用するコンテンツは、スラッシュなしではアクセスできなくなります (scorm、アップロードhtmlページ等)。
file.php
コースファイルを提供します。
基本的なファイルを扱います。理想的には、コースセクションからリンクされたイメージおよびファイルのみ扱われるべきです。XSS保護は必要としません - 私たちはjavaスクリプト、sw (shockwave) 等の使用を想定しています。「セキュア」にする方法はありません。私たちがほとんどのファイルをモジュール内に移動する場合、アクセスコントロールは重要な意味を持ちません。
既存のコースコンテンツに対する下位互換性に関して、ファイル名およびパラメータ構造は重要です。
/file.php/courseid/dir/dir/filename.ext
内部的にファイルは、array('contextid'=>$coursecontextid, 'filearea'=>'coursefiles', 'itemid'=>0)
に保存されます。
pluginfile.php
(別名 modfile.php) モジュール、ブロック、問題ファイルを送信します。
- モジュールは、アクセスコントロールを決定します。
- 任意のXSS保護 - 学生が送信したファイルは、ノーマルヘッダと共に提供されるべきではありません。私たちは、代わりにダウンロードさせる必要があります。理想的には、信頼できないファイルに対して、第2のwwwrootを使用した方が良いでしょう。
- 選択したエリアの内部リンクのみサポートされます - あなたは要約エリアのみイメージをリンクすることができますが、提出課題にはリンクすることができません。
モジュールでHTML編集が許可されている場合、絶対リンクは書き換えられる必要があります。リンクは、相対リンクとして内部に保存されます。編集または表示する前、str_replace()を使用して、内部リンクは絶対リンクに変換されます (@@thipluginlink/summary@@/image.jpg --> /pluginfile.php/assignmentcontextid/intro/image.jpg)。保存される前、内部リンクに戻されます。
- 明確な (distinct) ファイルエリアは、情報を追加するため、どこかで定義されたプラグインによってサポートされますか? 例えば、以下のように宣言されると面白いと思います:
- assignment_summary:
- relpath='intro'
- userdata=false
- anotherproperty=anothervalue
- assignment_submission:
- relpath='submission/@@USERID@@'
- userdata=false
- anotherproperty=anothervalue
- など ...
- assignment_summary:
- それから、エディタが「assignment_summary」エリア名を「受信」した場合、何を表示するのか等、知っているとしたら? また、バックアップおよびリストアにおいて、ファイルエリアが処理されるか否か (userdata=fals) 判断するため、その情報が有用だとしたら。または、リンクの再構築 (str_replace() above) に対して、その情報が有用だとしたら。そして、自由にコーディング (prone to errors 間違いがち) する代わりに、モジュールによって良く定義されたファイルエリアのリストがあるとしたら。Eloy Lafuente (stronk7) 16:35, 28 June 2008 (CDT)
- 明確な (distinct) ファイルエリアは、情報を追加するため、どこかで定義されたプラグインによってサポートされますか? 例えば、以下のように宣言されると面白いと思います:
- このような機能は、ファイル管理APIの一部にありますが、これをファイル保存のコードにハードコードすると柔軟性が失われます、私の考えでは。Skodak
- はい、はい。ストレージは、ファイルをget/putする以外、何も知ってませんね。確かに、これは管理の一部ですね。Eloy Lafuente (stronk7) 11:21, 29 June 2008 (CDT)
/pluginfile.php/contextid/areaname/arbitrary/params/or/dirs/filename.ext
pluginfile.phpは、コンテクストテーブルよりプラグインタイプを検出し、基本情報 (状況に応じて、$courseまたは$cm) を取得します。また、アクセスをコントロールして最終的にファイルをユーザに送信するプラグイン関数 (または後のメソッド) をコールます。areanameは、タイプ別にファイルを分離して、コンテクストをいくつかのサブツリーに分けます - 例えば、summaryファイル (モジュールのイントロダクションで使用されるイメージ)、投稿の添付ファイル等。
課題例
/pluginfile.php/assignmentcontextid/intro/someimage.jpg /pluginfile.php/assignmentcontextid/submission/submissionid/attachmentname.ext /pluginfile.php/assignmentcontextid/extra/allsubmissionfiles.zip
- あの ... これらすべてのファイルが同じ場所ですか? 上記例の「submission」パスを「summary」から区別したらどうなりますか? エディタまたはファイルマネージャが許可しないからですか? 例えば、課題の要約 (summary) として1つのファイルを「submission」エリアからピックアップした場合、「summary」エリアのみ表示されますか? コンテクストに複数のファイルマネージャが存在することになり、以下で合意された「コンテクストあたり1つのファイルマネージャ」という考え方に反してしまいます。 Eloy Lafuente (stronk7) 21:28, 26 June 2008 (CDT)
- はい、Eloyさん、異なるエリア (summary、submission) 等は、異なる使い方をされて、異なるアクセスコントロールを持ちます。ファイルマネージャには、2種類あります - すべてのコンテクスト+エリア一覧にユーザがアクセス可能な2つのウィンドウ枠を持ったファイルマネージャ、および (他へリンクできないため) 現在のプラグインのサブセットのみ表示する最小限のHTMLエディタです。
SCORM例
/pluginfile.php/scormcontextid/intro/someimage.jpg /pluginfile.php/scormcontextid/content/revisionnumber/dir/somescormfile.js
キャッシングの問題を避けるため、すべてのファイル変更に関して、リビジョンカウンターの値が増加されます。存続期間は、モジュール設定で調整されるようにすべきです。
小テスト例
pluginfile.php/quizcontextid/intro/niceimage.jpg pluginfile.php/quizcontextid/report/type/export.ods
問題例
pluginfile.php/SYSCONTEXTID/question/questionid/file.jpg
ブログ例
一般的にブログエントリまたはメモには、コンテクストIDを持ちません (これらはシステムコンテクスト内に存在し、以下のSYSCONTEXTIDがシステムコンテクストのIDだからです)。 メモの添付ファイルは、常にXSSプロテクションと共に提供されます。理想的には、私たちはこのファイルとwwwrootを分けるべきです。アクセスコントロールは、ハードコードできます。
/pluginfile.php/SYSCONTEXTID/blog/blogentryid/attachmentname.ext
内部的には、array('contextid'=>SYSCONTEXTID, 'filearea'=>'blog', 'itemid'=>$blogentryid)
に保存されます。
バックアップ例
特別に保護されたバックアップファイルを持つことは素晴らしいと思います - バックアップファイルのダウンロードおよびアップロードに関する新しいケイパビリティ。バックアップには、多くの個人情報を含んでいます。ですから、私たちは他のサイトでバックアップをリストアすることをブロックできるのではないでしょうか。
/pluginfile.php/coursecontextid/backup/backupfile.zip
内部的には、array('contextid'=>$coursecontextid, 'filearea'=>'backup', 'itemid'=>0)
に保存されます。
userfile.php
パーソナルファイルの保存は、提出する前の課題のような、作業中のファイルのオンラインストレージを目的としています。
- 自分のファイルのみ読み込み/書き込みします。
- 後で他のユーザと共有できるオプションを持ちます。
- パーソナル「ウェブサイトはサポートされません (セキュリティ上の理由から)。
/userfile.php/userid/dir/dir/filename.ext
rssfile.php
下位互換を保持するためのみ実装されているrss/file.phpと入れ替えます。 RSSファイルは、セッション/クッキーを要求すべきではありません。URIは、ある種のセキュリティトークン/キーを含むべきです。 内部的には、ファイルはデータベースに保存されるか、他のファイルと共に保存されます。 パフォーマンス改善 - If-None-Match/If-Modified-Since => 304を受け取った場合、私たちはEtag (cool) および Last-Modified (より多く使われています) をサポートします。
/rssfile.php/contextid/any/parameters/module/wants/rss.xml /rssfile.php/SYSCONTEXTID/blog/userid/rss.xml
さらに、モジュールおよびプラグインは、何をユーザに送信するか決定します。
一時ファイル
通常、一時ファイルは1つのスクリプトの存続期間中のみに使用されます。 一時ファイルは、次のスクリプトで使用されます:
- エクスポート
- インポート
- ZIP圧縮/解凍
- 実行ファイルによる処理 (latex、mimetex)
理想的には、これらのファイルはUTF-8 (現在のところZIP圧縮に問題があります) を使用べきではありません。 提案している新しいsha1ベースのファイルストレージでは、パフォーマンスおよび技術的な理由からUTF-8の使用は適していません。
レガシーのファイル保存および提供
$CFG->dataroot内の古き良き個別ディレクトリを使用する予定です。
ファイルの提供および保存:
- ユーザアバター - user/pix.php
- グループアバター - user/pixgroup.php
- tex、algebra - filter/tex/* and filter/algebra/*
- rssキャッシュ (?full rss rewrite soon?) - 下位互換は、rss/file.phpのみ
保存のみ:
- セッション
ファイル保存API
一般的にモジュールは、ローカルのMoodleファイルとともに動作します。主な理由として、外部リポジトリにアクセスすることがあります。ファイルをアップロードする代わりにリポジトリを利用して、外部リポジトリとローカルファイルを同期化させることもできます。
ファイルコンテンツは、ファイル名の代わりにSHA1ハッシュを使用して、moodledata/filepoolの中に保存されます。ファイル名、相対パスおよび他のメタデータは、file(_xxx)データベーステーブルに保存されます。どこにファイルがあるのか、モジュールが実際に知らなくても良いよう、これは完全に抽象化されます。ファイルを保存する場合、コンテンツはストリングまたはファイルハンドルとして送信されます。また、コンテンツを読む場合、ファイルハンドルとして返されます。
ファイルテーブル
このテーブルは、すべてのファイルに対して、それぞれ1つのエントリを含みます。ファイルが十分に識別され、必要に応じて検索されるよう、十分な情報をここで保持します。
note:「file」は予約語のため、pluralが使用されます。
フィールド | タイプ | デフォルト | 情報 |
id | int(10) | オートインクリメント | |
contenthash | varchar(40) | sha1ハッシュコンテンツ | |
pathnamehash | varchar(40) | contextid+filearea+itemid+filepath+filenameのsha1ハッシュ - ファイル重複防止および迅速なルックアップを実現します。 | |
contextid | int(10) | コンテクストテーブルで定義されるコンテクストID - ファイルを所有しているプラグインインターフェースの識別 | |
filearea | varchar(50) | 「submissions」「intro」「content」(サマリーからのイメージおよびswfのリンク) 等のように、「blogs」および「userfiles」は、システムコンテクストにある特別なケースです。 | |
itemid | int(10) | プラグイン特有のアイテムID (例 フォーラム投稿、ブログエントリ、提出課題、ユーザファイルのユーザID等) | |
filepath | text | モジュールコンテンツのルートからのファイル相対パスです。SCORMおよびリソースモジュールで有用です。多くのモジュールでは、必要としません。 | |
filename | varchar(255) | このファイルに関するフルユニコード名です (大文字小文字の区別をします)。 | |
filesize | int(10) | ファイルサイズ - バイト | |
mimetype | varchar(100) | NULL | ファイルタイプ |
userid | int(10) | NULL | 任意 - 一般的なユーザIDフィールド - プラグインに依存します。 |
timecreated | int(10) | このファイルが作成された日時です。 | |
timemodified | int(10) | このファイルが更新された最終日時です。 |
非ユニークインデックス: contextid、filearea、itemid、contenthash
ユニークインデックス: pathnamehash
contextidから生成されるため、プラグインタイプは指定されません。ブログのような独自のコンテクストを持たないアイテムは通常、systemcontextidから独自のファイルエリアを使用します。
- DBサイドにテキスト制限 (インデックス長の制限、インデックス不可、複合検索 ...) を保存するため、恐らく、私たちはハッシュファイルパスおよびファイル名、それらのインデックスを持つことができると思います。 Eloy Lafuente (stronk7) 11:54, 29 June 2008 (CDT)
- また、それぞれのプラグインの正確なファイル処理に使用するため、恐らく私たちは、最終的にそこへプラグインタイプを保存すべきです。 Eloy Lafuente (stronk7) 18:54, 29 June 2008 (CDT)
files_cleanupテーブル
このテーブルには、ファイルプールからの削除対象ファイルが含まれます。すぐにファイルが削除されるのではなく、cronがfiles_cleanupテーブルを使用して、もはやファイルが使用されていないか確認した後、プールから削除します。cronでクリーンアップする理由は、パフォーマンスおよび衝突の回避にあります - 同時アップロードおよび削除では問題が生じる場合があります。クリーンアップ中、恐らく私たちは、さらにテーブルベースのロッキングが必要だと思います。
プールエリアの深い妥当性チェックのため、私たちは特別なスクリプトを追加することができます - 不明なファイルの報告、迷子ファイルの報告、sh1ファイル名に合致しないコンテンツ等 - これには、とてもとても時間がかかります。
フィールド | タイプ | デフォルト | 情報 |
id | int(10) | オートインクリメント | |
contenthash | varchar(40) |
files_metadataテーブル
このテーブルは、ファイルに関する特別なメタデータを含みます。リポジトリは、このデータを提供することができます。または、ローカルコピーを手動で編集することができます。
フィールド | タイプ | デフォルト | 情報 |
id | int(10) | オートインクリメント | |
fileid | int(10) | ファイルID | |
name | varchar(255) | 特別メタデータ名 | |
value | text | 値 |
files_aclテーブル
このテーブルでは、ファイルの任意なACPに関して記述します。多くの場合、この記述は必要ではありません。通常、モジュールはアクセスロジックをハードコードしますし、コースファイルが使われることは極めて少ないと思われます。
フィールド | タイプ | デフォルト | 情報 |
id | int(10) | オートインクリメント | |
fileid | int(10) | 私たちがアクセスを定義するファイルです。 | |
contextid | int(10) | このファイルが公開されるコンテクストです。 | |
capability | text | このファイルの閲覧に必要なケイパビリティです。 |
aclメモ
- これには、user/group/othersに似ている、いくつかのコンセプトがありません。例えば、ユーザファイルに関して、標準的なユーザはパーミッションを割り当てたり、閲覧することができません - これでは役に立ちません。
- ファイルリンクおよびファイルの可用性を同期することは、さらに重要です - アクセスできないファイルにリンクしている場合、またはアクセスを望まないファイルにアクセスしている場合、両者とも問題になります。
- ここでは、ブラウザ/プロクシのキャッシングは私たちに反して動作します - 「シークレット」なファイルはキャッシュされるべきではありません。
files_syncテーブル
このテーブルには、リポジトリのデータをどのように同期化するかという情報を含んでいます。データは、cron.phpまたはファイルマネージャの要求により同期化されます。同期化は一方向 (リポジトリ -> ローカルファイル) からのみです。
フィールド | タイプ | デフォルト | 情報 |
id | int(10) | オートインクリメント | |
fileid | int(10) | ファイルID | |
repositoryid | int(10) | このファイルが関連付けられているリポジトリインスタンスです。詳細は、開発:リポジトリAPIをご覧ください。 | |
updates | int(10) | アップデータスケジュールを指定します (0 = なし、1 = オンデマンド、other = 秒数) | |
repositorypath | text | リポジトリのオリジナルファイルのフルパスです。 | |
timeimportfirst | int(10) | このファイルが最初にMoodleにインポートされた日時です。 | |
timeimportlast | int(10) | このファイルがMoodleにインポートされた最新日時です |
ファイルコンテンツストレージ
最初、ファイルストレージ階層には、ユーザID、エントリiD、ファイル名等、数多くのメタデータを含んでいました。現在、ファイルコンテンツは、ファイルメタデータと分離して保存されます。すべてのプラットフォームにおいて、UTF8をサポートします。
ファイル保存:
- コンテンツのSHA1ハッシュを計算する。
- SHA1名のファイルが存在するかどうか確認する。存在しない場合、ファイルをファイルプールに追加する。
- 削除ファイルのリストにSHA1ファイルがある場合、削除する。
- SHA1をファイルプールIDに使用して、ファイルをfileテーブルに保存する。
ファイル読込み:
- fileテーブルよりファイルレコードを取得 - 恐らく、ファイルIDまたはコンテクストID+インスタンスIDを使用する。
- ファイルコンテンツを取得する。
ファイル削除:
- fileテーブルよりレコードを削除して、SHA1を記憶する。
- 削除ファイルテーブルに削除されたSHA1を保存する。まだ、物理ファイルは削除しません。
- クリーンアップスクリプトによる、実際のSHA1ファイル削除を待ちます (ファイルの追加/削除に関して、競合が発生しないよう、適切なテーブルロックが必要です)。
ファイルプール詳細
ファイルプールは、$CFG->dataroot/filepool/ にありますが、OSの制限により、ファイルすべてを1つのディレクトリに保存することはできません。ファイルの保存には、sha1ハッシュの先頭3文字を使用します。コンテンツのsha1ハッシュ先頭3文字が同じファイルが数千あるということは考えられません。
同じ大きなファイルを複数保存する場合、このタイプのストーレジでは多くのディスクスペースを節約することができます。データを外部リポジトリと同期化する場合、ディスクスペースを大幅に節約することもできます。もうひとつの利点は、私たちがファイルコンテンツの不一致を発見することができることです。
ファイル読み込みのパフォーマンスは、前のコードに似ています。ハッシングおよび特別なデータベースアクセスのため、ファイル書き込みのパフォーマンスは遅くなります。
dataroot /filepool /00 /01 ... /23 /00 /01 ... /1e /00 /01 ... /2d /231e2dc421be4fcd0172e5afceea3970e2f3d940 ... /fe /ff
ファイル管理API
このセクションでは、以下の内容に関して記述します:
- ファイルマネージャ
- HTMLエディタとの統合
- リポジトリとの相互関係
ファイルマネージャ
単一ウィンドウ枠のファイルマネージャは、ウェブベースのアプリケーションでは悪評高いドラッグ&ドロップなしに実装するのは、簡単ではありません。私は2つのウィンドウ枠を持ったコマンダースタイルのファイルマネージャーを提案します。2つのウィンドウ枠を持ったマネージャーを使用することで、あなたは2つの異なるコンテクスト間 (例: コース) において、簡単にファイルをコピー/移動することができます。
ファイルマネージャは、直接ファイルシステムAPIと相互作用すべきではありません。代わりに、それぞれのモジュールは、実およびローカライズ名 (ローカライズ名は、backupdataのようなディレクトリに必要です) のファイルおよびディレクトリの横断的なツリーを返すべきです。
最初、それぞれのコースには単一のファイルツリーがありました。私たちは、それぞれのモジュール/ブロックをコースから完全に分離して、モジュール内に独立したファイルエリア (例: モジュールイントロダクション、コンテンツファイル、提出課題、投稿添付ファイル) を持つ必要がありました。ファイルエリアは、私たちが相対パスを使用できるよう、小さなツリーとして定義することができます。これらのファイルエリアは、コンテンツツリーのブランチからぶら下がっています (これには図が必要です)。
HTMLエディタとの統合
HTMLエディタは、関係するファイルのみ閲覧できるべきです - 例えば、リソースのイントロダクションを編集する場合、そのリソースのファイルエリアのみのイメージを使用できるべきです。また、HTMLリソースページを編集する場合、コンテンツエリアのイメージのみ使用できるべきです。
ここにいくつか問題を挙げます:
- 新しいリソースを追加する場合、まだコンテンツは存在していません。新しいコンテンツを追加するため、私たちは一時的なファイルストレージを処理するためのテーブルを作成する必要があります。簡単ではありませんが、解決できないことではありません - 恐らく、私たちはコースコンテクストIDを使ってしまうか、特別なユーザファイルエリアに一時的に保存できると思います。
- 私たちは、pluginfile.phpのリンクに絶対アドレス再リンクを使用することができません。代わりに、編集時または保存前に@@thispluginfile@@/2112/112/image.jpgのように変換される前のみ、私たちは絶対リンクを使用することができます。表示または編集される前、ローカルリンクは完全な絶対リンクに変換されます。すべてのファイルエリアがこれをサポートするわけではありません (例: 誰もアクセスしないため、提出課題にリンクすることは意味をなしません)。HTMLエディタのイメージプレビューに関して、私たちはこれを実装することはできます。
HTMLエディタは、基本的な操作のみできる、シンプルな単一のウィンドウ枠を持ったファイルマネージャであるべきです - ファイルエリアの選択、ファイルエリアの閲覧、ファイルのアップロード、ユーザファイルのコピー、リポジトリファイルの使用、削除。エディタに埋め込まれたモジュールにより指定されるスクリプトをコールするajaxを通して、エディタはモジュールおよびコアとコミュニケートします。コールバックスクリプトは、ファイルツリーを作成するため、ファイルマネージャとは異なるロジックを使用します。コールバックスクリプトは、他のユーザが閲覧した結果として生じる、HTMLがアクセスすることのできるファイルのみ知る必要があるからです。
リポジトリとの相互関係
リポジトリは、ファイルアップロードの代替手段として提供されます。また、リポジトリは、コース間のファイル同期化にも使用することができます。リポジトリオプションは、ファイルアップロードフィールドがある場合、また、時々「同期化を維持する」オプションが有効にされた場合 (これは、提出課題等に意味をなします)、常に利用できるようにすべきです。
アップグレード、移行および下位互換性
DML/DDLのように、大変な作業になりそうです ;-)
コード下位互換性
ファイルストレージに関して、下位互換性はゼロ%です。新しいオブジェクトの使用が必須です。古い $CFG->dataroot/$courseid/ および $CFG->dataroot/blog/ は空です。
コンテンツ下位互換性
既存のコースがイメージ、Flash等を失わないための手段です。しかし、これは、コースファイルエリアからファイルを使用している既存のデータでは動作しない、新しい機能 (実装されている場合、リソース共有のようなもの) です。
ファイルアップロード時の特殊文字の除去により、アップロードされたHTMLファイル内のリンクとファイルが合致しなくなるかもしれません。私は、このようなことが、頻繁に起きないことを望むばかりです。
コンテンツの移行
- リソース - 新しいコンテンツファイルエリアにPDF、イメージリソース等を自動的に移動します。当然、アップロードされたウェブページは、正確ではなくなります。
- 問題 - イメージファイルは、新しいアリアに移動されます。問題にはイメージタグが付加されます。
- moddataファイル - 最も簡単な部分です。新しいストレージに移動するだけです。
- コースファイル - 恐らく非常に多くの古いファイルがあると思います :-( :-(
- リーダー内のRSSフィードリンク - 壊れます。新しいセキュリティ関連のコードがリンクを壊してしまいます。
ファイルをファイルテーブルおよびファイルプールに移動する
処理に極めて長い時間を要するため、移行プロセスは中断できるようにすべきです。ファイルは古いロケーションから移動されます。再スタートは、簡単にする予定です。
ステージ案:
- moddataを除く、すべてのコースファイルの移行 - $CFG->files_migrated=true; のように設定して実行完了させる - このステップでは、古いファイルマネージャおよびHTMLエディタのインテグレーションを壊してしまいます。
- ブログ添付ファイルの移行
- 問題ファイルの移行
- moddataファイルの移行 - それぞれのモジュールは、変換されたコースファイルまたはmoddataから直接データをコピーすることに関して責任を負います。なぜなら、これらのデータは自動的に変換されないからです。
いくつかのpplでは、コースファイルにシンボリックリンクを使用します - コースファイルとシンボリックリンクが使われないとしても、私たちは両者が新しいストレージにコピーされることを確認すべきです - 同期化されたコンテンツを望む人は誰でも、ファイルの移動先でも再度同期化を必要とするものです。
- ここでは、コースファイルをモジュールエリアに移行する場合の二重タスクに関して話題にしました:
- すべての依存状態を見つけて、同時に移動するため、HTMLファイルを構文解析します。
- モジュールファイルエリアで足りないものが見つかった場合、コースファイルエリアで検索した後、コピーして提供するため、pluginfile.php内でフォールバックします。
- ここでは、コースファイルをモジュールエリアに移行する場合の二重タスクに関して話題にしました:
- また、古いコースファイルまたは新しく自動的に作成されるファイルエリアに対して適用できるかどうか明確にするため、私たちはリソースに新しい設定を追加する可能性についても話しました。移行されたリーソースは、自動的に作成されたファイルエリアに新しいコースファイルが移行されるまで、古いコースファイルを扱います。
- リソースファイルのみ本当に複雑なようです (なぜなら、HTMLを自由に含むことができるからです)。残り (ラベル、イントロダクション ... ではなく) の構文解釈は難しくありません。
- Eloy Lafuente (stronk7) 19:00, 29 June 2008 (CDT)
バックアップ/リストアの変更
バックアップのファイル処理の部分は、完全に書き換えるる必要があります - xmlのファイル一覧 + sha1署名ファイルコンテンツのプール。これにより、utf-8のトラブルを解消できます、yay!!
クオータ
ファイルサイズは、ファイルテーブルに保存されます。私たちは、どれくらいのスペースを使用しているか、シンプルなクエリを使用して探すことができます。しかし、sha1ハッシュベースのストレージでは、重複したファイルは取り除かれるため、このファイルサイズは、正確ではありません。
- sha1ストリングがファイルテーブル (non-unique) に保存される場合、ファイルテーブル内の複製を見つけるために使用することができます。また、1度だけファイルサイズを集計します。これを避けるため、私たちは定期的に複製を見つけるようにして、それぞれのファイルレコードにファイルサイズを保存します (最初の複製のみファイルサイズを取得し、他はゼロを取得します)。 Nicolas Connault
- 合計コースファイル - コース内で使用されている、すべてのコンテクストを探します。そして、コンテクストID ($listofcontexts) を使用して、ファイルテーブルに問い合わせします。
- モジュールファイル - モジュールコンテクストを探して、ファイルエリアごとのスペースを計算します。
- ユーザファイルクオータ - パーソナルエリア内部のみ。すべてのモジュール内のすべての添付ファイルを集計するには、しばらくかかります。私たちは、使用されているインスタンスごとに、ファイルサイズを分割することもできます。いくつかのシナリオでは、この集計は、さらに正確にした方が良いでしょう。
その他
- アンチウイルススキャニング + アップロードマネージャ 書き直し/forms libとの統合
- zip圧縮および解凍
主要な問題
解決が難しい問題の一覧
zipサポート
Zipフォーマットは、ファイル圧縮に関する古い基準でした。ユニコードが使われるようになる、ずっと以前に開発され、最近ユニコードのサポートが追加されました。パス名に非アスキーのエンコーディングを使用するには、いくつかの方法があります。残念なことに、これらの方法は、それほど標準化されているわけではありません。多くのWindows圧縮ツールでは、DOSエンコーディングを使用しています。
クライアントソフトウェア:
- Windowsビルトイン圧縮 - Windowsに実装、非DOSエンコーディングのみ
- WinZip - シェアウェア、ユニコードオプション (v11.2より)
- TotalCommander - シェアウェア、シングルバイト (DOS) エンコーディングのみ
- 7-Zip - フリー、ユニコードまたはDOSエンコーディング、ファイル名に使用されているエンコーディングによる (v4.58betaより)
- Info-ZIP - フリー、 変わった文字セット変換
PHP拡張モジュール:
- Info-ZIPユーティリティ - ユニコードサポートなし、ファイル名の文字を壊します (OS次第、詳細はドキュメントをご覧ください)、圧縮および後の解凍のため、ファイルをtempディレクトリにコピーする必要があります。
- PclZip PHPライブラリ - シングルバイトのエンコード名のみ読みます。ランダム問題および高いメモリー使用量の問題があります。
- Zip PHP拡張モジュール - シングルバイトのエンコード名のみ読みます。64bitのオペレーティングシステムは、500ファイル以上のアーカイブをコピー/作成することができません (すべてのファイル名およびディレクトリ名の合計長に依存します。PHP 5.3 + PECLライブラリの環境に対して修正します。PHP 5.2.xへのバックポートは予定していません!)。ファイルの追加は、空きのファイルハンドルに制限されます (1000前後 - OSおよび他のPHPコードに依存します。次善策は、アーカイブを閉じて、再度開く方法です)。
ラージファイルのサポート: 32ビットのオペレーティングシステムで動作しているPHPは、2GB以上のファイルをサポートしません (PHP 6以前には修正されません)。これは、ファイルサイズの大きなバックアップに関する潜在的な問題となります。
Tarアーカイブ:
- tar + gzip圧縮 - PHP + zlib拡張モジュールにより容易に実装 (PEARまたはカスタムコードからPclTar、Tar)
- *nixのユニコードでは問題なし、もう一度、WindowsではDOSエンコーディングが必要です :-(
- バックアップ/リストア向きだと思います - yay!
ロードマップ:
- 配下のライブラリを完全に隠す、zip処理クラスを追加します。
- Zipアーカイブのファイルエンコーディングに、「garbage in/garbage out (コンピュータが高性能だとしても、不完全なデータを入力すれば、不完全な結果しか得られないという意)」アプローチを使用します。言語パックに新たに「zipencoding」(例 Czechロケール用cp852 DOS文字セット) を追加して、解凍時に使用します。PHP Zip拡張モジュールがサポートを実現するようになった場合、私たちは本当の意味でのユニコードをサポートします。
空のディレクトリ
うーん、Justinさんのコメントをもう少しだけ考えてみると、この提案では、空ディレクトリに対するサポートがないようです。これには、新しいテーブルまたはファイルテーブルのハックが必要です - 恐らく、私たちはファイル名「.」のファイルを追加できます。また、ディレクトリコンテンツの繰り返しをスキップすることができます。
メモ: ファイル名「.」で解決しました。ファイル追加時にディレクトリが自動的に追加され、rootディレクトリは閲覧時に作成されます。
ファイルのオーバーライト
ここでは、オーバーライティングという考え方は、もはや存在しません。そして、パス+ファイル名は、ユニーク (unique 固有) である必要はありません - ルーズなmssqlが900バイト以上のインデックスを許可しないため、私たちはインデックスを作成することができません :-( 私たちは、インデックスの作成をどうにかエミュレートして、衝突が発生した場合、処理する必要があります。
メモ: pathnamehashフィールドのユニークインデックスで解決しました。
いくつか考える必要のあるコメント (忘れないため)
- それぞれのコンテクストは、独自の「ファイルマネージャ」を持ちます。
- 「file manager context」ファイル (FMF) および「internal context」(ICF) ファイルを (現在のmodeditファイル、提出課題、添付 ... から) 分離します。
- /pluginfile.php/SYSCONTEXTID/{blog|question}等は独自のFMFも持ちますか? または、ICFのみ?
- コンテクスト間をコピーする方法
- Links = -1 for them
- 削除戦略 (ロック、隔離ステータス ...)
- ユーザごと、コースごと等のクオータのサポートを含む
- いつでも停止/再開できるよう、(ユニコードアップグレードのように) アップグレードは一時停止可能な状態にすべきです。
Justinの明確な考え
全体のファイル/リポジトリシステムと統合して動作するよう、私は既存のAlfrescoを拡張して実装するよう作業を進めています。また、フィードバックのため、私のコメントおよび考え方をここに投稿したいと思います。お手柔らかに =)
今までのところ、私が欲するフィードバックを1つだけ頂きました (ところで、これがフォーラムディスカッションに向いているのでしたら、私に教えてください):
ファイルテーブル内の各エントリのフル「ファイルパス」を保存しない
- ディレクトリ構造を閲覧する場合、ファイルパスを渡して子ディレクトリまたは親ディレクトリを決めるような処理には、PHPの外部コードを数多く必要とします。私はディレクトリ名のみ保存した新しい「file_directory」を作成して、親ディレクトリコードを参照した方が良いと思います。私たちにとってのメリットは、多くの重複テキストフィールド値を「file」テーブルの中に入れて、ローカルファイルをファイルピッカーで閲覧することで、親ディレクトリ「/」から子ディレクトリへのリンクを計算するのに大きなPHPオーバヘッドを要しないということです。
- 構造化ファイルパスの使用に対して、今後ファイルパーミッションが計算されないことを考えると、特定のファイルに完全なフルパスを与えることは、恐らく必要ではないと思われます。
- しかし、repository_syncテーブルのrepositorypathフィールドは、まだ意味をなします。
- file_directoryテーブル
フィールド | タイプ | デフォルト | 情報 |
id | int(10) | オートインクリメント | |
parent | int(10) | このディレクトリが子となっているディレクトリのID | |
directoryname | varchar(255) | このディレクトリの実際のディレクトリ名 |
skodak: ファイルパスは、filesテーブルに保存されます - ファイルパスのルートは、対応するファイルエリアになります。すべてのプラグイン/コースを検索するため、ファイルマネージャはコンテクストツリーを使用して、内部にある小ブランチを含んだエリア一覧を戻すよう求めます。
関連情報
- 開発:ファイルAPIの利用
- 開発:リポジトリAPI
- 開発:ポートフォリオAPI
- MDL-14589 - File APIのメタ問題