開発:コーディング

提供:MoodleDocs
2022年1月22日 (土) 15:03時点におけるMitsuhiro Yoshida (トーク | 投稿記録)による版
移動先:案内検索

再作成中です - Mitsuhiro Yoshida (トーク)

このページはMoodleのコーディングガイドラインを説明するためのトップレベルのページです。 あなたがMoodleのコードをどのように書くか知りたい場合、ここから始めてください。

Moodleアーキテクチャ

Moodleではインストール、利用、アップグレード、他のシステムとの統合が容易でありながら、可能な限り多くの人々のためにできるだけ幅広いプラットフォームでも動作するよう心がけています。

詳細はMoodleアーキテクチャをご覧ください。

プラグイン Plugins

Moodleにはモジュール化という一般的な哲学があります。 30種類近い標準的なプラグインタイプおよびさらに多くのサブプラグインタイプがありますが、これらのプラグインタイプはすべて同じように動作します。そして、ブロックおよび活動は唯一の小さな例外です。

詳細は MoodleプラグインおよびMoodleサブプラグインをご覧ください。

コーディングスタイル

一貫したコーディングスタイルはどんな開発プロジェクトにおいても重要であり、多くの開発者が関わる場合は特にそうです。標準的なスタイルはコードが読みやすく、理解しやすいことを保証して、全体の品質向上に役立ちます。

この方法でコードを書くことはあなたのコードがMoodleコミュニティにより受け入れられるための重要なステップです。

私たちのMoodleコーディングスタイルドキュメントではこの標準を説明しています。

セキュリティ

セキュリティとは私たちのすべてのユーザの利益およびデータを守ることです。 Moodleは銀行のソフトウェアではないかもしれませんが、プライベートな議論および成績のような多くの機密かつ重要なデータを外部の目 (または学生のハッカー!) から保護して、さらに私たちのユーザをスパム発信者および他のインターネット犯罪者から保護しています。

Moodleは人々のサーバ上で動作するスクリプトでもあるため、責任あるインターネット市民である必要があり、動作するサーバにクラッカによる不法アクセスを可能にする脆弱性を持ち込まないようにしなければなりません。

Moodleコアまたはサードパーティモジュールの スクリプト1つで何千ものサイトに脆弱性をもたらせるため、すべての開発者は私たちの Moodleセキュリティガイドライン に厳密に従うことが重要です。

XHTMLおよびCSS

Moodleはすべての一般的なアクセシビリティガイドライン (http://www.w3.org/TR/WCAG20/ W3C WAG 2.0], ARIA など) に準拠した厳格で的確な HTML 5 コード (可能であれば [[XHTML|XHTML 1.1] と下位互換性のあることが望ましい) の生成が重要です。

レイアウトにはCSSを使用してください。Moodleにはいくつかのテーマがインストールされています。バージョン2.7以降、「クリーン」テーマのみがMoodleの基本コードに含まれています。「標準」テーマは他のテーマのビルディングブロックとして動作するのに適したプレーンなテーマであるべきです。このテーマにはMoodleの外観を整え機能的にするための最小限のスタイルが含まれていなければなりません。そして、Moodleには見た目が良くテーマ構築のための様々なテクニックを示す他のいくつかのデフォルトテーマが付属しています。

これはブラウザ間の一貫性をきれいに低下させて (特に非ビジュアルブラウザまたはモバイルブラウザを使用している人)、テーマデザイナの生活を向上させるのに役立ちます。

JavaScript

Moodleの新しいJavscriptはES6スタイルのバニラJavscriptとして記述されるべきです。jQuery、YUI、およびその他のフレームワークの使用は強く推奨されません。これらのオブジェクトの使用を必要とするレガシーインターフェースを扱う場合を除き、コアに受け入れられることはありません。

一般に削除されたインターフェースを表示したり、ページ読み込み中に新しいインターフェースを追加しないようコードを記述する必要があります。

すべてのJavascriptはアクセス可能でなければなりません。

Internationalisation

私たちが言語パックの言語文字列およびロケール情報をコードから分離することに細心の注意を払っているため、Moodleは84以上の言語で動作します。

しかし、すべてのコード、コメントおよびドキュメントのデフォルト言語は英語(AU)です。

詳細: ストリングAPI

アクセシビリティ

Moodleは可能な限り多くの人々にうまく動作する必要があります。

詳細はMoodleアクセシビリティをご覧ください。

ユーザビリティ Usability

詳細はインターフェースガイドラインをご覧ください (作成中)。

パフォーマンス Performance

上の理由から、運用サイトでは推奨されないいくつかの機能 (特に開発者のための機能) が存在します。

最も重要な特性はスケーラビリティであり、ユーザ数、コース数、コース内の活動数等が多少増えたとしても、サーバの負荷はそれに比例して増加するだけです。

詳細な情報およびアドバイスに関してパフォーマンスおよびスケーラビリティをご覧ください。

データベース

Moodleには私たちが書いたXMLDBと呼ばれる強力なデータベース抽象化レイヤがあります。 これにより、同じMoodleコードがMySQL/MariaDB、PostgreSQL、MS SQL ServerおよびOracleで動作します。Oracleを使用する場合、既知の問題があります。Oracleは完全にサポートされていないため、実運用環境には推奨されません。

私たちには[DDL関数|テーブル定義および変更]]のためのツールおよびデータベースからデータを出し入れするためのメソッドがあります。

概要: Moodleデータベースガイドライン

イベント

Moodleは「イベント」でモジュール間のコミュニケーションを可能にします。 モジュールは特定のイベントを「起動」できます。また、他のモジュールはそれらのイベントを「処理/観察」できます。

詳細:

  • イベントAPI - Moodle 2.6以降 - 特に[イベントAPI#イベント命名規則|イベント命名規則]]に注意してください。

ウェブサービス

ウェブサービスは命名規則を含むWebサービスAPI関数およびコアへのWebサービス関数寄稿方法に従って実装する必要があります。

手動テスト

コアコードベースに統合されたすべての問題は統合時にテストされます。その後、私たちのテストチームによりテストされます。テストの多くの部分は自動化されていますが、自動化できない部分も多く、手動でのテストが必要です。

Moodleには明確なテスト指示の書き方のガイドラインがあります。このガイドラインを読んだ上で従うことをお勧めします。

単体テスト Unit testing

Unit testing is not simply a technique but a philosophy of software development. 単体テスト単なる技術ではなく、ソフトウェア開発の哲学でもあります。 ] The idea is to create automatable tests for each bit of functionality that you are developing (at the same time you are developing it). This not only helps everyone later test that the software works, but helps the development itself, because it forces you to work in a modular way with very clearly defined structures and goals.

Moodle uses a framework called PHPUnit that makes writing unit tests fairly simple.

See PHPUnit for more information.

Acceptance testing

PHPUnit covers mostly the internal implementation of functions and classes, the user interaction testing can be automated using the Behat framework.

See Acceptance testing for more information.

Third Party Libraries

Moodle has a standard way to include third party libraries in your code. See https://docs.moodle.org/dev/Third_Party_Libraries

Other standards

Please note that Moodle coding style and design is pretty unique, it is not compatible with PEAR coding standards or any other common PHP standards.

■■■■■■ OLD DOCUMENT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 協力的なプロジェクトを堅牢にするために、一貫性および安定性は必要です。

このガイドラインは、Moodleコードが目指すゴールを提示するためにあります。間違いなく、いくつかの古いコードは少数の場所で目標基準に達していませんが、最終的に修正します。すべての新しいコードは、これらの基準を可能な限り確実に順守してください。

一般ルール

  1. すべてのコードファイルは、.php拡張子を使用してください。
  2. すべてのテンプレートファイルは、.html拡張子を使用してください。
  3. すべてのテキストファイルは、Unixスタイルのテキストフォーマットを使用してください。 ( ほとんどのテキストエディタには、このオプションがあります。 )
  4. すべてのphpタグは、<?php ?> のように「フルタグ」を使用してください ... <? ?> のように「ショートタグ」ではなく。
  5. すべての著作権情報は保持してください。必要であれば、あなた独自の情報を追加することができます。
  6. 各ファイルでは、config.phpをインクルードしてください。
  7. 各ファイルでは、require_login() および isadmin()、isteacher()、iscreator() または isstudent() を使用してユーザが正しく認証されているか確認してください。
  8. データベースへのアクセスは、可能な場合は常に関数 lib/datalib.php を使用してください - この関数により幅広いデータベースの互換性を実現します。この関数を使用することにより、ほとんどのことが実現できることに気づくでしょう。SQLコードを書く必要がある場合、次のことを確認してください: クロスプラットフォームであること、あなたのコードが特定の関数 ( 通常、lib.phpファイル ) に限定されていること、明確に注釈がなされていること。
  9. $CFG、$SESSION、$THEME および $USER のような標準的なもの以外、グローバル変数を作成または使用しないでください。
  10. すべての変数は使用する前に初期化するか、少なくとも isset() または empty() を使用して存在チェックを行ってください。
  11. すべてのストリングは翻訳できるようにしてください - 「lang/en」内のファイルに新しい簡潔な英語の小文字でテキストを作成して、あなたのコードから get_string() または print_string() を使用して取り出してください。
  12. すべてのヘルプファイルは翻訳できるようにしてください - 「en/help」ディレクトリ内に新しいテキストを作成して、helpbutton() でコールしてください。 ヘルプファイルを更新したい場合は:
    • 小規模の変更の場合、古い翻訳ファイルはまだ意味をなすため、変更することが可能ですが、translation@moodle.org にご連絡ください。
    • 大規模の変更の場合、翻訳者が新しいバージョンのファイルだと簡単に分かるように、インクリメントした番号を付加した新しいファイル ( 例 filename2.html ) を追加してください。当然、新しいコードおよびヘルプインデックスファイルは、最新バージョンをポイントするように修正する必要もあります。
  13. ブラウザから ( GET または POST 経由で ) 入ってくるデータは、( PHPの設定に関わらず ) 安全にデータベースにインサートできるよう、自動的に magic_quotes が適用されます。他のすべての生データ ( ファイルまたはデータベース ) は、データベースにインサートする前に addslashes() でエスケープしてください。
  14. 重要: Moodle内のすべてのテキスト、特にユーザによって入力されるものは format_text() 関数を使用してプリントしてください。これによりテキストは、正確にフィルタおよびクリーニングされます。
  15. ユーザログは、add_to_log()関数を使用して記録してください。これらのログは、活動レポートおよびログで使用されます。

コーディングスタイル

他のスタイルを使用してきた場合、あなたのスタイルを変更することは少々面倒なことであると私は理解しています。しかし、後で人々が雑多なスタイルが使用されたMoodleコードの意味を理解する面倒さと、この面倒さのバランスを取る必要があります。人々が使用するスタイルには、明らかに良い部分もありますが、現在のスタイルはこのスタイルですので、どうか従ってください。

1. インデント は連続した4つのスペースにしてください。タブは使用しないでください。

2. 変数名 は常に読みやすく、意味のある英語小文字にしてください。本当に1語以上の単語が必要な場合、単語を連結して可能な限り短くしてください。配列オブジェクト名には、複数形を使用してください。

     良い: $quiz
     良い: $errorstring
     良い: $assignments (for an array of objects)
     良い: $i (but only in little loops)
     悪い: $Quiz
     悪い: $aReallyLongVariableNameWithoutAGoodReason
     悪い: $error_string

3. 定数 は常に大文字を使用して、常にモジュール名で始めてください。単語はアンダースコア ( _ ) で別けてください。

     define("FORUM_MODE_FLATOLDEST", 1);

4. 関数名 は単純な英語の小文字の単語を使用して、モジュール間のコンフリクトを避けるため、モジュール名で始めてください。 単語はアンダースコア ( _ ) で別けてください。可能でしたら、パラメータは常に適切なデフォルト値を持つようにしてください。 関数名および続く ( 大括弧 ) の間にはスペースを入れないことに注意してください。

     function forum_set_display_mode($mode=0) {
         global $USER, $CFG;
         
         if ($mode) {
             $USER->mode = $mode;
         } else if (empty($USER->mode)) {
             $USER->mode = $CFG->forum_displaymode;
         }
     }

5. ブロック は ( 1行のみでも ) 常に丸括弧で囲んでください。Moodleは、このようなスタイルを使用します。

     if ($quiz->attempts) {
         if ($numattempts > $quiz->attempts) {
             error($strtoomanyattempts, "view.php?id=$cm->id");
         }
     }

6. 文字列 は処理速度を増すため、可能であればシングル・クオテーションで定義してください。

     $var = 'some text without any variables';
     $var = "with special characters like a new line \n";
     $var = 'a very, very long string with a '.$single.' variable in it';
     $var = "some $text with $many variables $within it";

7. コメント は可能な限り実用的に追加し、コードの流れ、関数および変数の目的を説明してください。

  • すべての関数 ( およびクラス ) は、評判の良い phpDocフォーマット を使用してください。 phpDocにより、コードドキュメンテーションを自動的に生成することができます。
  • インラインコメントは、 // スタイルを使用し、コードおよび行が並ぶよう、きちんとレイアウトしてください。
     /**
     * The description should be first, with asterisks laid out exactly
     * like this example. If you want to refer to a another function,
     * do it like this: {@link clean_param()}. Then, add descriptions
     * for each parameter as follows.
     *
     * @param int $postid The PHP type is followed by the variable name
     * @param array $scale The PHP type is followed by the variable name
     * @param array $ratings The PHP type is followed by the variable name
     * @return mixed
     */
     function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
         if (!$ratings) {
             $ratings = array();     // Initialize the empty array
             if ($rates = get_records("forum_ratings", "post", $postid)) {
                 // Process each rating in turn
                 foreach ($rates as $rate) {
     ....etc

8. スペース は自由に使用してください - 明快さを得るために、物事を少し広げることを恐れないでください。一般的に、 大括弧と標準的な命令文の間には1つのスペースを入れますが、大括弧と変数および関数の間にはスペースを入れません。

     foreach ($objects as $key => $thing) {
         process($thing);
     }
     
     if ($x == $y) {
         $a = $b;
     } else if ($x == $z) {
         $a = $c;
     } else {
         $a = $d;
     }

9. オブジェクトのコピーを作成する場合、常にphp5 clone() 関数 ( そうでなければ最初のオブジェクトの参照で終わります ) を使用してください。Moodleは、これがphp4でも間違いなく動作するようにします。

     悪い:   $b = $a;
     良い:  $b = clone($a);

あなたがコピーしたいものがオブジェクトではない ( 例 オブジェクトの配列 ) 場合、代わりにfullclone() 関数を使用してください。

データベース構造

  1. すべてのテーブルは、プライマリインデックスとして auto-incrementing id フィールド ( INT10 ) を持つ必要があります。
  2. 各モジュールのインスタンスを含むメインテーブルは、モジュールと同じ名称を持ち ( 例 widget )、次の最小限のフィールドを含む必要があります:
    • id - 上記で説明
    • course - 各インスタンスが属するコースID
    • name - 各モジュールのインスタンスのフルネーム
  3. モジュールと関連する他のテーブルで「things」に関する情報を含むものは widget_things という名称を付けてください ( 複数形に注意してください )。
  4. カラムの名称は、変数名と同じルールに従って簡単かつ短くつけてください。
  5. 可能であれば、他のテーブルのidフィールドへの参照を含むカラム ( 例 widget ) は、widgetidと呼ばれるべきです。( この仕様は、やや新しいもので、他のいくつかの古いテーブルには適用されていないことに注意してください。)
  6. 論理値 ( Boolean ) フィールドは、必要に応じて後で値を拡張できるよう、0または1を含む整数フィールド ( 例 INT4 ) を使用してください。
  7. ほとんどのフィールドは、PHP time() 関数から現在のタイムスタンプで更新される timemodified フィールド ( INT10 ) を持つ必要があります。

セキュリティ関連 ( およびフォームおよびURLデータの取り扱い )

  1. 「register_globals」を信頼しないでください。すべての変数は、すべてのコードファイルで適切に初期化してください。変数がどこから来たか明らかでなければなりません。
  2. 空でもすべての配列およびオブジェクトを初期化してください。$a = array() または $obj = new stdClass();。
  3. optional_variable() 関数は使用しないでください。代わりに optional_param() 関数を使用してください。あなたが必要なデータタイプのために正しい PARAM_XXXX 値を選択してください。変数の任意の値をチェックおよびセットする場合、set_default() 関数を使用してください。
  4. require_variable() 関数を使用しないでください。代わりに required_param() 関数を使用してください。あなたが必要なデータタイプのために正しい PARAM_XXXX 値を選択してください。
  5. 気をつけて data_submitted() を使用してください。データは使用される前に、さらにきれいにする必要があります。
  6. $_GET、$_POST または $_REQUEST を使用しないでください。必要に応じて、適切な required_param() または optional_param() を使用してください。
  7. if (isset($_GET['something'])) のようなものを使用して動作をチェックしないでください。例えば $something = optional_param( 'something',-1,PARAM_INT ) を使用して、適切な値の幅に入っているかテストしてください。例 if ($something>=0) {...
  8. 簡単に探すことができるよう、可能な限りすべての required_param()、optional_param() および他の変数を各ファイルの最初で初期化してください。
  9. フォーム処理ルーチンをアタックから保護するために「sesskey」メカニズムを使用してください。基本的な使用例: フォームが生成されるときに、 include <input type="hidden" name="sesskey" value="<?php echo sesskey(); ?>" /> と使用します。フォームの処理を行うときは、 if (!confirm_sesskey()) {error('Bad Session Key');} でチェックしてください。
  10. required_param() または optional_param() の適切な使用で「きれいにされていない」場合、すべてのファイルは clean_filename() 関数を使用して「きれいにする」必要があります。
  11. データベースから読み込んだデータは、更新する前に addslashes() を適用してください。データオブジェクト全体は、addslashes_object() で一度に処理することができます。
  12. 可能な限り、データベースに保存するデータは、GETデータ ( 例 URLラインからのデータ ) とは対照的な POSTデータ ( method="POST" によるフォームデータ ) を使用してください。
  13. 避けることができるなら $_SERVER からのデータを使用しないでください。これは移植性に問題があります。
  14. 他で行っていない場合、データベースに書き込むすべてのデータを適切なデータタイプのPARAM_XXXXを使用して clean_param() 関数に通してください。
  15. あなたがカスタムSQLコードを記述する場合、間違いなく正しいことを確認してください。特に値の周囲のクォート漏れに気をつけてください。SQLインジェクションの脆弱性 ( exploit ) となる可能性があります。
  16. すべてのファイルで使用されるすべてのデータ ( 特にデータベースに書き込む部分) をチェックしてください。他でチェックされることを期待したり、信頼しないでください。
  17. インクルードされるコードのブロックは、明確なPHP構造を含むべきです ( 例 クラス宣言、関数定義等 ) - 連続したコードのブロックは、初期化なしの変数使用を奨励してしまいます。