「コーディングスタイル (Dev docs)」の版間の差分

提供:MoodleDocs
移動先:案内検索
 
(同じ利用者による、間の137版が非表示)
54行目: 54行目:
=== インデント ===
=== インデント ===


タブ文字を使用せず、インデントは '''4 スペース'''を使用してください。新しいタブ文字がソースコードに挿入されないように、エディタをタブをスペースとして扱うように設定する必要があります。
タブ文字を使用せず、インデントは '''4つのスペース'''を使用してください。新しいタブ文字がソースコードに挿入されないように、エディタをタブをスペースとして扱うように設定する必要があります。


メインスクリプトレベルをインデントしないでください:
メインスクリプトレベルをインデントしないでください:
97行目: 97行目:
行を折り返す場合、次のルールが一般的に適用されます。
行を折り返す場合、次のルールが一般的に適用されます。


* 通常は4スペースでインデントします。
* 通常は4つのスペースでインデントします。
* 制御文の条件や関数/クラス宣言といった折り返し行は、制御文や関数/クラスの本体と視覚的に区別できるように、4つのスペースでインデントします。
* 制御文の条件や関数/クラス宣言といった折り返し行は、制御文や関数/クラスの本体と視覚的に区別できるように、4つのスペースでインデントします。


146行目: 146行目:
         garply, waldo, fred, plugh, xyzzy, thud {
         garply, waldo, fred, plugh, xyzzy, thud {


     // クラス本体は4スペースでインデントされます。
     // クラス本体は4つのスペースでインデントされます。
}
}
</syntaxhighlight>
</syntaxhighlight>


また、読みやすくするために、実装されたインターフェ-スをそれぞれ1行にまとめて提供することもできます:
また、読みやすくするために、実装されたインターフェースをそれぞれ1行にまとめて提供することもできます:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
class provider implements
class provider implements
         // これらの行は、クラス本体と視覚的に区別するために、8個のスペースでインデントされます。
         // これらの行は、クラス本体と視覚的に区別するために、8つのスペースでインデントされます。
         \core_privacy\local\metadata\provider,
         \core_privacy\local\metadata\provider,
         \core_privacy\local\request\subsystem\provider,
         \core_privacy\local\request\subsystem\provider,
         \core_privacy\local\request\core_userlist_provider {
         \core_privacy\local\request\core_userlist_provider {


     // クラス本体は4スペースでインデントされます。
     // クラス本体は4つのスペースでインデントされます。
}
}
</syntaxhighlight>
</syntaxhighlight>
178行目: 178行目:
</syntaxhighlight>
</syntaxhighlight>


====Wrapping parameters of a function call====
====関数呼び出しのパラメータの折り返し====
Normally, parameters will just fit on one line. If they eventually become too long to fit a single line or of it helps readability, indent with 4 spaces.
通常、パラメータは1行に収まるようになっています。1行に収まらないほど長くなる場合や、読みやすくなる場合は、空白を4つ入れてインデントします。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
186行目: 186行目:
</syntaxhighlight>
</syntaxhighlight>


====Wrapping arrays====
====配列の折り返し====
There is nothing special and the general rules apply again. Indent the wrapped line with 4 spaces.
特別なことはなく、一般的なルールが再び適用されます。折り返し行を4つのスペースでインデントします。
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$plugininfo['preferences'][$plugin] = ['id' => $plugin, 'link' => $pref_url,  
$plugininfo['preferences'][$plugin] = ['id' => $plugin, 'link' => $pref_url,  
193行目: 193行目:
</syntaxhighlight>
</syntaxhighlight>


In many cases, the following style with each item on its own line will make the code more readable.
多くの場合、各項目を1行にまとめた以下のようなスタイルが、コードをより読みやすくします。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
202行目: 202行目:
];
];
</syntaxhighlight>
</syntaxhighlight>
Note the last item has a trailing comma left there which allows to extend the list of items later with a cleaner diff. For the same reason, it is better not to align the assignment operators.
最後の項目には末尾のカンマが残っていることに注意してください。これは、後で項目リストを拡張してよりきれいな差分を得ることができるようにするためです。同じ理由で、代入演算子も揃えない方がよいでしょう。


====Wrapping arrays passed as function parameter====
====関数のパラメータとして渡される配列の折り返し====
This is just an example of combining some of the examples above.
これは、上記のいくつかの例を組み合わせたものに過ぎません。
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$url = new moodle_url('/course/loginas.php', [
$url = new moodle_url('/course/loginas.php', [
213行目: 213行目:
</syntaxhighlight>
</syntaxhighlight>


===Line Termination===
===行の終端部===


* Every line must be terminated by a Unix line feed character (LF, decimal 10, hexadecimal 0x0A).
* すべての行は、Unixの改行文字(LF、10進数10、16進数 0x0A)で終了する必要があります。
* Carriage returns (CR, decimal 13, hexadecimal 0x0D) must NOT be used alone or with LFs.
* キャリッジリターン(CR、10進数13、16進数 0x0D)は単独または LF と一緒に使用してはいけません。
* There must be no whitespace characters (spaces or tabs) at the end of any line.
* 行末に空白文字(スペースやタブ)を入れてはいけません。
* There must be no extra blank lines at the end of a file; every file should end with a single LF character.
* ファイルの最後には余分な空白行があってはならず、すべてのファイルは1つの LF 文字で終わる必要があります。


''Note: This is consistent with the conventions of [https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md#22-files PSR-12].''
''注意: これは[https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md#22-files PSR-12]の規約と一致しています。''


==Naming Conventions==
==命名規則==


===Filenames===
===ファイル名===


Filenames should :
ファイル名は :
* be whole english words
* 全て英語であること
* be as short as possible
* できるだけ短くすること
* use lowercase letters only
* 小文字のみを使用すること
* end in .php, .html, .js, .css or .xml
* .php、.html、.js、.css、.xmlのいずかで終わること


===Classes===
===クラス===


Class names should always be lower-case English words, separated by underscores:
クラス名は必ず小文字の英単語で、アンダースコアで区切ってください:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
244行目: 244行目:
</syntaxhighlight>
</syntaxhighlight>


Always use () when creating new instances even if constructor does not need any parameters.
コンストラクタがパラメータを必要としない場合でも、新しいインスタンスを作成するときは常に()を使用します。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
250行目: 250行目:
</syntaxhighlight>
</syntaxhighlight>


When you want a plain object of no particular class, for example when you are preparing some data to insert into the database with $DB->insert_record, you should use the PHP standard class '''stdClass'''. For example:
例えば、$DB->insert_recordでデータベースに挿入するデータを準備するときなど、特定のクラスのないプレーンなオブジェクトが欲しいときは、PHP標準クラス '''stdClass''' を使用する必要があります。 例:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
259行目: 259行目:
</syntaxhighlight>
</syntaxhighlight>


''Before Moodle 2.0, we used to define a class '''object''' extending stdClass, and use new object(); This has now been deprecated. Please use stdClass instead.''
''Moodle 2.0以前では、私たちはstdClassを拡張したクラス '''object''' を定義し、new object() を使用していました; これは現在非推奨です。代わりに stdClass を使用してください。''


===Functions and Methods===
===関数および手法===


Function names should be simple English lowercase words, and start with the [[Frankenstyle]] prefix and plugin name to avoid conflicts between plugins. Words should be separated by underscores.
関数名は単純な英語の小文字の単語で、プラグイン間の衝突を避けるために [[Frankenstyle (Dev docs)|Frankenstyle]] のプレフィックスとプラグイン名で始まるようにします。単語はアンダースコアで区切られる必要があります。


Verbosity is encouraged: function names should be as illustrative as is practical to enhance understanding.
冗長性が奨励されます: 関数名は、理解を深めるために、できるだけ具体的に説明することが望ましいです。


The uses of type hints and return type declarations is required in PHP in all possible locations for all new code. There will be necessary exclusions, such as code extending existing non-compliant code and implementing things where it is not available. Progressive approach will be applied.
PHPでは、すべての新しいコードに対して、タイプヒントと戻り値の宣言の使用が可能なすべての場所で要求されています。既存の非準拠なコードを拡張するコードや、利用できないものを実装するコードなど、必要な除外項目があるものとします。プログレッシブ・アプローチが適用されます。


Note there is no space between the function name and the following (brackets). There is also no whitespace between the nullable character (question mark - ?) and params or return types or between the function closing brackets and the colon.
関数名と次の(括弧)の間にスペースがないことに注意してください。また、Nullable文字(クエスチョンマーク - ?)とパラメータやリターンタイプの間、関数の閉じ括弧とコロンの間にも空白がありません。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
function report_participation_get_overviews(string $action, ?int userid): ?array {
function report_participation_get_overviews(string $action, ?int userid): ?array {


     // Actual function code goes here.
     // 実際のファンクションコードはここに入ります。
}
}
</syntaxhighlight>
</syntaxhighlight>


There is an exception for [[Activity modules|activity modules]] that still use only plugin name as the prefix for legacy reasons.
ただし、レガシーな理由でプラグイン名のみをプレフィックスとして使用している[[活動モジュール (Dev docs)|活動モジュール]]は例外です。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
284行目: 284行目:
     global $USER, $CFG;
     global $USER, $CFG;
          
          
     // Actual function code goes here.
     // 実際のファンクションコードはここに入ります。
}
}
</syntaxhighlight>
</syntaxhighlight>


====Function Parameters====
====関数パラメータ====


Parameters are always simple lowercase English words (sometimes more than one, like $initialvalue), and should always have sensible defaults if possible.
パラメーターは常に単純な小文字の英単語($initialvalueのように複数の場合もあります)であり、可能な場合は常に適切なデフォルト値を持つべきです。


Use "null" as the default value instead of "false" for situations like this where a default value isn't needed.
このようにデフォルト値が必要ない場合は、"false" の代わりに "null" をデフォルト値として使用します。
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
public function foo($required, $optional = null)
public function foo($required, $optional = null)
</syntaxhighlight>
</syntaxhighlight>


However, if an optional parameter is boolean, and its logical default value should be true, or false, then using true or false is acceptable.
ただし、オプションのパラメータが boolean であり、その論理的なデフォルト値が true または false である場合は、true または false を使用しても構いません。


===Variables===
===変数===


Variable names should always be easy-to-read, meaningful lower-case English words. If you really need more than one word then run them together, but keep them as short as possible. Use '''plural''' names for arrays of objects. Use '''positive''' variables names always (allow, enable not prevent, disable).
変数名は常に読みやすく、意味がある小文字の英単語でなければなりません。もし1つ以上の単語が必要な場合は、連結して書くことができますが、できるだけ短く保つようにしてください。オブジェクトの配列には、'''複数形''' の名前を使用してください。そして、変数名には、常に '''肯定的''' な言葉を使うようにしてください。(例えば、prevent や disable ではなく、allow や enable などです。


  GOOD: $quiz
  GOOD: $quiz
315行目: 315行目:
  BAD: $preventfilelocking = true
  BAD: $preventfilelocking = true


Core global variables in Moodle are identified using uppercase variables (ie $CFG, $SESSION, $USER, $COURSE, $SITE, $PAGE, $DB and $THEME).  Don't create any more!
Moodleのコアグローバル変数は、大文字の変数 ($CFG、$SESSION、$USER、$COURSE、$SITE、$PAGE、$DBおよび$THEME) を使用して識別します。 これ以上作らないでください!


===Constants===
===定数===


Constants should always be in upper case, and always start with [[Frankenstyle]] prefix and plugin name (in case of activities the module name only for legacy reasons). They should have words separated by underscores.
定数は常に大文字で、常に [[Frankenstyle (Dev docs)|Frankenstyle]] のプレフィックスとプラグイン名で始まります(レガシーな理由からモジュール名のみで活動する場合)。単語はアンダースコアで区切ってください。
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
define('BLOCK_COURSE_OVERVIEW_SHOWCATEGORIES_NONE', '0');
define('BLOCK_COURSE_OVERVIEW_SHOWCATEGORIES_NONE', '0');
325行目: 325行目:
</syntaxhighlight>
</syntaxhighlight>


===Booleans and the null value===
===ブーリアンおよびヌル値===


Use lower case for '''true''', '''false''' and '''null'''.
'''true''''''false''''''null'''は小文字を使用してください。


=== Namespaces ===
=== 名前空間 ===


Formal namespaces are required for any new classes in Moodle. The following exceptions apply:
Moodleの新しいクラスには、正式な名前空間が必要です。ただし、以下の例外があります:
# There is no requirement to move existing non-namespaced classes to a namespace; and
# 既存の非名前空間クラスを名前空間に移動させる必要はありません; また
# Where an existing mechanism exists for loading a class, and that mechanism does not support the use of a namespaced class, the existing [[Frankenstyle]] prefix on the class name will be allowed.
# クラスを読み込むための既存のメカニズムが存在し、そのメカニズムが名前空間クラスの使用をサポートしていない場合、クラス名に既存の [[Frankenstyle (Dev docs)|Frankenstyle]] プレフィックスを使用することが許可されます。


The use of a [[Frankenstyle#Class names|Frankenstyle prefix on class names]] is deprecated and should only be used in the above exceptions.
クラス名に対する[[Frankenstyle (Dev docs)#クラス名|クラス名のFrankenstyleプレフィックス]]の使用は非推奨であり、上記の例外においてのみ使用されるべきである。


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace mod_forum;
namespace mod_forum;
351行目: 351行目:
</syntaxhighlight>
</syntaxhighlight>


BAD (deprecated):
悪い例 (非推奨):
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
class mod_forum_example {
class mod_forum_example {
363行目: 363行目:
</syntaxhighlight>
</syntaxhighlight>


The use of namespaces must conform to the following rules:
名前空間の使用は、以下のルールに従う必要があります:
# Classes belonging to a namespace must be created in a classes directory inside a plugin (e.g. mod/forum/classes), or for core code, in lib/classes or subsystemdir/classes.
# 名前空間に属するクラスは、プラグイン内のクラスディレクトリ(例:mod/forum/classes)または、コアコードの場合は lib/classes または subsystemdir/classesに作成する必要があります。
# The classname and filename for all namespaced classes must conform to the [[Automatic class loading|automatic class loading]] rules. The use of formal PHP namespaces in all new code is required.
# すべての名前空間に属するクラスのクラス名とファイル名は、[[クラスの自動読み込み (Dev docs)|クラスの自動読み込み]]ルールに従う必要があります。新しいコードには、形式的なPHP名前空間の使用が必要です。
# Use at most one namespace declaration per file.
# ファイルあたり1つの名前空間宣言を使用する必要があります。


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
<? // This is a file mod/porridge/classes/local/equipment/spoon.php
<? // これは mod/porridge/classes/local/equipment/spoon.php のファイルです。


namespace mod_porridge\local\equipment;
namespace mod_porridge\local\equipment;


class spoon {
class spoon {
     // Your code here.
     // ここにあなたのコード。
}
}


// End of file.
// ファイルの終了。
</syntaxhighlight>
</syntaxhighlight>


BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace mod_porridge\local\equipment;
namespace mod_porridge\local\equipment;


class spoon {
class spoon {
     // Your code here.
     // ここにあなたのコード。
}
}


namespace mod_porridge\local\procedures; // We are changing the namespace here, do not do it.
namespace mod_porridge\local\procedures; // ここで名前空間を変更しているため、変更しないでください。


class eat {
class eat {
     // Another code here.
     // ここにもう1つのコード。
}
}


// End of file.
// ファイルの終了。
</syntaxhighlight>
</syntaxhighlight>


The namespace declaration may be preceded with a doc block.
名前空間宣言は、ドックブロックで先行することができます。


The [[Coding style#Classes|class naming]] rules also apply to the names for each level of namespace.
[[コーディングスタイル (Dev docs)#クラス|クラスの命名]]は、名前空間の各レベルの名前にも適用されます。


The namespace declaration must be the first non-comment line in the file, followed by one blank line, followed by the (optional)
名前空間宣言は、ファイル内で最初の非コメント行でなければならず、1つの空白行に続いて(オプションで)1行に1つの "use" ステートメントが続き、さらに1つの空白行が続きます。
"use" statements, one per line, followed by one blank line.


"use" statements should be used to avoid repetition of long namespaces in the code.
"use" ステートメントは、コード内で長い名前空間を繰り返し使うのを避けるために使用する必要があります。


Do not import an entire namespace with a "use" statement, import individual classes only.
"use" ステートメントを使用して、名前空間全体をインポートしないでください。個々のクラスだけをインポートしてください。


Do not use named imports ("use XXX as YYY;") unless it is absolutely required to resolve a conflict.
衝突を解決するために絶対に必要でない限り、名前を付けてインポートしないでください("use XXX as YYY;")。


GOOD:
良い例:
<syntaxhighlight lang="php">use mod_porridge\local\equipment\spoon; // One class per line.
<syntaxhighlight lang="php">use mod_porridge\local\equipment\spoon; // 1行につき1つのクラスです。
use mod_porridge\local\equipment\bowl; // One class per line.
use mod_porridge\local\equipment\bowl; // 1行につき1つのクラスです。


</syntaxhighlight>
</syntaxhighlight>


BAD:
悪い例:
<syntaxhighlight lang="php">use mod_porridge\local\equipment\spoon, mod_porridge\local\equipment\bowl; // Multiple classes per line.
<syntaxhighlight lang="php">use mod_porridge\local\equipment\spoon, mod_porridge\local\equipment\bowl; // 1行に複数のクラスがあります。
use mod_porridge\local; // Importing an entire namespace.
use mod_porridge\local; // 名前空間全体をインポートします。
use core; // Importing an entire namespace.
use core; // 名前空間全体をインポートします。
use mod_breakfast; // Importing an entire namespace.
use mod_breakfast; // 名前空間全体をインポートします。
use mod_porridge\local\equipment\spoon as silverspoon; // Named import with no good reason.
use mod_porridge\local\equipment\spoon as silverspoon; // 名前を付けてインポートする理由がありません。


</syntaxhighlight>
</syntaxhighlight>


Never use the __NAMESPACE__ magic constant.
__NAMESPACE__のマジック定数を使用しないでください。


Never use the "namespace" keyword anywhere but the namespace declaration.
名前空間宣言以外の場所で "namespace" キーワードを使用しないでください。


BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$obj = new namespace\Another();
$obj = new namespace\Another();
</syntaxhighlight>
</syntaxhighlight>


Do not use bracketed "namespace" blocks.
ブラケットで囲まれた "namespace" ブロックを使用しないでください。


BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace {
namespace {
     // Global scope.
     // グローバルスコープ。
}
}
</syntaxhighlight>
</syntaxhighlight>


Namespaces MUST only be used for classes existing in a subfolder of "classes".
名前空間は、"classes" のサブフォルダに存在するクラスにのみ使用する必要があります。


For new classes - the maximum level of detail should be used when deciding the namespace.
新しいクラスの場合 - 名前空間を決定する際には、最大の詳細レベルを使用する必要があります。


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace xxxx\yyyy; // xxxx is the component, yyyy is the api.
namespace xxxx\yyyy; // xxxx はコンポーネント、 yyyy はAPIです。


class zzzz {
class zzzz {
456行目: 455行目:
</syntaxhighlight>
</syntaxhighlight>


Never use a leading backslash (\) in "namespace" and "use" statements.
"namespace" および "use" ステートメントで先頭にバックスラッシュ(\)を使用しないでください。


Global functions called from namespaced code should never use a leading
名前空間付きのコードから呼び出されるグローバル関数には、先頭にバックスラッシュ(\)を使用しないでください。現在のスコープの外側のクラスは、先頭にバックスラッシュを使用するか、"use" キーワードでインポートされます。詳細については、[https://www.php.net/manual/ja/language.namespaces.fallback.php PHPマニュアル]を参照してください。
backslash (\). Classes from outside the current scope use the leading backslash
or are imported by the "use" keyword. See
[https://www.php.net/manual/en/language.namespaces.fallback.php PHP manual] for
details.


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace mod_breakfast\local;
namespace mod_breakfast\local;
470行目: 465行目:
use moodle_url;
use moodle_url;


echo get_string('goodmorning', 'mod_breakfast'); // No leading backslash for global functions.
echo get_string('goodmorning', 'mod_breakfast'); // グローバル関数の先頭にバックスラッシュがありません。
$url = new moodle_url(...); // Leading backslash not needed here because we imported it into our namespace via "use".
$url = new moodle_url(...); // "use" で名前空間にインポートしているので、先頭のバックスラッシュは必要ありません。
$tasks = \core\task\manager::get_all_scheduled_tasks(); // Leading slash needed here.
$tasks = \core\task\manager::get_all_scheduled_tasks(); // ここでは先頭にスラッシュが必要です。
$a = new \stdClass(); // Leading slash needed here.
$a = new \stdClass(); // ここでは先頭にスラッシュが必要です。
</syntaxhighlight>
</syntaxhighlight>


BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace \mod_breakfast; // The leading backslash should not be here.
namespace \mod_breakfast; // 先頭のバックスラッシュはあってはいけません。


use \core\task\manager; // The leading backslash should not be here.
use \core\task\manager; // 先頭のバックスラッシュはあってはいけません。


\get_string('xxxx', 'yyyy'); // The leading backslash should not be here.
\get_string('xxxx', 'yyyy'); // 先頭のバックスラッシュはあってはいけません。
</syntaxhighlight>
</syntaxhighlight>


==== Parts of a namespace ====
==== 名前空間の構成要素 ====


Given the following fully qualified name of a class:
以下のような完全修飾名でクラスが示されている場合:


"\<level1>\<level2>\<level3>\...\<classname>"
"\<level1>\<level2>\<level3>\...\<classname>"


There are clear rules for what is allowable at each level of namespace. Only the first level is mandatory. Nested namespaces are used when the class implements some core API or when the plugin maintainer want to organise classes to separate namespaces within the plugin - see rules regarding the level2 for details.
各名前空間のレベルには許容される要素について明確な規則があります。最初のレベルだけが必須です。クラスがコアAPIを実装する場合や、プラグイン管理者がプラグイン内の名前空間を分けてクラスを整理する場合は、ネストされた名前空間が使用されます。詳細はlevel2に関する規則を参照してください。


==== Rules for level1 ====
==== レベル1のルール ====


The first level MUST BE EITHER:
最初のレベルは、次のいずれかでなければなりません:
* a full component name (e.g. "\mod_forum"). All classes using namespaces in a plugin MUST be contained in
* 完全なコンポーネント名(例:"\mod_forum")。プラグインで名前空間を使用するすべてのクラスは、このレベル1の名前空間に含まれている必要があります。
this level 1 namespace.
または
or
* すべてのコアAPIに対して "\core" を使用してください。
* "\core" for all core apis


==== Rules for level2 ====
==== レベル2のルール ====


The second level, when used, MUST BE EITHER:
第2レベルは、使用される場合、次のいずれかでなければなりません:
* The short name of a core API (must be defined on https://docs.moodle.org/dev/API). The classes in this namespace must either implement or use the API in some way.
* コアAPIの短い名前(https://docs.moodle.org/dev/API で定義されている必要があります)。この名前空間のクラスは、APIを実装または使用する必要があります。
or
または
* "\local" for any other classes in a component, if the maintainer wants to organise them further (note that for most components, it's probably enough to have all their own classes in the root level1 namespace only).
* コンポーネント内の他のクラスをさらに整理したい場合は、"\local" を使用します(ほとんどのコンポーネントでは、ルートレベル1の名前空間のみにすべての独自のクラスを持つことで十分であることに注意してください)。


==== Rules for level3 ====
==== レベル3のルール ====


There are no rules limiting what can be used as a level 3 namespace. This is where a plugin or addon can make extensive use of
レベル3名前空間として使用できるものを制限するルールはありません。このため、プラグインやアドオンがレベル3の名前空間として使用することができます。
namespaces with no chance of conflict with any other plugin or api, now and forever onwards.
の名前空間は、他のプラグインやapiと衝突する可能性がなく、現在も、そしてこれからも、ずっと続くでしょう。


==== Namespaces within **/tests directories ====
==== **/testsディレクトリ内の名前空間 ====
(agreed @ MDLSITE-4800)
(MDLSITE-4800で合意)


* The use of namespaces is strongly recommended for unit tests.
* ユニットテストでは、名前空間の利用を強く推奨します。
* When using namespaces, the namespace of the test class should match the namespace of the code under test.
* 名前空間を使用する場合、テストクラスの名前空間は、テスト対象のコードの名前空間と一致させる必要があります。
* Test classes should be named after the class under test, and suffixed with `_test.php`.
* テストクラスは、テスト対象のクラスから名前をとり、`_test.php` を接尾辞としてつける必要があります。
* The 1st level namespace of the test class '''must''' match the component it belongs to.
* テストクラスの第 1 レベルの名前空間は、それが属するコンポーネントと一致 '''しなければなりません'''
* Sub-namespaces are allowed, strictly following the general namespace rules for levels 2 & 3 above. Always trying to match as much as possible the namespace of the code being covered.
* サブの名前空間は許可されますが、上記のレベル2および3の一般的な名前空間のルールに厳密に従う必要があります。常に、対象となるコードの名前空間と可能な限り一致させるようにします。
* Sub-directory structure must match the namespace structure, but will be placed in the `tests` directory instead.
* サブディレクトリの構造は、名前空間の構造と一致しなければなりませんが、代わりに `tests` ディレクトリに配置されます。


Please note: auto-loading of tests is not supported (but autoloading the standard class from a test is).
注意:テストの自動読み込みはサポートされていません(ただし、テストから標準クラスを自動読み込みすることは可能です)。


==== Examples ====
==== ====


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
// Plugin's own namespace when not using nested namespaces (typical)
// 入れ子になった名前空間を使用しない場合のプラグイン固有の名前空間(一般的な)
// Namespace location: mod/breakfast/classes/
// 名前空間の場所:mod/breakfast/classes/
// Test location: mod/breakfast/tests/
// テストの場所:mod/breakfast/tests/
namespace mod_breakfast;
namespace mod_breakfast;


// Plugin's own namespace when using nested namespaces
// 入れ子になった名前空間を使用する場合のプラグイン固有の名前空間
// Namespace location: mod/breakfast/classes/local/
// 名前空間の場所:mod/breakfast/classes/local/
// Test location: mod/breakfast/tests/local/
// テストの場所:mod/breakfast/tests/local/
namespace mod_breakfast\local;
namespace mod_breakfast\local;


// Plugin's own namespace when using nested namespaces with further organisation
// さらに組織化された入れ子になった名前空間を使用する場合のプラグイン固有の名前空間
// Namespace location: mod/breakfast/classes/local/utils/
// 名前空間の場所:mod/breakfast/classes/local/utils/
// Test location: mod/breakfast/tests/local/utils/
// テストの場所:mod/breakfast/tests/local/utils/
namespace mod_breakfast\local\utils;
namespace mod_breakfast\local\utils;


// Plugin's namespace to implement core API
// コアAPIを実装するためのプラグインの名前空間
// Namespace location: mod/breakfast/classes/event/
// 名前空間の場所:mod/breakfast/classes/event/
// Test location: mod/breakfast/tests/event/
// テストの場所:mod/breakfast/tests/event/
namespace mod_breakfast\event;
namespace mod_breakfast\event;
</syntaxhighlight>  
</syntaxhighlight>  


BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
namespace mymodule;                    // Violates the level1 rules - invalid component name
namespace mymodule;                    // レベル1のルールに違反 - 無効なコンポーネント名
namespace mod_breakfast\myutilities;    // Violates the level2 rules - invalid core API name
namespace mod_breakfast\myutilities;    // レベル2のルールに違反 - 無効なコアAPI名
namespace mod_forum\test;              // While technically correct ("test" is a valid API) - it's not ok
namespace mod_forum\test;              // 技術的には正しいですが("test" は有効なAPIです) - これは許容できません
                                         // because the namespace in tests should match the namespace of the code
                                         // なぜなら、テストの名前空間はコードの名前空間と一致する必要があるためです
                                         // being covered, and normally components don't have any "test"
                                         // 通常、コンポーネントに "test" という名前のものは存在しないため、これはカバーされるべきではありません
                                         // level-2 to be covered. Only then it could be used.
                                         // レベル2がカバーされた後にのみ、それを使用することができます
</syntaxhighlight>
</syntaxhighlight>


== Strings ==
== 文字列 ==


Since string performance is not an issue in current versions of PHP, the main criteria for strings is readability.
現在のPHPバージョンでは、文字列のパフォーマンスは問題にならないため、文字列の主な基準は可読性です。


===Single quotes===
=== シングルクォーテーション ===


Always use single quotes when a string is literal, or contains a lot of double quotes (like HTML):
文字列がリテラルである場合や、ダブルクォーテーションが多く含まれる場合(HTMLなど)、常にシングルクォーテーションを使用してください。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
574行目: 568行目:
</syntaxhighlight>
</syntaxhighlight>


===Double quotes===
===ダブルクォーテーション===


These are a lot less useful in Moodle. Use double quotes when you need to include plain variables or a lot of single quotes.
これらは、Moodleではあまり役に立ちません。プレーンな変数や多くのシングルクォーテーションを含める必要がある場合、ダブルクォーテーションを使用してください。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
583行目: 577行目:
</syntaxhighlight>
</syntaxhighlight>


Complex SQL queries should be always enclosed in double quotes.
複雑なSQLクエリは、必ずダブルクォーテーションで囲む必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
593行目: 587行目:
</syntaxhighlight>
</syntaxhighlight>


===Variable substitution===
===変数の置換===


Variable substitution can use either of these forms:
変数の置換には、次のいずれかの形式を使用できます:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
603行目: 597行目:
</syntaxhighlight>
</syntaxhighlight>


===String concatenation===
=== 文字列の結合 ===


Strings must be concatenated using the "." operator.
文字列は "." 演算子を使用して結合する必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$longstring = $several.$short.'strings';
$longstring = $several . $short . 'strings';
</syntaxhighlight>
</syntaxhighlight>
 
行が長い場合は、可読性を向上させるために、ステートメントを複数の行に分割してください。この場合、各行の最後に "ドット" を置いてください。
If the lines are long, break the statement into multiple lines to improve readability.  In these cases, put the "dot" at the end of each line.


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$string = 'This is a very long and stupid string because '.$editorname.
$string = 'This is a very long and stupid string because ' . $editorname .
           " couldn't think of a better example at the time.";
           " couldn't think of a better example at the time.";
</syntaxhighlight>
</syntaxhighlight>
The dot operator may be used without any space to either side (as shown in the above examples), or with spaces on each side; whichever the developer prefers.
演算子 "." は、上記の例に示されるように、どちらの側にもスペースを入れずに使用することもできます。開発者が好む方法を使用してください。


===Language strings===
=== 言語文字列 ===


====Capitals====
==== 大文字と小文字 ====


Language strings should "Always look like this" and "Never Like This Example".
言語文字列は "Always look like this(このように常に見える)""Never Like This Example(このように決して見えない)" のように書くべきです。


Capitals should only be used when:
大文字は、次の場合にのみ使用する必要があります:
# starting a sentence, or
# 文章の先頭で始まる場合、または
# starting a proper name, like Moodle.
# Moodle のような固有名詞で始まる場合。


====Structure====
====構造====


Strings should not be designed for UI concatenation, as it may cause problems in other languages.  Each string should stand alone.
文字列は UI の連結を想定して設計されていないため、他の言語で問題が発生する可能性があります。各文字列は単独で機能する必要があります。


BAD:   
悪い例:   
  $string['overduehandling'] = 'When time expires';
  $string['overduehandling'] = 'When time expires';
  $string['overduehandlingautosubmit'] = 'the attempt is submitted automatically';
  $string['overduehandlingautosubmit'] = 'the attempt is submitted automatically';
639行目: 632行目:
  $string['overduehandlingautoabandon'] = 'that is it. The attempt must be submitted before time expires, or it is not counted';
  $string['overduehandlingautoabandon'] = 'that is it. The attempt must be submitted before time expires, or it is not counted';


GOOD:
良い例:
  $string['overduehandling'] = 'Time expiry behaviour';
  $string['overduehandling'] = 'Time expiry behaviour';
  $string['overduehandlingautosubmit'] = 'Unfinished attempts will be auto-submitted immediately';
  $string['overduehandlingautosubmit'] = 'Unfinished attempts will be auto-submitted immediately';
645行目: 638行目:
  $string['overduehandlingautoabandon'] = 'Unfinished attempts are immediately discarded';
  $string['overduehandlingautoabandon'] = 'Unfinished attempts are immediately discarded';


====Whitespace====
==== 空白 ====


Language strings should not contain or even rely on any leading or trailing whitespace. Such strings are not easy to be translated in the translation tool, AMOS.
言語文字列には、前後にスペースを含めたり、依存したりしないでください。そのような文字列は、AMOS翻訳ツールで翻訳することが容易ではありません。


==Arrays==
== 配列 ==


===Numerically indexed arrays===
=== 数値インデックス付きの配列 ===


When declaring arrays, a trailing space must be added after each comma delimiter to improve readability:
配列を宣言する際には、可読性を向上させるため、各カンマ区切りの後にスペースを追加する必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
659行目: 652行目:
</syntaxhighlight>
</syntaxhighlight>


Multi-line indexed arrays are fine, but pad each successive lines as above with an 4-space indent:
複数行のインデックス配列も問題ありませんが、次の各行も前述のように4つのスペースのインデントで埋め込みます:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
666行目: 659行目:
</syntaxhighlight>
</syntaxhighlight>


Note that the example above also can be written as follows:<br/>
上記の例は以下のように書くこともできます:<br/>
(with special attention to the last line having a trailing comma to extend the list of items later with a cleaner diff)
(後で項目のリストを拡張するためのクリーンな diff を作成するため、最後の行にカンマがあることに注意してください)


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
676行目: 669行目:
</syntaxhighlight>
</syntaxhighlight>


In any case, brackets and newlines need to be balanced, irrespectively of the number of elements per line.
いずれにしても、1行の要素数に関係なく、括弧と改行のバランスをとる必要があります。


===Associative arrays===
=== 連想配列 ===


Use multiple lines if this helps readability. For example:
可読性が向上する場合は、複数行に分割して使用してください。例:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
689行目: 682行目:
</syntaxhighlight>
</syntaxhighlight>


==Classes==
==クラス==
 
=== Class declarations ===


* Classes must be named according to Moodle's naming conventions.
=== クラス宣言 ===
* Classes must go under their respective "component/classes" dir to get the benefits of autoloading and [[Coding style#Namespaces|namespacing]]. There aren't such luxuries out from there.
* Each php file will contain only one class (or interface, or trait...). Unless it's part of old APIs where multi-artifact files were allowed.
* The brace should always be written on the line beside the class name.
* Every class must have a documentation block that conforms to the PHPDocumentor standard.
* All code in a class must be indented with 4 spaces.
* Placing additional code ("side-effects") in class files is only permitted to require artifacts not provided via autoloading (old classes or libs out from the "classes" directories and not loaded by Moodle's bootstrap). In those cases, the use of the [[Coding style#Require_.2F_include|MOODLE_INTERNAL check]] will be required.


: An example:
* クラスはMoodleの命名規則に従って命名する必要があります。
* クラスは、自動読み込みや[[コーディングスタイル (Dev docs)#名前空間|名前空間]]の利点を得るために、それぞれの "component/classes" ディレクトリの下に置かなければなりません。そこから先は、そんな贅沢なことはできません。
* 各PHPファイルには、クラス(またはインターフェース、トレイトなど)が1つだけ含まれます。ただし、複数のアーティファクトファイルが許可されていた古いAPIの一部である場合を除きます。
* ブレースは必ずクラス名の横の行に書いてください。
* すべてのクラスは、PHPDocumentor の標準に準拠したドキュメントブロックを持つ必要があります。
* クラス内のすべてのコードは、4つのスペースでインデントされなければなりません。
* クラスファイルに追加のコード("サイドエフェクト")を配置することは、自動読み込みで提供されないアーティファクト("classes" ディレクトリ以外から取得した古いクラスやライブラリで、Moodleのブートストラップによって読み込まれなかったもの)を必要とする場合にのみ許可されます。そのような場合には、[[コーディングスタイル (Dev docs)#Require_.2F_include|MOODLE_INTERNALチェック]]の使用が必要になります。
: 一例:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
714行目: 706行目:
  */
  */
class sample_class {
class sample_class {
     // All contents of class
     // クラスの全てのコンテンツは
     // must be indented 4 spaces.
     // スペース4つ分インデントされる必要があります。
}
}
</syntaxhighlight>
</syntaxhighlight>
Note the classes PHPDoc style is defined with more detail in the [[Coding style#Classes_3|Documentation and comments / Classes]] section in this document.
クラス PHPDoc スタイルは、このドキュメントの [[コーディングスタイル (Dev docs)#Classes_3|ドキュメントおよびコメント/クラス]] セクションでより詳しく定義されていることに注意してください。


===Class member variables===
===クラスのメンバ変数===


Member variables must be named according to Moodle's variable naming conventions.
メンバ変数は、Moodleの変数命名規則に従って命名する必要があります。


Any variables declared in a class must be listed at the top of the class, above the declaration of any methods.
クラスで宣言された変数は、クラスの先頭で、メソッドの宣言の上に記載しなければなりません。


The var construct is not permitted. Member variables always declare their visibility by using one of the '''private''', '''protected''', or '''public''' modifiers. Giving access to member variables directly by declaring them as public is permitted but discouraged in favor of accessor methods (set/get).
var構成は許可されていません。メンバ変数は常に、'''private''', '''protected''', '''public''' のいずれかの修飾子を使用して可視性を宣言します。メンバ変数を public として直接アクセスすることは許可されていますが、アクセサメソッド(set/get)を優先することが推奨されています。


==Functions and methods==
== 関数とメソッド ==
===Function and method declaration===
=== 関数とメソッドの宣言 ===


Functions must be named according to the Moodle function naming conventions.
関数は、Moodleの関数命名規則に従って名前を付ける必要があります。


Methods inside classes must always declare their visibility by using one of the private, protected, or public modifiers.
クラス内のメソッドは、常に private、protected、または public の修飾子を使用して可視性を宣言する必要があります。


As with classes, the brace should always be written on same line as the function name.
クラスと同様に、波括弧は常に関数名と同じ行に書く必要があります。


Don't leave spaces between the function name and the opening parenthesis for the arguments.
引数の開き括弧と関数名の間にスペースを入れてはいけません。


The return value must not be enclosed in parentheses. This can hinder readability, in additional to breaking code if a method is later changed to return by reference.
返り値は、括弧で囲まれていてはいけません。これは可読性を損なうだけでなく、後で参照による返り値に変更された場合にコードが壊れる可能性があります。


Return should only be one data type. It is discouraged to have multiple return types
返り値は1つのデータ型でなければなりません。複数の返り値型を持つことは推奨されません。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
/**
/**
  * Documentation Block Here
  * ここにドキュメンテーションブロックを記述します
  */
  */
class sample_class {
class sample_class {
      
      
     /**
     /**
     * Documentation Block Here
     * ここにドキュメンテーションブロックを記述します
     */
     */
     public function sample_function() {
     public function sample_function() {
         // All contents of function
         // 関数の中身はすべて
         // must be indented four spaces.
         // スペース4つ分インデントされる必要があります。
         return true;
         return true;
     }
     }
760行目: 752行目:
</syntaxhighlight>
</syntaxhighlight>


===Function and method usage===
=== 関数とメソッドの使用 ===


Function arguments should be separated by a single trailing space after the comma delimiter.
関数の引数は、コンマ区切りの後に1つのスペースを開けるようにしてください。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
768行目: 760行目:
</syntaxhighlight>
</syntaxhighlight>


===Magic methods===
=== マジックメソッド ===
Magic methods are heavily discouraged, justification will be required when used. Note: lazyness will not be a valid argument. 
マジックメソッドは強く非推奨であり、使用する際には正当性が必要です。注意: 怠惰さは正当な理由とはなりません。


(See MDL-52634 for discussion of rationale)
(背景についてはMDL-52634を参照してください)


==Control statements==
== 制御文 ==


In general, use white space liberally between lines and so on, to add clarity.
一般的に、行間などに十分なスペースを使って、明瞭さを追加するようにしてください。


===If / else===
===If/else文===


Put a space before and after the control statement in brackets, and separate the operators by spaces within the brackets.  Use inner brackets to improve logical grouping if it helps.
中括弧の制御文の前後にはスペースを入れ、中括弧内の演算子はスペースで区切ります。 論理的なグループ化を改善する場合は、内部の括弧を使用してください。


Indent with four spaces.
4つのスペースでインデントしてください。


''Don't use elseif!''
''elseif は使用しないでください!''


Always use braces (even if the block is one line and PHP doesn't require it). The opening brace of a block is always placed on the same line as its corresponding statement or declaration.
ブロックが1行であっても(PHPが必要としなくても)、常に中括弧を使用してください。ブロックの開始中括弧は、対応するステートメントまたは宣言と同じ行に配置されます。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
797行目: 789行目:
</syntaxhighlight>
</syntaxhighlight>


===Switch===
=== Switch文 ===


Put a space before and after the control statement in brackets, and separate the operators by spaces within the brackets.  Use inner brackets to improve logical grouping if it helps.
中括弧の制御文の前後にはスペースを入れ、中括弧内の演算子はスペースで区切ります。論理的なグループ化を改善する場合は、内部の括弧を使用してください。


Always indent with four spaces.  Content under each case statement should be indented a further four spaces.
常に4つのスペースでインデントしてください。各case文の下のコンテンツはさらに4つのスペースでインデントする必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
816行目: 808行目:
</syntaxhighlight>
</syntaxhighlight>


===Foreach===
=== Foreach文 ===


As above, uses spaces like this:
前述のように、次のようにスペースを使用します:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
826行目: 818行目:
</syntaxhighlight>
</syntaxhighlight>


===Ternary Operator===
===三項演算子===


The ternary operator is only permitted to be used for '''short''', '''simple to understand''' statements. If the statement can't be understood in one sentance, use an if statement instead.
三項演算子は、'''短く''', '''理解しやすい'''文に限定して使用することができます。文が一文で理解できない場合は、if文を代わりに使用してください。


Whitespace must be used around the operators to make it clear where the operation is taking place.
演算子の周りに空白を使用して、操作がどこで実行されているかを明確にする必要があります。


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$username = isset($user->username) ? $user->username : ''; **
$username = isset($user->username) ? $user->username : ''; **
838行目: 830行目:
</syntaxhighlight>
</syntaxhighlight>


BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$toload = (empty($CFG->navshowallcourses))?self::LOAD_ROOT_CATEGORIES:self::LOAD_ALL_CATEGORIES;
$toload = (empty($CFG->navshowallcourses))?self::LOAD_ROOT_CATEGORIES:self::LOAD_ALL_CATEGORIES;
844行目: 836行目:
</syntaxhighlight>
</syntaxhighlight>


<nowiki>**</nowiki> Note that, since PHP 7.0, many of those "isset()" ternaries can be changed to use the new shorthand [https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op null coalescing operator] so, the above is equivalent to:
<nowiki>**</nowiki> 注意:PHP 7.0以降、多くの "isset()" 三項演算子は、新しい省略記法 [https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op null coalescing operator] を使用するように変更できます。つまり、上記は以下と同じです。
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
$username = $user->username ?? '';
$username = $user->username ?? '';
851行目: 843行目:
==Require / include==
==Require / include==


Each file that is accessed via browser should start by including the main config.php file.
ブラウザ経由でアクセスされる各ファイルは、まずメインのconfig.phpファイルをインクルードすることから始める必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
857行目: 849行目:
</syntaxhighlight>
</syntaxhighlight>


Any other include/require should use a path starting with <tt>__DIR__</tt> or an absolute path starting with <tt>$CFG->dirroot</tt> or <tt>$CFG->libdir</tt>. Relative includes starting with "../" can [https://www.php.net/manual/en/function.include.php sometimes behave strangely under PHP], so should not be used. Our [[CLI scripts]] must not use relative config.php paths starting with "../".
その他のinclude/requireは、<tt>__DIR__</tt>で始まるパスまたは<tt>$CFG->dirroot</tt>または<tt>$CFG->libdir</tt>で始まる絶対パスを使用する必要があります。"../" で始まる相対的なインクルードは、[https://www.php.net/manual/en/function.include.php PHPでは時々奇妙な動作をする]ため、使用しないでください。[[CLIスクリプト (Dev docs)|CLIスクリプト]]では、"../" で始まる相対的なconfig.phpパスを使用しないでください。


For library files in normal usage, require_once should be used (this is different from config.php which should always use 'require' as above). Examples:
一般的な使用において、ライブラリファイルについては、require_onceを使用する必要があります(これは常に上記のように'require'を使用する必要があるconfig.phpとは異なります)。例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
require_once(__DIR__ . '/locallib.php');
require_once(__DIR__ . '/locallib.php');
865行目: 857行目:
</syntaxhighlight>
</syntaxhighlight>


Includes should generally only be done at the top of files or inside functions/methods that need them. Using include/require in the middle of a file in global scope very hard to audit the security of the code.
インクルードは、通常はファイルの先頭または必要な場合にのみ、関数/メソッドの内部で行うべきです。ファイルの途中でinclude/requireを使用すると、グローバルスコープでのセキュリティの監査が非常に困難になります。


All other scripts with the exception of imported 3rd party libraries and files without ''side-effects*'' (i.e. single class definitions, interfaces or traits), should use following code at the very top to prevent direct execution which might reveal error messages on misconfigured production servers.
他のすべてのスクリプトにおいて、インポートされたサードパーティのライブラリおよび ''side-effects*''(つまり、単一のクラス定義、インターフェイス、またはトレイト)のないファイルを除き、誤って設定された本番サーバでエラーメッセージを公開する可能性がある直接実行を防止するために、以下のコードをファイルの先頭で使用する必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
873行目: 865行目:
</syntaxhighlight>
</syntaxhighlight>


<nowiki>*</nowiki>''side-effects'': Any global scope code not being: a) namespace and use statements or b) namespace constants or c) strict_types declarations (declarations in general).
<nowiki>*</nowiki>''side-effects'': a) 名前空間と使用文 b) 名前空間定数 c) strict_types宣言(宣言全般)以外のグローバルスコープコード。


Please note that the existence or absence of side-effects in a file only affects as explained above, at code level. It shouldn't be considered in other parts of the coding style unless specifically mentioned.
ファイル内に副作用があるかどうかの存在または不在は、コードレベルで上記のように説明されるようにのみ影響します。特に言及されない限り、コーディングスタイルの他の部分では考慮すべきではありません。


==Documentation and comments==
== ドキュメンテーションとコメント ==


Code documentation explains the code flow and the purpose of functions and variables.  Use it whenever practical.
コードのドキュメンテーションは、関数や変数の目的やコードのフローを説明します。実用的な場合には、必ず使用してください。


===PHPDoc===
=== PHPDoc ===


Moodle stays as close as possible to "standard" [https://www.phpdoc.org/ PHPDoc format] to document our files, classes and functions.  This helps IDEs (like Netbeans or Eclipse) work properly for Moodle developers, and also allows us to generate web documentation automatically.
Moodleは、ファイル、クラス、および関数を文書化するために、できるだけ「標準的な」[https://www.phpdoc.org/ PHPDocフォーマット]に従います。これにより、Moodle開発者がNetbeansやEclipseのようなIDEを適切に使用できるようになり、Webドキュメンテーションを自動的に生成することもできます。


PHPDoc has a number of tags that can be used in different places (files, classes and functions).  We have some particular rules for using them in Moodle that you must follow:
PHPDocには、異なる場所(ファイル、クラス、関数)で使用できるいくつかのタグがあります。Moodleでは、それらを使用するためのいくつかの特別なルールがあり、それに従う必要があります。


====Types====
==== ====


Some of the tags below (@param, @return...) do require the specification of a valid php type and a description. All these are allowed:
以下のタグ (@param, @return...) のいくつかは、有効なPHPの型とその説明を指定する必要があります。以下のものが許可されています:


* PHP primitive types: int, bool, string...
* PHPのプリミティブ型:int、bool、stringなど
* PHP complex types: array, stdClass (not Array, object).
* PHPの複雑な型:array、stdClass (Array、objectではない)
* PHP classes:full or relative (to current namespace) class names.
* PHPのクラス:完全な名前または相対的な(現在の名前空間に対する)クラス名
* true, false, null (always lowercase).
* true、false、null (常に小文字)
* static: for methods returning a new instance of the child/caller class.
* static: 子クラス/呼び出し側のクラスの新しいインスタンスを返すメソッドに使用します。
* self: for methods returning a new instance of the parent/called class.
* self: 親クラス/呼び出されたクラスの新しいインスタンスを返すメソッドに使用します。
* $this: for methods returning the current instance of the class.
* $this: クラスの現在のインスタンスを返すメソッドに使用します。
* void: for methods with a explicit empty "return" statement.
* void: 明示的に空の "return" ステートメントを持つメソッドに使用します。


Also, there are some basic rules about how to use those types:
また、これらの型を使用する際には、いくつかの基本的なルールがあります:
* We use [https://www.php.net/manual/en/language.types.type-juggling.php short type names] (bool instead of boolean, int instead of integer).
* [https://www.php.net/manual/en/language.types.type-juggling.php 短い型名]を使用します (booleanではなくbool、integerではなくintなど)
* With cases represented as array of given type, it's highly recommended to document them as type[] instead of the simpler and less informative "array" alternative (e.g. <tt>int[]</tt> or <tt>stdClass[]</tt>).
* 特定の型の配列として表現される場合、より簡単で情報量の少ない "array" の代わりにtype[]として文書化することを強くお勧めします (例:<tt>int[]</tt>または<tt>stdClass[]</tt>など)
* When multiple different types are possible, they must be separated by a vertical bar (pipe) (e.g. <tt>@return int|false</tt>).
* 複数の異なる型が可能な場合、縦棒 (パイプ) で区切る必要があります (例:<tt>@return int|false</tt>など)
* All primitives and keywords must be lowercase. The case of the complex types and classes must match the original.
* すべてのプリミティブおよびキーワードは小文字で記述します。複雑な型とクラスの場合は、元のものと同じ大文字と小文字を使用します。


====Tags====
====タグ====


===== @copyright =====
===== @copyright =====


These include the year and copyright holder (creator) of the original file.  Do not change these in existing files!
これらには、オリジナルファイルの作成者である年と著作権保有者が含まれます。既存のファイルではこれらを変更しないでください!


   @copyright 2008 Kim Bloggs
   @copyright 2008 Kim Bloggs
916行目: 908行目:
===== @license =====
===== @license =====


These must be GPL v3+ and use this format:
これらは GPL v3+ を使用し、以下の形式を使用する必要があります:


   @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
   @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 以降


===== @param =====
===== @param =====


Don't put hyphens or anything fancy after the variable name, just a space.
変数名の後ろにハイフンや何か特別な文字を入れないでください。スペースだけを使用してください。


   @param [[#Types|type]] $name Description.
   @param [[#|type]] $name 説明。


===== @return =====
===== @return =====


The @return tag is mandatory if the function has a return statement, but can be left out if it does not have one.
関数に戻り値がある場合は、@returnタグは必須ですが、戻り値がない場合は省略できます。


The description portion is optional, it can be left out if the function is simple and already describes what is returned.
説明部分はオプションです。関数がシンプルで戻り値について説明されている場合は、省略することができます。


   @return [[#Types|type]] Description.
   @return [[#|type]] 説明。


===== @var =====
===== @var =====


The @var tag is used to document class properties.
@varタグは、クラスのプロパティをドキュメント化するために使用されます。


   @var [[#Types|type]] Description.
   @var [[#|type]] 説明。


Exceptionally, when none of the available [[#Types|types]] define the returned value, inline @var phpdocs (within the body of the methods) providing type hinting are allowed to the returned type. Don't abuse!
例外的に、利用可能な[[#|types]]のいずれも返された値を定義しない場合、メソッドの本文内で型ヒントを提供するインライン@var phpdocsを返された型に許可されています。濫用しないでください!


===== @uses =====
===== @uses =====


If a function uses die or exit, please add this tag to the docblock to help developers know this function could terminate the page:
関数がdieまたはexitを使用する場合は、このタグをドックブロックに追加して、開発者がこの関数がページを終了できることを知るのに役立ててください。


   @uses exit
   @uses exit
950行目: 942行目:
===== @access =====
===== @access =====


The access can be used to specify access control for an element
アクセスは、要素のアクセス制御を指定するために使用できます。


# Should only be used when the method definition does not already specify access control.
# メソッド定義が既にアクセス制御を指定していない場合にのみ使用する必要があります。
# In the case of functions, specifying public access is redundant and so should be avoided.
# 関数の場合、publicアクセスを指定することは冗長であるため、避けるべきです。


   @access private
   @access private
959行目: 951行目:
===== @package =====
===== @package =====


The package tag should always be used to label php files with the correct [[Frankenstyle]] component name.  Full rules are explained on that page, but in summary:
@packageタグは、正しい[[Frankenstyle (Dev docs)|Frankenstyle]]コンポーネント名でphpファイルにラベルを付けるために常に使用する必要があります。詳細なルールはそのページで説明されていますが、要約すると次のとおりです。


# If the file is part of any component plugin, then use the plugin component name (eg '''mod_quiz''' or '''gradereport_xls''')
# ファイルが任意のコンポーネントプラグインの一部である場合は、プラグインコンポーネント名(例:'''mod_quiz''' または '''gradereport_xls''' )を使用します。
# If the file is part of a core subsystem then it will be core_xxxx where xxxx is the name defined in get_core_subsystems().  (eg '''core_enrol''' or '''core_group''')
# ファイルがコアサブシステムの一部である場合、get_core_subsystems()で定義された名前がxxxxであることになります(たとえば、'''core_enrol''' または '''core_group''' )。
# If the file is one of the select few files in core that are not part of a subsystem (such as lib/moodlelib.php) then it just as a package of '''core'''.
# サブシステムの一部でないコアの選択された数少ないファイル(lib/moodlelib.phpなど)の場合は、単に '''core''' というパッケージとして存在します。
# Each file can only be part of ONE package.
# 各ファイルは1つのパッケージのみに属することができます。


(We do not have standards for @subpackage at all.  You can use within your @package how you like.)
@subpackageにはまったく標準がありません。@package内で好きなように使用できます。)


   @package gradereport_xls
   @package gradereport_xls
972行目: 964行目:
===== @category =====
===== @category =====


We use @category only to highlight the public classes, functions or files that are part of one of our [[Core APIs]], or that provide good example implementations of a Core API.  The value must be one of the ones on the [[Core APIs]] page. 
私たちは、@categoryを使用して、[[コアAPI (Dev docs)|コアAPI]]の一部であるパブリッククラス、関数、またはファイル、あるいはコアAPIの良い例の実装を示すためにのみ使用します。値は、[[コアAPI (Dev docs)|コアAPI]]ページのいずれかの値である必要があります。


   @category preferences  
   @category preferences


===== @since =====
===== @since =====


When adding a new classes or function to the Moodle core libraries (or adding a new method to an existing class), use a @since tag to document which version of Moodle it was added in. For example:
Moodleのコアライブラリに新しいクラスや関数を追加する場合(または既存のクラスに新しいメソッドを追加する場合)、@sinceタグを使用して、その追加されたMoodleのバージョンを文書化します。例:
 
   @since Moodle 2.1
   @since Moodle 2.1


===== @see =====
===== @see =====


If you want to refer the user to another related element (include, class, function, define, method, variable), but not to URLs, then you can use @see.
関連する別の要素(include、class、function、define、method、variable)をユーザに参照させたい場合は、URLではなく@seeタグを使用することができます。
 
  @see some_other_function()
@see some_other_function()


This tag can be used inline too, within phpdoc comments.
このタグは、phpdocコメント内でもインラインで使用できます。


   /**
   /**
     * This function uses {@see get_string()} to obtain the currency names...
     * この関数は{@see get_string()}を使用して通貨名を取得します...
     * .....
     * .....


===== @link =====
===== @link =====


If you want to refer the user to an external URL, but not to related elements, use @link.
外部のURLにユーザを参照させたい場合は、関連要素ではなく@linkを使用します。


   @link https://docs.moodle.org/dev/Core_APIs
   @link https://docs.moodle.org/dev/Core_APIs


This tag can be used inline too, within phpdoc comments.
このタグは、phpdocコメント内でもインラインで使用できます。


   /**
   /**
     * For details about the implementation below, visit {@link https://docs.moodle.org/dev/Core_APIs} and read...
     * 下記の実装の詳細については、{@link https://docs.moodle.org/dev/Core_APIs} にアクセスし、読んでください...
     * .....
     * .....


===== @deprecated (and @todo) =====
===== @deprecated (および@todo) =====


When deprecating an old API, use a @deprecated tag to document which version of Moodle it was deprecated in, and add @todo and @see if possible.  Make sure to mention relevant MDL issues.  For example:
古いAPIを廃止する場合は、@deprecatedタグを使用して、どのバージョンのMoodleで廃止されたかを文書化し、できる限り@todoと@seeを追加してください。関連するMDLの問題を必ず記載してください。例えば:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
1,019行目: 1,011行目:
</syntaxhighlight>
</syntaxhighlight>


If it is important that developers update their code, consider also adding a debugging('...', DEBUG_DEVELOPER); call to repeat the deprecated message. If the old function can no longer be supported at all, you may have to throw a coding_exception. There are examples of the various options in lib/deprecatedlib.php.
開発者がコードを更新する必要がある場合は、デバッグメッセージを繰り返して表示するために、debugging('...', DEBUG_DEVELOPER);呼び出しを追加することも検討してください。古い関数を全くサポートできなくなった場合は、coding_exceptionをスローする必要がある場合もあります。各種オプションの例については、lib/deprecatedlib.phpを参照してください。


===== @throws =====
===== @throws =====


This tag is valid and can be used optionally to indicate the method or function will throw and exception. This is to help developers know they may have to handle the exceptions from such functions.
このタグは有効であり、オプションで使用することができます。メソッドまたは関数が例外をスローすることを示すために使用されます。これにより、開発者がそのような関数からの例外を処理する必要があることを知ることができます。


===== Other specific tags =====
===== その他の特定のタグ =====


There are some tags that are only allowed within some contexts and not globally. More precisely:
グローバルではなく、特定の文脈でのみ許可されているタグがあります。より具体的には、以下のようになります:


* @Given, @When, @Then, within the [[Acceptance testing#Adding steps definitions|behat steps definitions]].
* @Given、@When、@Thenは、[[受け入れテスト (Dev docs)#ステップ定義の追加|behatステップ定義]]内でのみ使用できます。
* @covers, @coversDefaultClass, @coversNothing, @uses to better control coverage within [[Writing PHPUnit tests#Generators|unit tests]].
* @covers、@coversDefaultClass、@coversNothing、@usesは、[[PHPUnitテストの書き方 (Dev docs)#ジェネレータ|ユニットテスト]]内でカバレッジをより細かく制御するために使用します。
* @dataProvider and @testWith, to provide example data and expectations, within [[Writing PHPUnit tests#Generators|unit tests]].
* @dataProviderと@testWithは、[[PHPUnitテストの書き方 (Dev docs)#ジェネレータ|ユニットテスト]]内で、例と期待値を提供するために使用されます。
* @depends, to express dependencies between tests, where each producer returned data in passed to consumers. See [https://phpunit.readthedocs.io/en/9.5/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-stacktest2-php @depends examples] for more information.
* @dependsは、テスト間の依存関係を表現するために使用されます。各プロデューサが返したデータがコンシューマに渡されます。詳細については、[https://phpunit.readthedocs.io/en/9.5/writing-tests-for-phpunit.html#writing-tests-for-phpunit-examples-stacktest2-php @depends examples] を参照してください。
* @group, for easier collecting unit tests together, following the guidelines in the [[PHPUnit#Using_the_.40group_annotation|PHPUnit MoodleDocs]].
* @groupは、[[PHPUnit (Dev docs)#Using_the_.40group_annotation|PHPUnit MoodleDocs]]のガイドラインに従い、ユニットテストを簡単にグループ化するために使用されます。
* @requires, to specify unit test requirements and skip if not fulfilled. See [https://phpunit.readthedocs.io/en/9.5/incomplete-and-skipped-tests.html#incomplete-and-skipped-tests-requires-tables-api @requires usages] for more information.
* @requiresは、ユニットテストの要件を指定し、満たされない場合はスキップします。詳細については、[https://phpunit.readthedocs.io/en/9.5/incomplete-and-skipped-tests.html#incomplete-and-skipped-tests-requires-tables-api @requires usages] を参照してください。
* @runTestsInSeparateProcesses and @runInSeparateProcess, to execute an individual test or a testcase in isolation. To be used only when strictly needed.
* @runTestsInSeparateProcessesと@runInSeparateProcessは、個々のテストまたはテストケースを独立して実行するために使用されます。厳密に必要な場合にのみ使用してください。


===Files===
=== ファイル ===


All files that contain PHP code should contain, without any blank line after the php open tag, a full GPL copyright statement at the top, plus a SEPARATE docblock right under it containing a:
PHPコードを含むすべてのファイルは、PHPオープンタグの後に空行を挿入せず、トップに完全なGPL著作権声明を含める必要があります。その下には、以下の情報を含む別個のドックブロックが必要です:


# short one-line description of the file
# ファイルの簡単な一行の説明
# longer description of the file
# ファイルの詳細な説明
# @package tag (required)
# @packageタグ (必須)
# @category tag (only when everything in the file is related to one of the [[Core APIs]])
# @categoryタグ (ファイル内のすべてが[[コアAPI (Dev docs)|コアAPI]]の関連である場合にのみ必要)
# @copyright (required)
# @copyright (必須)
# @license (required)
# @license (必須)


For files containing only one artifact, the file phpdc block is optional as long as the artifact (class, interface, trait...) is documented. Read the following "Classes" section about that case.
1つのアーティファクトだけを含むファイルの場合、そのアーティファクト(クラス、インターフェース、トレイトなど)が文書化されている限り、ファイルのphpdocブロックはオプションです。この場合については、以下の "クラス" のセクションを読んでください。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
<?php
<?php
// This file is part of Moodle - https://moodle.org/
// このファイルはMoodleの一部です - https://moodle.org/
//
//
// Moodle is free software: you can redistribute it and/or modify
// Moodleはフリーソフトウェアであり、あなたはそれを再配布したり、
// it under the terms of the GNU General Public License as published by
// 改変することができます。
// the Free Software Foundation, either version 3 of the License, or
// これはGNU General Public Licenseに従って公開されています。
// (at your option) any later version.
// ライセンスのバージョンは、バージョン3、あるいは
// (あなたの選択により)それ以降のバージョンを使用することができます。
//
//
// Moodle is distributed in the hope that it will be useful,
// Moodleは、役に立つことを願って配布されていますが、
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// すべての保証を含めて、明示的にも黙示的にも何の保証もありません。
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// 詳細については、GNU General Public Licenseを参照してください。
// GNU General Public License for more details.
//
//
// You should have received a copy of the GNU General Public License
// あなたは、Moodleと共にGNU General Public Licenseのコピーを受け取るはずです。
// along with Moodle.  If not, see <https://www.gnu.org/licenses/>.
// もし受け取っていなければ、<https://www.gnu.org/licenses/>を参照してください。


/**
/**
  * This is a one-line short description of the file.
  * これはファイルの簡単な一行の説明です。
  *
  *
  * You can have a rather longer description of the file as well,
  * あなたはファイルのかなり長い説明も持つことができ、
  * if you like, and it can span multiple lines.
  * 複数の行にまたがることもできます。
  *
  *
  * @package    mod_mymodule
  * @package    mod_mymodule
  * @category  backup
  * @category  backup
  * @copyright  2008 Kim Bloggs
  * @copyright  2008 Kim Bloggs
  * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3またはそれ以降
  */
  */
</syntaxhighlight>
</syntaxhighlight>


===Classes===
===クラス===


All classes must have a complete docblock like this:
すべてのクラスは以下のような完全なドックブロックを持つ必要があります。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
/**
/**
  * Short description for class.
  * クラスの短い説明。
  *
  *
  * Long description for class (if any)...
  * クラスの長い説明 (ある場合)
  *
  *
  * @package    mod_mymodule
  * @package    mod_mymodule
  * @category  backup
  * @category  backup
  * @copyright  2008 Kim Bloggs
  * @copyright  2008 Kim Bloggs
  * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3 またはそれ以降のバージョン
  */
  */
class policy_issue {
class policy_issue {
</syntaxhighlight>
</syntaxhighlight>


For files containing only one artifact (class, interface, trait...), specifically for all the files within <tt>classes</tt> directories, but also any other file fulfilling the condition anywhere else, it will be enough with the class phpdoc block. The file phpdoc block will be considered optional at all effects, giving to the class one precedence.
1つのアーティファクト (クラス、インターフェース、トレイトなど) のみを含むファイルについて、特に <tt>classes</tt> ディレクトリ内のすべてのファイル、および他の場所にある条件を満たす任意のファイルについては、クラスの phpdoc ブロックだけで十分です。ファイルの phpdoc ブロックは、クラスに優先度を与えるため、すべての効果においてオプションと見なされます。


The [[#@package|@package]], [[#@copyright|@copyright]] and [[#@license|@license]] tags (and the optional [[#@category|@category]] tag ), as shown in the example above, must be present always in the file (in whichever docblock, but all together).
上記の例に示されるように、[[#@package|@package]][[#@copyright|@copyright]][[#@license|@license]] タグ(およびオプションの [[#@category|@category]] タグ)は、常にファイルに存在する必要があります(どのドックブロックにあっても、すべて一緒に)。


===Properties===
===プロパティ===


All properties should have a docblock with the following minimum information:
すべてのプロパティには、次の最小情報を持つドックブロックが必要です。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
class example {
class example {
     /** @var string This variable does something */
     /** @var string この変数は何かを行います */
     protected $something;
     protected $something;
}
}
</syntaxhighlight>
</syntaxhighlight>
or
または
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
class example {
class example {
     /**  
     /**
     * This variable does something and has a very long description which can
     * この変数は何かを行い、複数行にまたがる非常に長い説明があります
    * wrap on multiple lines
     * @var string  
     * @var string  
     */
     */
1,123行目: 1,114行目:
}
}
</syntaxhighlight>
</syntaxhighlight>
Even if there are several properties all sharing something in common, do not use [https://en.wikipedia.org/wiki/PHPDoc#DocBlock_Templates DocBlock templates]. Instead, document every property explicitly as in the following example:
 
[https://en.wikipedia.org/wiki/PHPDoc#DocBlock_Templates DocBlockテンプレート]を使用しないでください。代わりに、次の例のように、すべてのプロパティを明示的に文書化してください。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
class zebra {
class zebra {
     /** @var int The number of white stripes */
     /** @var int 白いストライプの数 */
     protected $whitestripes = 0;
     protected $whitestripes = 0;


     /** @var int The number of black stripes */
     /** @var int 黒いストライプの数 */
     protected $blackstripes = 0;
     protected $blackstripes = 0;


     /** @var int The number of red stripes */
     /** @var int 赤いストライプの数 */
     protected $redstripes = 0;
     protected $redstripes = 0;
}
}
</syntaxhighlight>
</syntaxhighlight>


===Constants===
===定数===


Class constants should be documented in the following way:
クラス定数は、次の方法で文書化する必要があります:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
class sam {
class sam {
   /**
   /**
     * This is used when Sam is in a good mood.
     * Samが良い気分のときに使用されます。
     */
     */
   const MOOD_GOOD = 0;
   const MOOD_GOOD = 0;
1,151行目: 1,143行目:
</syntaxhighlight>
</syntaxhighlight>


===関数===


===Functions===
すべての関数とメソッドには、次のように完全なドックブロックが必要です。
 
All functions and methods should have a complete docblock like this:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
/**
/**
  * The description should be first, with asterisks laid out exactly
  * 説明は最初に記述し、この例のようにアスタリスクを正確に並べます。
  * like this example. If you want to refer to a another function,
  * 別の関数を参照する場合は、以下のように@seeを使用してください。
* use @see as below.  If it's useful to link to Moodle
  * MoodleのWeb上のドキュメントへのリンクが役立つ場合は、以下のように@linkを使用するか、
  * documentation on the web, you can use a @link below or also
  * またはインラインで{@link https://docs.moodle.org/dev/something}のように使用できます。
  * inline like this {@link https://docs.moodle.org/dev/something}
  * その後、各パラメータと戻り値について次のように説明を追加します。
  * Then, add descriptions for each parameter and the return value as follows.
  *
  *
  * @see clean_param()
  * @see clean_param()
  * @param int  $postid The PHP type is followed by the variable name
  * @param int  $postid PHPのタイプに続いて変数名を記述します
  * @param array $scale The PHP type is followed by the variable name
  * @param array $scale PHPのタイプに続いて変数名を記述します
  * @param array $ratings The PHP type is followed by the variable name
  * @param array $ratings PHPのタイプに続いて変数名を記述します
  * @return bool A status indicating success or failure
  * @return bool 成功または失敗を示すステータス
  */
  */
</syntaxhighlight>
</syntaxhighlight>


You must include a description even if it appears to be obvious from the @param and/or @return lines.
@paramおよび/または@return行から明らかであると思われる場合でも、説明を含める必要があります。


An exception is made for overridden methods which make no change to the meaning of the parent method and maintain the same arguments/return values. In this case you should omit the comment completely. Use of the @inheritdoc or @see tags is explicitly forbidden as a replacement for any complete docblock.
親メソッドの意味を変更せず、同じ引数/戻り値を維持するオーバーライドされたメソッドについては、この場合はコメントを完全に省略する必要があります。@inheritdocまたは@seeタグの使用は、完全なドックブロックの代わりに明示的に禁止されています。


===Defines===
===定義===


All defines should be documented in the following way:
すべての定義は、以下の方法でドキュメント化する必要があります:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
/**
/**
  * PARAM_INT - integers only, use when expecting only numbers.
  * PARAM_INT - 整数のみ、数字のみを想定する場合に使用します。
  */
  */
define('PARAM_INT', 'int');
define('PARAM_INT', 'int');
/**


/**
PARAM_ALPHANUM - 数字と文字のみを想定します。
* PARAM_ALPHANUM - expected numbers and letters only.
*/
*/
define('PARAM_ALPHANUM', 'alphanum');
define('PARAM_ALPHANUM', 'alphanum');
</syntaxhighlight>
</syntaxhighlight>


===Inline comments===
===インラインコメント===


Inline comments must use the "// " (2 slashes + whitespace) style, laid out neatly so that it fits among the code and lines up with it. The first line of the comment must begin with a capital letter (or a digit, or '...') and the comment must end with a proper punctuation character. Permitted final characters are '.', '?' or '!'.
インラインコメントは、"// "(2つのスラッシュ+空白)スタイルを使用する必要があります。そのコメントがコードに収まり、整然と並ぶように配置します。コメントの最初の行は大文字で始まり(または数字、または '...')、適切な句読点文字で終わる必要があります。許可される最後の文字は、'.''?''!'のいずれかです。


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
1,201行目: 1,191行目:
     if (!$ratings) {
     if (!$ratings) {


         $ratings = [];    // Initialize the empty array.
         $ratings = [];    // 空の配列を初期化します。


         $rates = $DB->get_records('forum_ratings', ['post' => $postid)];
         $rates = $DB->get_records('forum_ratings', ['post' => $postid)];


         // ... then process each rating in
         // ... そして、それぞれの評価を処理します。
        // turn.
         foreach ($rates as $rate) {
         foreach ($rates as $rate) {
             do_something_with($rate);
             do_something_with($rate);
         }
         }


         // Do we need to tidy up?
         // 片付けが必要か?
         if (!empty($rates))
         if (!empty($rates))
             // 42 more things happen here!
             ここで42の別の処理が行われます!
             finsh_up();
             finsh_up();
         }
         }
</syntaxhighlight>
</syntaxhighlight>


GOOD:
良い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
// Comment explaining this piece of code.
// このコードの説明をするコメント。
</syntaxhighlight>
</syntaxhighlight>
BAD:
悪い例:
<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
/* Comment explaining this piece of code. */
/* このコードの説明をするコメント。*/
# Comment explaining this piece of code.
# このコードの説明をするコメント。
// comment explaining this piece of code (without capital letter and punctuation)
// このコードの説明をするコメント(大文字と句読点なし)。
</syntaxhighlight>
</syntaxhighlight>




If your comment is due to some MDL issue, please feel free to include the correct MDL-12345 in your comment.  This makes it easier to track down decisions and discussions about things.
もしコメントがMDLの問題に関連している場合は、適切なMDL-12345をコメントに含めてください。これにより、決定や議論を追跡することがより簡単になります。


====Using TODO====
==== TODOを使用する ====


This is especially important if you know an issue still exists in that code that should be dealt with later.  Use a TODO along with a MDL code to mark this.  For example:
特に、後で取り組む必要のある問題がまだそのコードに存在することを知っている場合には、TODOとMDLコードを使用してそれをマークすることが重要です。例えば:


<syntaxhighlight lang="php">
<syntaxhighlight lang="php">
// TODO MDL-12345 This works but is a bit of a hack and should be revised in future.
// TODO MDL-12345 これは機能するが、ややハック的であり、将来的に改訂する必要がある。
</syntaxhighlight>
</syntaxhighlight>


If you have a big task that is nearly done, apart a few TODOs, and you really want to mark the big task as finished, then you should file new tracker tasks for each TODO and change the TODOs comments to point at the new issue numbers.
ほとんど完了している大きなタスクがあり、いくつかのTODOが残っている場合は、大きなタスクを完了したとマークしたい場合は、各TODOのために新しいトラッカータスクを作成し、TODOのコメントを新しい問題番号に指し示すように変更する必要があります。


There is a nice "todo checker" reporting tool, restricted to admins and available via web @ [https://github.com/moodle/moodle/blob/master/lib/tests/other/todochecker.php lib/tests/other/todochecker.php].
"TODO チェック" を行う便利なレポートツールがあります。管理者専用で、ウェブ経由で [https://github.com/moodle/moodle/blob/master/lib/tests/other/todochecker.php lib/tests/other/todochecker.php] で利用できます。


Finally, don't forget to add any MDL-l2345 used by your TODOs (and @todos too, unless part of the [[Deprecation|deprecation process]], those are handled apart) to the "Review TODOs Epic" : MDL-47779 (requires login to see the issues)
最後に、あなたのTODO(また、@todosも、[[非推奨 (Dev docs)|非推奨プロセス]]の一部でない限り、それらは別に扱われます)で使われているMDL-l2345を "Review TODOs Epic" に加えることを忘れないでください : MDL-47779 (問題を見るにはログインが必要です)


===CVS keywords===
===CVS キーワード===


We have stopped using CVS keywords such as $Id$ in Moodle 2.0 completely.
Moodle 2.0 からは、$Id$ のような CVS キーワードの使用を完全に停止しています。


==Exceptions==
== 例外処理 ==


Use exceptions to report errors, especially in library code.
エラーの報告には、特にライブラリコードにおいて、例外を使用してください。


Throwing an exception has almost exactly the same effect as calling print_error(), but it is more flexible. For example, the caller can choose to catch the exception and handle it in some way. It also makes it easier to write unit tests.
例外を投げることは、print_error() を呼び出すこととほぼ同じ効果がありますが、より柔軟性があります。例えば、呼び出し元は例外をキャッチして、何らかの方法で処理することができます。また、ユニットテストを書くこともより簡単になります。


Note that, since 2021, it has been [https://tracker.moodle.org/browse/MDL-69936 agreed to deprecate print_error()] and, instead, to throw moodle_exception() is the correct way to proceed.
2021年以降、print_error() を廃止し、代わりに moodle_exception() をスローすることが合意されたため、注意してください。


Any exception that is not caught will trigger an appropriate call to print_error, to report the problem to the user. Exceptions "error codes" will be translated only when they are meant to be shown to final users.
キャッチされていない例外は、問題をユーザに報告するために適切な print_error の呼び出しをトリガーします。"エラーコード" として表される例外は、最終的なユーザに表示するために翻訳されます。


Do not abuse exceptions for normal code flow. Exceptions should only be used in erroneous situations.
通常のコードフローに例外を乱用しないでください。例外は、異常な状況でのみ使用する必要があります。


===Exception classes===
===例外クラス===


We have a set of custom exception classes. The base class is moodle_exception. You will see that the arguments you pass to new moodle_exception(...) are very similar to the ones you would pass to print_error. There are more specific subclasses for particular types of error.
カスタム例外クラスのセットを持っています。ベースクラスはmoodle_exceptionです。new moodle_exception(...)に渡す引数は、print_errorに渡す引数と非常に似ていることに気づくでしょう。特定の種類のエラーに対してより具体的なサブクラスがあります。


To get the full list of exception types, search for the regular expression 'class +\w+_exception +extends' or ask your IDE to list all the subclasses of moodle_exception.
例外タイプの完全なリストを取得するには、 'class +\w+_exception +extends'という正規表現を検索するか、あなたのIDEにmoodle_exceptionのすべてのサブクラスをリストアップするように依頼してください。


Where appropriate, you should create new subclasses of moodle_exception for use in your code.
適切な場合は、自分のコードで使用するためにmoodle_exceptionの新しいサブクラスを作成する必要があります。


A few notable exception types:
いくつかの注目すべき例外タイプ:
; moodle_exception : base class for exceptions in Moodle. Use this when a more specific type is not appropriate.
; moodle_exception : Moodleの例外の基本クラス。より特定のタイプが適切でない場合に使用します。
; coding_exception : thrown when the problem seems to be caused by a developer's mistake. Often thrown by core code that interacts with plugins. If you throw an exception of this type, try to make the error message helpful to the plugin author, so they know how to fix their code.
; coding_exception : 開発者のミスが原因と思われる場合にスローされます。プラグインとやり取りするコアコードによって頻繁にスローされます。このタイプの例外をスローする場合は、エラーメッセージがプラグインの作者に役立つようにし、彼らが自分のコードを修正する方法を知ることができるようにしてください。
; dml_exception (and subclasses) : thrown when a database query fails.
; dml_exception (およびサブクラス) : データベースクエリが失敗したときにスローされます。
; file_exception : thrown by the File API.
; file_exception : File APIによってスローされます。


==Dangerous functions and constructs==
==危険な関数や構造体==
PHP includes multiple questionable features that are highly discouraged because they are very often source of serious security problems.
PHPには、深刻なセキュリティ問題の原因となることが非常に多いとされている、問題のある機能が複数含まれています。


# do not use ''eval()'' function - language packs are exception (to be solved in future).
# ''eval()'' 関数を使用しないでください。ただし、言語パックに関しては(将来的に解決されることを前提に)例外です。
# do not use ''preg_replace()'' with /e modifier - use callbacks in order to prevent unintended PHP execution.
# ''preg_replace()'' 関数を /e 修飾子とともに使用しないでください。PHPの予期しない実行を防止するために、コールバックを使用してください。
# do not use backticks for shell command execution.
# バッククォートを使用してシェルコマンドを実行しないでください。
# do not use ''goto'', neither the operator neither labels - use other programming techniques to control the execution flow.
# ''goto'' 文、演算子、またはラベルを使用しないでください。代わりに他のプログラミング技法を使用して実行フローを制御してください。


==Policy about coding-style only fixes==
==コーディングスタイルの修正についての方針==


Way before this coding-style guide was defined and agreed, a lot of code had been written already. Obviously such code does not follow the coding-style at all. While '''we enforce conformance for all the new code''', we are not paranoid about the status of all the previous one.
このコーディングスタイルガイドが定義され、合意される前に、多くのコードがすでに書かれていました。明らかに、そのようなコードはまったくコーディングスタイルに従っていません。新しいコードについては '''従うことを強制します''' が、以前のコードの状態については過剰に心配していません。


In any case, in order to normalize the (progressive, non-critical) transition, a policy issue (MDL-43233) was created and agreed about. And these are the rules to apply to coding-style only changes:
いずれの場合でも、(進行中であり、重要でない) 移行を正規化するために、方針問題 (MDL-43233) が作成され、合意が得られました。そして、コーディングスタイルのみの変更に適用するルールは以下の通りです:


# Related coding-style changes (same lines, a variable within a method/function, adjacent comments...) within a real issue are allowed.
# 実際の問題内で関連するコーディングスタイルの変更 (同じ行、メソッド/関数内の変数、隣接するコメントなど) は許可されます。
# Unrelated coding-style changes (other methods, blocks of code, comments...) within a real issue are only accepted for master and in a separate commit.
# 実際の問題内で関連しないコーディングスタイルの変更(他のメソッド、ブロックのコード、コメントなど)は、マスターにのみ、別のコミットで許可されます。
# Coding-style only issues are only accepted for master along the first 2 months of every cycle.
# コーディングスタイルのみの問題は、各サイクルの最初の2か月間に限り、マスターにのみ受け入れられます。


== Git commits ==
== Gitのコミット ==


Constructing a clear and informative commit is an important aspect of the craft of creating open source code and the history of commits is a vital part of the communication between developers. Time should be spent on crafting commits appropriately and using the git tools to achieve it.
クリアで分かりやすいコミットを作成することは、オープンソースのコード作成の重要な側面であり、コミット履歴は開発者間のコミュニケーションの重要な部分です。適切なコミットを作成するために時間をかけ、gitのツールを使用することが重要です。


Git commits should:
Gitのコミットは以下のようにする必要があります:


* Tell a perfect, cleaned up version of the history. As if the code was written perfectly first time.
* コードが完璧に書かれた初回のような、完全で整理されたバージョンの履歴を表すこと。
* Include the MDL-xxxx issue number associated with the change
* 変更に関連するMDL-xxxxの問題番号を含めること。
* Include CODE AREA when appropriate. (Code area, is just a short name for the area of Moodle that this change affects. It can be a component name if that makes sense, but does not have to be. Remember that your audience here is humans not computers, so if a shortened version of a component name is more readable and distinctive, use that instead.)
* 適切な場合にはCODE AREAを含めること。(Code areaとは、この変更が影響するMoodleの領域の短い名前です。コンポーネント名であっても構いませんが、そうである必要はありません。ここでの対象はコンピュータではなく人間であることに注意してください。コンポーネント名の省略形がより読みやすくて識別可能である場合は、そちらを使用してください。)
* Be formatted as:
* 以下の形式でフォーマットすること:
<pre>
<pre>
MDL-xxxx CODE AREA: short summary (72 chars soft limit)
MDL-xxxx CODE AREA: 短い要約(72文字の制限)


Blank line on line 2, followed by an unlimited length detailed explanation
2行目には空白行を挿入し、必要に応じて無制限の詳細な説明を続けます。このセクションには、変更の動機や以前の動作との対比が含まれる場合があります。
following if necessary. This section might include the motivation for the change
and contrast it with the previous behaviour.
</pre>
</pre>


Git commits should not:
Gitのコミットには、以下のようなものは含めないでください:
* Include changes from bugs found and fixed before integration
 
* Include many separate revisions to the same lines of code for a single issue
* 統合前に見つかったバグの修正内容
* Arbitrarily split when part of a atomic set of logical changes
* 1つの問題に対して同じコード行の多数の別々の修正を含める
* 論理的に1つのセットとして扱うべき変更を、恣意的に分割する


For more guidance, see [[Commit cheat sheet]]
詳細については、[[コミットチートシート (Dev docs)|コミットチートシート]]を参照してください。


==Credits==
== クレジット ==


This document was drawn from the following sources:
このドキュメントは以下のソースから引用されています:


# The original [https://docs.moodle.org/en/index.php?title=Development:Coding&oldid=976 Coding guidelines] page
# オリジナルの[https://docs.moodle.org/en/index.php?title=Development:Coding&oldid=976 コーディングガイドライン]ページ
# The [http://framework.zend.com/manual/en/coding-standard.html Zend guidelines] and
# [http://framework.zend.com/manual/en/coding-standard.html Zendのガイドライン]  
# Feedback from all core Moodle developers
# 全てのMoodleコア開発者からのフィードバック


==関連項目==
==関連項目==


* [[Javascript/Coding_Style|Javascript Coding Style]]
* [[Javascript/コーディングスタイル (Dev docs)|Javascript コーディングスタイル]]
* [[CSS_Coding_Style|CSS Coding Style]]
* [[CSSコーディングスタイル (Dev docs)|CSS コーディングスタイル]]
* [[SQL coding style]]
* [[SQLコーディングスタイル (Dev docs)|SQLコーディングスタイル]]
* [[Coding]]
* [[コーディング (Dev docs)|コーディング]]
* [[CodeSniffer]]
* [[CodeSniffer (Dev docs)|CodeSniffer]]
* [https://moodle.org/plugins/local_codechecker Code Checker plugin]
* [https://moodle.org/plugins/local_codechecker コードチェッカープラグイン]
* [[Accessibility#Moodle-related_accessibility_coding_guidelines|Accessibility coding guidelines]]
* [[アクセシビリティ (Dev docs)#Moodle関連のアクセシビリティコーディングガイドライン|アクセシビリティコーディングガイドライン]]


[[カテゴリ:コーディングガイドライン|コーディングスタイル]]
[[カテゴリ:コーディングガイドライン|コーディングスタイル]]


[[en:development:Coding style]]
[[en:development:Coding style]]

2023年4月27日 (木) 07:11時点における最新版

重要:

このページの内容は更新され、新しいMoodle Developer Resourcesに移行されました。このページに含まれる情報は、もはや最新であるとみなされるべきではありません。

このページを新サイトで閲覧する そして より多くのコンテンツを新サイトに移行するために協力する というのはいかがでしょうか!


(このページは現在翻訳中です。)

概要

範囲

この文書では、Moodleのコードを扱う開発者向けに、コードのレイアウトのメカニズムと、Moodleで採用した選択肢についての スタイル ガイドラインについて説明します。この仕様の目的は、異なる著者によるコードをスキャンする際の認知的な摩擦を減らすことです。それは、PHPコードをフォーマットするための共有されたルールや期待事項を列挙することによって実現されます。

特に指定がない限り、このコーディングスタイル文書は、順番に PSR-12、そしてPSR-1に従います

de-facto Moodle standard* が文書化されていない場合は、適切な MDLSITE の問題を提起し、そのスタンダードをこのコーディングスタイルガイドに記載するか、PSRの勧告を代わりに採用するようにしてください。

* "de-facto Moodle standard" とは、Moodleで一般的かつ典型的に使用されるコーディングスタイルを指します。

ゴール

どんな開発プロジェクトにおいても、一貫性のあるコーディングスタイルは重要であり、特に多数の開発者が関わる場合には必要不可欠です。標準的なスタイルを採用することで、コードをより読みやすく理解しやすくすることができ、全体的な品質を向上させることができます。

私たちが目指す抽象的な目標:

  • シンプリシティ
  • 読みやすさ
  • ツールの使いやすさ、例えば、IDEツールやメソッド、クラス、定数名の自動補完をサポートするメソッドシグネチャ、定数、パターンの使用。

上記の目標を考慮する場合、各状況に応じて状況を検討し、様々なトレードオフをバランスさせる必要があります。

既存のMoodleのコードの多くが、これらのガイドラインに従っていない可能性があることに注意してください。私たちはそれを見つけ次第、このコードをアップグレードし続けています。

何かを実行するためにMoodle APIを使用する詳細については、コーディングガイドラインを参照してください。

便利なツール

このガイドに従うコードの記述に役立つ、いくつかの異なるツールがあります。

コードチェッカー(eclipse/phpstormと統合
https://moodle.org/plugins/view.php?plugin=local_codechecker
Moodle PHPdocチェッカー
https://moodle.org/plugins/local_moodlecheck

両方のツールを使用して、書いているコードをチェックすることは価値があります。両方とも若干異なるチェックを実行するためです。 両方のチェッカーをパスできるようにすると、あなたの作品を審査する人々と友好的になるための良い道を歩んでいます。

ファイルフォーマット

PHPタグ

常に "long" PHPタグを使用してください。ただし、余分な空白を回避するため、ファイルの最後に閉じるタグを含めないでください。

<?php
require('config.php');

インデント

タブ文字を使用せず、インデントは 4つのスペースを使用してください。新しいタブ文字がソースコードに挿入されないように、エディタをタブをスペースとして扱うように設定する必要があります。

メインスクリプトレベルをインデントしないでください:

良い例:

<?php
require('config.php');
$a = required_param('a', PARAM_INT);
if ($a > 10) {
    call_some_error($a);
} else {
    do_something_with($a);
}

悪い例:

<?php
    require('config.php');
    $a = required_param('a', PARAM_INT);
    if ($a > 10) {
        call_some_error($a);
    } else {
        do_something_with($a);
    }

SQLクエリは、SQLコーディングスタイルを参照して特別なインデントを使用します。

最大行長

最も重要な点は可読性です。

132文字を目指すことが望ましく、180文字を超えることは推奨されません。

例外は /lang ディレクトリ内の文字列ファイルで、行 $string['id'] = 'value'; の値は引用符で囲まれた1つの文字列として定義する必要があります(連結演算子、heredoc構文、newdoc構文は使用しない)。これにより、これらの文字列ファイルがPHPコードとして解釈されずに解析および処理できるようになります。

行の折り返し

行を折り返す場合、次のルールが一般的に適用されます。

  • 通常は4つのスペースでインデントします。
  • 制御文の条件や関数/クラス宣言といった折り返し行は、制御文や関数/クラスの本体と視覚的に区別できるように、4つのスペースでインデントします。

以下のセクションの例を参照してください。

制御構造の折り返し

while ($fileinfolevel && $params['component'] === 'user'
        && $params['filearea'] === 'private') {
    $fileinfolevel = $fileinfolevel->get_parent();
    $params = $fileinfolevel->get_params();
}

if文の条件式の折り返し

特別なことは何もなく、制御構造体の規則が適用されます。

if (($userenrol->timestart && $userenrol->timestart < $limit) ||
        (!$userenrol->timestart && $userenrol->timecreated < $limit)) {
    return false;
}

ただし、1つの制御構造に複数の条件がある場合は、条件式の評価に使用するためのヘルパー変数を設定して、可読性を向上させてください。

$iscourseorcategoryitem = ($element['object']->is_course_item() || $element['object']->is_category_item());
$usesscaleorvalue = in_array($element['object']->gradetype, [GRADE_TYPE_SCALE, GRADE_TYPE_VALUE]);

if ($iscourseorcategoryitem && $usesscaleorvalue) {
    // 条件式がより簡単に見直しと理解ができるようになります。
}

次の例と比較してください。

// 以下は避けるべきです。
if (($element['object']->is_course_item() || $element['object']->is_category_item())
        && ($element['object']->gradetype == GRADE_TYPE_SCALE
        || $element['object']->gradetype == GRADE_TYPE_VALUE)) {
    // 条件が複雑で長い行は、適切にインデントされていても非推奨です。
}

クラス宣言の折り返し

class foo implements bar, baz, qux, quux, quuz, corge, grault,
        garply, waldo, fred, plugh, xyzzy, thud {

    // クラス本体は4つのスペースでインデントされます。
}

また、読みやすくするために、実装されたインターフェースをそれぞれ1行にまとめて提供することもできます:

class provider implements
        // これらの行は、クラス本体と視覚的に区別するために、8つのスペースでインデントされます。
        \core_privacy\local\metadata\provider,
        \core_privacy\local\request\subsystem\provider,
        \core_privacy\local\request\core_userlist_provider {

    // クラス本体は4つのスペースでインデントされます。
}

関数シグネチャの折り返し

/**
 * ...
 */
protected function component_class_callback_failed(\Throwable $e, string $component, string $interface,
        string $methodname, array $params) {
    global $CFG, $DB;

    if ($this->observer) {
        // ...
    }
}

関数呼び出しのパラメータの折り返し

通常、パラメータは1行に収まるようになっています。1行に収まらないほど長くなる場合や、読みやすくなる場合は、空白を4つ入れてインデントします。

do_something($param1, $param2, null, null,
    $param5, null, true);

配列の折り返し

特別なことはなく、一般的なルールが再び適用されます。折り返し行を4つのスペースでインデントします。

$plugininfo['preferences'][$plugin] = ['id' => $plugin, 'link' => $pref_url, 
    'string' => $modulenamestr];

多くの場合、各項目を1行にまとめた以下のようなスタイルが、コードをより読みやすくします。

$plugininfo['preferences'][$plugin] = [
    'id' => $plugin, 
    'link' => $pref_url, 
    'string' => $modulenamestr,
];

最後の項目には末尾のカンマが残っていることに注意してください。これは、後で項目リストを拡張してよりきれいな差分を得ることができるようにするためです。同じ理由で、代入演算子も揃えない方がよいでしょう。

関数のパラメータとして渡される配列の折り返し

これは、上記のいくつかの例を組み合わせたものに過ぎません。

$url = new moodle_url('/course/loginas.php', [
    'id' => $course->id,
    'sesskey' => sesskey(),
]);

行の終端部

  • すべての行は、Unixの改行文字(LF、10進数10、16進数 0x0A)で終了する必要があります。
  • キャリッジリターン(CR、10進数13、16進数 0x0D)は単独または LF と一緒に使用してはいけません。
  • 行末に空白文字(スペースやタブ)を入れてはいけません。
  • ファイルの最後には余分な空白行があってはならず、すべてのファイルは1つの LF 文字で終わる必要があります。

注意: これはPSR-12の規約と一致しています。

命名規則

ファイル名

ファイル名は :

  • 全て英語であること
  • できるだけ短くすること
  • 小文字のみを使用すること
  • .php、.html、.js、.css、.xmlのいずかで終わること

クラス

クラス名は必ず小文字の英単語で、アンダースコアで区切ってください:

class some_custom_class {
    function class_method() {
        echo 'foo';
    }
}

コンストラクタがパラメータを必要としない場合でも、新しいインスタンスを作成するときは常に()を使用します。

$instance = new some_custom_class();

例えば、$DB->insert_recordでデータベースに挿入するデータを準備するときなど、特定のクラスのないプレーンなオブジェクトが欲しいときは、PHP標準クラス stdClass を使用する必要があります。 例:

$row = new stdClass();
$row->id = $id;
$row->field = 'something';
$DB->insert_record('table', $row);

Moodle 2.0以前では、私たちはstdClassを拡張したクラス object を定義し、new object() を使用していました; これは現在非推奨です。代わりに stdClass を使用してください。

関数および手法

関数名は単純な英語の小文字の単語で、プラグイン間の衝突を避けるために Frankenstyle のプレフィックスとプラグイン名で始まるようにします。単語はアンダースコアで区切られる必要があります。

冗長性が奨励されます: 関数名は、理解を深めるために、できるだけ具体的に説明することが望ましいです。

PHPでは、すべての新しいコードに対して、タイプヒントと戻り値の宣言の使用が可能なすべての場所で要求されています。既存の非準拠なコードを拡張するコードや、利用できないものを実装するコードなど、必要な除外項目があるものとします。プログレッシブ・アプローチが適用されます。

関数名と次の(括弧)の間にスペースがないことに注意してください。また、Nullable文字(クエスチョンマーク - ?)とパラメータやリターンタイプの間、関数の閉じ括弧とコロンの間にも空白がありません。

function report_participation_get_overviews(string $action, ?int userid): ?array {

    // 実際のファンクションコードはここに入ります。
}

ただし、レガシーな理由でプラグイン名のみをプレフィックスとして使用している活動モジュールは例外です。

function forum_set_display_mode($mode = 0) {
    global $USER, $CFG;
         
    // 実際のファンクションコードはここに入ります。
}

関数パラメータ

パラメーターは常に単純な小文字の英単語($initialvalueのように複数の場合もあります)であり、可能な場合は常に適切なデフォルト値を持つべきです。

このようにデフォルト値が必要ない場合は、"false" の代わりに "null" をデフォルト値として使用します。

public function foo($required, $optional = null)

ただし、オプションのパラメータが boolean であり、その論理的なデフォルト値が true または false である場合は、true または false を使用しても構いません。

変数

変数名は常に読みやすく、意味がある小文字の英単語でなければなりません。もし1つ以上の単語が必要な場合は、連結して書くことができますが、できるだけ短く保つようにしてください。オブジェクトの配列には、複数形 の名前を使用してください。そして、変数名には、常に 肯定的 な言葉を使うようにしてください。(例えば、prevent や disable ではなく、allow や enable などです。

GOOD: $quiz
GOOD: $errorstring
GOOD: $assignments (for an array of objects)
GOOD: $i (but only in little loops)
GOOD: $allowfilelocking = false
BAD: $Quiz
BAD: $camelCase
BAD: $aReallyLongVariableNameWithoutAGoodReason
BAD: $error_string
BAD: $preventfilelocking = true

Moodleのコアグローバル変数は、大文字の変数 (例 $CFG、$SESSION、$USER、$COURSE、$SITE、$PAGE、$DBおよび$THEME) を使用して識別します。 これ以上作らないでください!

定数

定数は常に大文字で、常に Frankenstyle のプレフィックスとプラグイン名で始まります(レガシーな理由からモジュール名のみで活動する場合)。単語はアンダースコアで区切ってください。

define('BLOCK_COURSE_OVERVIEW_SHOWCATEGORIES_NONE', '0');
define('FORUM_MODE_FLATOLDEST', 1);

ブーリアンおよびヌル値

truefalsenullは小文字を使用してください。

名前空間

Moodleの新しいクラスには、正式な名前空間が必要です。ただし、以下の例外があります:

  1. 既存の非名前空間クラスを名前空間に移動させる必要はありません; また
  2. クラスを読み込むための既存のメカニズムが存在し、そのメカニズムが名前空間クラスの使用をサポートしていない場合、クラス名に既存の Frankenstyle プレフィックスを使用することが許可されます。

クラス名に対するクラス名のFrankenstyleプレフィックスの使用は非推奨であり、上記の例外においてのみ使用されるべきである。

良い例:

namespace mod_forum;
class example {
}
 
namespace mod_forum\external;
class example {
}
 
namespace core_user;
class example {}

悪い例 (非推奨):

class mod_forum_example {
}
 
class mod_forum_external_example {
}
 
class core_user_example {
}

名前空間の使用は、以下のルールに従う必要があります:

  1. 名前空間に属するクラスは、プラグイン内のクラスディレクトリ(例:mod/forum/classes)または、コアコードの場合は lib/classes または subsystemdir/classesに作成する必要があります。
  2. すべての名前空間に属するクラスのクラス名とファイル名は、クラスの自動読み込みルールに従う必要があります。新しいコードには、形式的なPHP名前空間の使用が必要です。
  3. ファイルあたり1つの名前空間宣言を使用する必要があります。

良い例:

<? // これは mod/porridge/classes/local/equipment/spoon.php のファイルです。

namespace mod_porridge\local\equipment;

class spoon {
    // ここにあなたのコード。
}

// ファイルの終了。

悪い例:

namespace mod_porridge\local\equipment;

class spoon {
    // ここにあなたのコード。
}

namespace mod_porridge\local\procedures; // ここで名前空間を変更しているため、変更しないでください。

class eat {
    // ここにもう1つのコード。
}

// ファイルの終了。

名前空間宣言は、ドックブロックで先行することができます。

クラスの命名は、名前空間の各レベルの名前にも適用されます。

名前空間宣言は、ファイル内で最初の非コメント行でなければならず、1つの空白行に続いて(オプションで)1行に1つの "use" ステートメントが続き、さらに1つの空白行が続きます。

"use" ステートメントは、コード内で長い名前空間を繰り返し使うのを避けるために使用する必要があります。

"use" ステートメントを使用して、名前空間全体をインポートしないでください。個々のクラスだけをインポートしてください。

衝突を解決するために絶対に必要でない限り、名前を付けてインポートしないでください("use XXX as YYY;")。

良い例:

use mod_porridge\local\equipment\spoon; // 1行につき1つのクラスです。
use mod_porridge\local\equipment\bowl; // 1行につき1つのクラスです。

悪い例:

use mod_porridge\local\equipment\spoon, mod_porridge\local\equipment\bowl; // 1行に複数のクラスがあります。
use mod_porridge\local; // 名前空間全体をインポートします。
use core; // 名前空間全体をインポートします。
use mod_breakfast; // 名前空間全体をインポートします。
use mod_porridge\local\equipment\spoon as silverspoon; // 名前を付けてインポートする理由がありません。

__NAMESPACE__のマジック定数を使用しないでください。

名前空間宣言以外の場所で "namespace" キーワードを使用しないでください。

悪い例:

$obj = new namespace\Another();

ブラケットで囲まれた "namespace" ブロックを使用しないでください。

悪い例:

namespace {
    // グローバルスコープ。
}

名前空間は、"classes" のサブフォルダに存在するクラスにのみ使用する必要があります。

新しいクラスの場合 - 名前空間を決定する際には、最大の詳細レベルを使用する必要があります。

良い例:

namespace xxxx\yyyy; // xxxx はコンポーネント、 yyyy はAPIです。

class zzzz {
}

"namespace" および "use" ステートメントで先頭にバックスラッシュ(\)を使用しないでください。

名前空間付きのコードから呼び出されるグローバル関数には、先頭にバックスラッシュ(\)を使用しないでください。現在のスコープの外側のクラスは、先頭にバックスラッシュを使用するか、"use" キーワードでインポートされます。詳細については、PHPマニュアルを参照してください。

良い例:

namespace mod_breakfast\local;

use moodle_url;

echo get_string('goodmorning', 'mod_breakfast'); // グローバル関数の先頭にバックスラッシュがありません。
$url = new moodle_url(...); // "use" で名前空間にインポートしているので、先頭のバックスラッシュは必要ありません。
$tasks = \core\task\manager::get_all_scheduled_tasks(); // ここでは先頭にスラッシュが必要です。
$a = new \stdClass(); // ここでは先頭にスラッシュが必要です。

悪い例:

namespace \mod_breakfast; // 先頭のバックスラッシュはあってはいけません。

use \core\task\manager; // 先頭のバックスラッシュはあってはいけません。

\get_string('xxxx', 'yyyy'); // 先頭のバックスラッシュはあってはいけません。

名前空間の構成要素

以下のような完全修飾名でクラスが示されている場合:

"\<level1>\<level2>\<level3>\...\<classname>"

各名前空間のレベルには許容される要素について明確な規則があります。最初のレベルだけが必須です。クラスがコアAPIを実装する場合や、プラグイン管理者がプラグイン内の名前空間を分けてクラスを整理する場合は、ネストされた名前空間が使用されます。詳細はlevel2に関する規則を参照してください。

レベル1のルール

最初のレベルは、次のいずれかでなければなりません:

  • 完全なコンポーネント名(例:"\mod_forum")。プラグインで名前空間を使用するすべてのクラスは、このレベル1の名前空間に含まれている必要があります。

または

  • すべてのコアAPIに対して "\core" を使用してください。

レベル2のルール

第2レベルは、使用される場合、次のいずれかでなければなりません:

  • コアAPIの短い名前(https://docs.moodle.org/dev/API で定義されている必要があります)。この名前空間のクラスは、APIを実装または使用する必要があります。

または

  • コンポーネント内の他のクラスをさらに整理したい場合は、"\local" を使用します(ほとんどのコンポーネントでは、ルートレベル1の名前空間のみにすべての独自のクラスを持つことで十分であることに注意してください)。

レベル3のルール

レベル3名前空間として使用できるものを制限するルールはありません。このため、プラグインやアドオンがレベル3の名前空間として使用することができます。 の名前空間は、他のプラグインやapiと衝突する可能性がなく、現在も、そしてこれからも、ずっと続くでしょう。

**/testsディレクトリ内の名前空間

(MDLSITE-4800で合意)

  • ユニットテストでは、名前空間の利用を強く推奨します。
  • 名前空間を使用する場合、テストクラスの名前空間は、テスト対象のコードの名前空間と一致させる必要があります。
  • テストクラスは、テスト対象のクラスから名前をとり、`_test.php` を接尾辞としてつける必要があります。
  • テストクラスの第 1 レベルの名前空間は、それが属するコンポーネントと一致 しなければなりません
  • サブの名前空間は許可されますが、上記のレベル2および3の一般的な名前空間のルールに厳密に従う必要があります。常に、対象となるコードの名前空間と可能な限り一致させるようにします。
  • サブディレクトリの構造は、名前空間の構造と一致しなければなりませんが、代わりに `tests` ディレクトリに配置されます。

注意:テストの自動読み込みはサポートされていません(ただし、テストから標準クラスを自動読み込みすることは可能です)。

良い例:

// 入れ子になった名前空間を使用しない場合のプラグイン固有の名前空間(一般的な)
// 名前空間の場所:mod/breakfast/classes/
// テストの場所:mod/breakfast/tests/
namespace mod_breakfast;

// 入れ子になった名前空間を使用する場合のプラグイン固有の名前空間
// 名前空間の場所:mod/breakfast/classes/local/
// テストの場所:mod/breakfast/tests/local/
namespace mod_breakfast\local;

// さらに組織化された入れ子になった名前空間を使用する場合のプラグイン固有の名前空間
// 名前空間の場所:mod/breakfast/classes/local/utils/
// テストの場所:mod/breakfast/tests/local/utils/
namespace mod_breakfast\local\utils;

// コアAPIを実装するためのプラグインの名前空間
// 名前空間の場所:mod/breakfast/classes/event/
// テストの場所:mod/breakfast/tests/event/
namespace mod_breakfast\event;

悪い例:

namespace mymodule;                     // レベル1のルールに違反 - 無効なコンポーネント名
namespace mod_breakfast\myutilities;    // レベル2のルールに違反 - 無効なコアAPI名
namespace mod_forum\test;               // 技術的には正しいですが("test" は有効なAPIです) - これは許容できません
                                        // なぜなら、テストの名前空間はコードの名前空間と一致する必要があるためです
                                        // 通常、コンポーネントに "test" という名前のものは存在しないため、これはカバーされるべきではありません
                                        // レベル2がカバーされた後にのみ、それを使用することができます

文字列

現在のPHPバージョンでは、文字列のパフォーマンスは問題にならないため、文字列の主な基準は可読性です。

シングルクォーテーション

文字列がリテラルである場合や、ダブルクォーテーションが多く含まれる場合(HTMLなど)、常にシングルクォーテーションを使用してください。

$a = 'Example string'; 
echo '<span class="'.s($class).'"></span>'; 
$html = '<a href="http://something" title="something">Link</a>';

ダブルクォーテーション

これらは、Moodleではあまり役に立ちません。プレーンな変数や多くのシングルクォーテーションを含める必要がある場合、ダブルクォーテーションを使用してください。

echo "<span>$string</span>"; 
$statement = "You aren't serious!";

複雑なSQLクエリは、必ずダブルクォーテーションで囲む必要があります。

$sql = "SELECT e.*, ue.userid
          FROM {user_enrolments} ue
          JOIN {enrol} e ON (e.id = ue.enrolid AND e.enrol = 'self' AND e.customint2 > 0)
          JOIN {user} u ON u.id = ue.userid
         WHERE :now - u.lastaccess > e.customint2";

変数の置換

変数の置換には、次のいずれかの形式を使用できます:

$greeting = "Hello $name, welcome back!";

$greeting = "Hello {$name}, welcome back!";

文字列の結合

文字列は "." 演算子を使用して結合する必要があります。

$longstring = $several . $short . 'strings';

行が長い場合は、可読性を向上させるために、ステートメントを複数の行に分割してください。この場合、各行の最後に "ドット" を置いてください。

$string = 'This is a very long and stupid string because ' . $editorname .
          " couldn't think of a better example at the time.";

演算子 "." は、上記の例に示されるように、どちらの側にもスペースを入れずに使用することもできます。開発者が好む方法を使用してください。

言語文字列

大文字と小文字

言語文字列は "Always look like this(このように常に見える)"、"Never Like This Example(このように決して見えない)" のように書くべきです。

大文字は、次の場合にのみ使用する必要があります:

  1. 文章の先頭で始まる場合、または
  2. Moodle のような固有名詞で始まる場合。

構造

文字列は UI の連結を想定して設計されていないため、他の言語で問題が発生する可能性があります。各文字列は単独で機能する必要があります。

悪い例:

$string['overduehandling'] = 'When time expires';
$string['overduehandlingautosubmit'] = 'the attempt is submitted automatically';
$string['overduehandlinggraceperiod'] = 'there is a grace period in which to submit the attempt, but not answer more questions';
$string['overduehandlingautoabandon'] = 'that is it. The attempt must be submitted before time expires, or it is not counted';

良い例:

$string['overduehandling'] = 'Time expiry behaviour';
$string['overduehandlingautosubmit'] = 'Unfinished attempts will be auto-submitted immediately';
$string['overduehandlinggraceperiod'] = 'Unfinished attempts have a short grace period to be submitted for grading';
$string['overduehandlingautoabandon'] = 'Unfinished attempts are immediately discarded';

空白

言語文字列には、前後にスペースを含めたり、依存したりしないでください。そのような文字列は、AMOS翻訳ツールで翻訳することが容易ではありません。

配列

数値インデックス付きの配列

配列を宣言する際には、可読性を向上させるため、各カンマ区切りの後にスペースを追加する必要があります。

$myarray = [1, 2, 3, 'Stuff', 'Here'];

複数行のインデックス配列も問題ありませんが、次の各行も前述のように4つのスペースのインデントで埋め込みます:

$myarray = [1, 2, 3, 'Stuff', 'Here',
    $a, $b, $c, 56.44, $d, 500];

上記の例は以下のように書くこともできます:
(後で項目のリストを拡張するためのクリーンな diff を作成するため、最後の行にカンマがあることに注意してください)

$myarray = [
    1, 2, 3, 'Stuff', 'Here',
    $a, $b, $c, 56.44, $d, 500,
];

いずれにしても、1行の要素数に関係なく、括弧と改行のバランスをとる必要があります。

連想配列

可読性が向上する場合は、複数行に分割して使用してください。例:

$myarray = [
    'firstkey' => 'firstvalue',
    'secondkey' => 'secondvalue',
];

クラス

クラス宣言

  • クラスはMoodleの命名規則に従って命名する必要があります。
  • クラスは、自動読み込みや名前空間の利点を得るために、それぞれの "component/classes" ディレクトリの下に置かなければなりません。そこから先は、そんな贅沢なことはできません。
  • 各PHPファイルには、クラス(またはインターフェース、トレイトなど)が1つだけ含まれます。ただし、複数のアーティファクトファイルが許可されていた古いAPIの一部である場合を除きます。
  • ブレースは必ずクラス名の横の行に書いてください。
  • すべてのクラスは、PHPDocumentor の標準に準拠したドキュメントブロックを持つ必要があります。
  • クラス内のすべてのコードは、4つのスペースでインデントされなければなりません。
  • クラスファイルに追加のコード("サイドエフェクト")を配置することは、自動読み込みで提供されないアーティファクト("classes" ディレクトリ以外から取得した古いクラスやライブラリで、Moodleのブートストラップによって読み込まれなかったもの)を必要とする場合にのみ許可されます。そのような場合には、MOODLE_INTERNALチェックの使用が必要になります。
一例:
/**
 * Short description for class.
 *
 * Long description for class (if any)...
 *
 * @package    mod_mymodule
 * @copyright  2008 Kim Bloggs
 * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class sample_class {
    // クラスの全てのコンテンツは
    // スペース4つ分インデントされる必要があります。
}

クラス PHPDoc スタイルは、このドキュメントの ドキュメントおよびコメント/クラス セクションでより詳しく定義されていることに注意してください。

クラスのメンバ変数

メンバ変数は、Moodleの変数命名規則に従って命名する必要があります。

クラスで宣言された変数は、クラスの先頭で、メソッドの宣言の上に記載しなければなりません。

var構成は許可されていません。メンバ変数は常に、private, protected, public のいずれかの修飾子を使用して可視性を宣言します。メンバ変数を public として直接アクセスすることは許可されていますが、アクセサメソッド(set/get)を優先することが推奨されています。

関数とメソッド

関数とメソッドの宣言

関数は、Moodleの関数命名規則に従って名前を付ける必要があります。

クラス内のメソッドは、常に private、protected、または public の修飾子を使用して可視性を宣言する必要があります。

クラスと同様に、波括弧は常に関数名と同じ行に書く必要があります。

引数の開き括弧と関数名の間にスペースを入れてはいけません。

返り値は、括弧で囲まれていてはいけません。これは可読性を損なうだけでなく、後で参照による返り値に変更された場合にコードが壊れる可能性があります。

返り値は1つのデータ型でなければなりません。複数の返り値型を持つことは推奨されません。

/**
 * ここにドキュメンテーションブロックを記述します
 */
class sample_class {
    
    /**
     * ここにドキュメンテーションブロックを記述します
     */
    public function sample_function() {
        // 関数の中身はすべて
        // スペース4つ分インデントされる必要があります。
        return true;
    }
}

関数とメソッドの使用

関数の引数は、コンマ区切りの後に1つのスペースを開けるようにしてください。

three_arguments(1, 2, 3);

マジックメソッド

マジックメソッドは強く非推奨であり、使用する際には正当性が必要です。注意: 怠惰さは正当な理由とはなりません。

(背景についてはMDL-52634を参照してください)

制御文

一般的に、行間などに十分なスペースを使って、明瞭さを追加するようにしてください。

If/else文

中括弧の制御文の前後にはスペースを入れ、中括弧内の演算子はスペースで区切ります。 論理的なグループ化を改善する場合は、内部の括弧を使用してください。

4つのスペースでインデントしてください。

elseif は使用しないでください!

ブロックが1行であっても(PHPが必要としなくても)、常に中括弧を使用してください。ブロックの開始中括弧は、対応するステートメントまたは宣言と同じ行に配置されます。

if ($x == $y) {
    $a = $b;
} else if ($x == $z) {
    $a = $c;
} else {
    $a = $d;
}

Switch文

中括弧の制御文の前後にはスペースを入れ、中括弧内の演算子はスペースで区切ります。論理的なグループ化を改善する場合は、内部の括弧を使用してください。

常に4つのスペースでインデントしてください。各case文の下のコンテンツはさらに4つのスペースでインデントする必要があります。

switch ($something) {
    case 1:
        break;

    case 2:
        break;

    default:
        break;
}

Foreach文

前述のように、次のようにスペースを使用します:

foreach ($objects as $key => $thing) {
    process($thing);
}

三項演算子

三項演算子は、短く, 理解しやすい文に限定して使用することができます。文が一文で理解できない場合は、if文を代わりに使用してください。

演算子の周りに空白を使用して、操作がどこで実行されているかを明確にする必要があります。

良い例:

$username = isset($user->username) ? $user->username : ''; **
$users = is_array($users) ? $users : [$users];

悪い例:

$toload = (empty($CFG->navshowallcourses))?self::LOAD_ROOT_CATEGORIES:self::LOAD_ALL_CATEGORIES;
$coefstring = ($coefstring=='' or $coefstring=='aggregationcoefextrasum') ? 'aggregationcoefextrasum' : 'aggregationcoef';

** 注意:PHP 7.0以降、多くの "isset()" 三項演算子は、新しい省略記法 null coalescing operator を使用するように変更できます。つまり、上記は以下と同じです。

$username = $user->username ?? '';

Require / include

ブラウザ経由でアクセスされる各ファイルは、まずメインのconfig.phpファイルをインクルードすることから始める必要があります。

require(__DIR__ . '/../../config.php');

その他のinclude/requireは、__DIR__で始まるパスまたは$CFG->dirrootまたは$CFG->libdirで始まる絶対パスを使用する必要があります。"../" で始まる相対的なインクルードは、PHPでは時々奇妙な動作をするため、使用しないでください。CLIスクリプトでは、"../" で始まる相対的なconfig.phpパスを使用しないでください。

一般的な使用において、ライブラリファイルについては、require_onceを使用する必要があります(これは常に上記のように'require'を使用する必要があるconfig.phpとは異なります)。例:

require_once(__DIR__ . '/locallib.php');
require_once($CFG->libdir . '/filelib.php');

インクルードは、通常はファイルの先頭または必要な場合にのみ、関数/メソッドの内部で行うべきです。ファイルの途中でinclude/requireを使用すると、グローバルスコープでのセキュリティの監査が非常に困難になります。

他のすべてのスクリプトにおいて、インポートされたサードパーティのライブラリおよび side-effects*(つまり、単一のクラス定義、インターフェイス、またはトレイト)のないファイルを除き、誤って設定された本番サーバでエラーメッセージを公開する可能性がある直接実行を防止するために、以下のコードをファイルの先頭で使用する必要があります。

defined('MOODLE_INTERNAL') || die();

*side-effects: a) 名前空間と使用文 b) 名前空間定数 c) strict_types宣言(宣言全般)以外のグローバルスコープコード。

ファイル内に副作用があるかどうかの存在または不在は、コードレベルで上記のように説明されるようにのみ影響します。特に言及されない限り、コーディングスタイルの他の部分では考慮すべきではありません。

ドキュメンテーションとコメント

コードのドキュメンテーションは、関数や変数の目的やコードのフローを説明します。実用的な場合には、必ず使用してください。

PHPDoc

Moodleは、ファイル、クラス、および関数を文書化するために、できるだけ「標準的な」PHPDocフォーマットに従います。これにより、Moodle開発者がNetbeansやEclipseのようなIDEを適切に使用できるようになり、Webドキュメンテーションを自動的に生成することもできます。

PHPDocには、異なる場所(ファイル、クラス、関数)で使用できるいくつかのタグがあります。Moodleでは、それらを使用するためのいくつかの特別なルールがあり、それに従う必要があります。

以下のタグ (@param, @return...) のいくつかは、有効なPHPの型とその説明を指定する必要があります。以下のものが許可されています:

  • PHPのプリミティブ型:int、bool、stringなど
  • PHPの複雑な型:array、stdClass (Array、objectではない)
  • PHPのクラス:完全な名前または相対的な(現在の名前空間に対する)クラス名
  • true、false、null (常に小文字)
  • static: 子クラス/呼び出し側のクラスの新しいインスタンスを返すメソッドに使用します。
  • self: 親クラス/呼び出されたクラスの新しいインスタンスを返すメソッドに使用します。
  • $this: クラスの現在のインスタンスを返すメソッドに使用します。
  • void: 明示的に空の "return" ステートメントを持つメソッドに使用します。

また、これらの型を使用する際には、いくつかの基本的なルールがあります:

  • 短い型名を使用します (booleanではなくbool、integerではなくintなど)。
  • 特定の型の配列として表現される場合、より簡単で情報量の少ない "array" の代わりにtype[]として文書化することを強くお勧めします (例:int[]またはstdClass[]など)。
  • 複数の異なる型が可能な場合、縦棒 (パイプ) で区切る必要があります (例:@return int|falseなど)。
  • すべてのプリミティブおよびキーワードは小文字で記述します。複雑な型とクラスの場合は、元のものと同じ大文字と小文字を使用します。

タグ

@copyright

これらには、オリジナルファイルの作成者である年と著作権保有者が含まれます。既存のファイルではこれらを変更しないでください!

 @copyright 2008 Kim Bloggs
@license

これらは GPL v3+ を使用し、以下の形式を使用する必要があります:

 @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 以降
@param

変数名の後ろにハイフンや何か特別な文字を入れないでください。スペースだけを使用してください。

 @param type $name 説明。
@return

関数に戻り値がある場合は、@returnタグは必須ですが、戻り値がない場合は省略できます。

説明部分はオプションです。関数がシンプルで戻り値について説明されている場合は、省略することができます。

 @return type 説明。
@var

@varタグは、クラスのプロパティをドキュメント化するために使用されます。

 @var type 説明。

例外的に、利用可能なtypesのいずれも返された値を定義しない場合、メソッドの本文内で型ヒントを提供するインライン@var phpdocsを返された型に許可されています。濫用しないでください!

@uses

関数がdieまたはexitを使用する場合は、このタグをドックブロックに追加して、開発者がこの関数がページを終了できることを知るのに役立ててください。

 @uses exit
@access

アクセスは、要素のアクセス制御を指定するために使用できます。

  1. メソッド定義が既にアクセス制御を指定していない場合にのみ使用する必要があります。
  2. 関数の場合、publicアクセスを指定することは冗長であるため、避けるべきです。
 @access private
@package

@packageタグは、正しいFrankenstyleコンポーネント名でphpファイルにラベルを付けるために常に使用する必要があります。詳細なルールはそのページで説明されていますが、要約すると次のとおりです。

  1. ファイルが任意のコンポーネントプラグインの一部である場合は、プラグインコンポーネント名(例:mod_quiz または gradereport_xls )を使用します。
  2. ファイルがコアサブシステムの一部である場合、get_core_subsystems()で定義された名前がxxxxであることになります(たとえば、core_enrol または core_group )。
  3. サブシステムの一部でないコアの選択された数少ないファイル(lib/moodlelib.phpなど)の場合は、単に core というパッケージとして存在します。
  4. 各ファイルは1つのパッケージのみに属することができます。

(@subpackageにはまったく標準がありません。@package内で好きなように使用できます。)

 @package gradereport_xls
@category

私たちは、@categoryを使用して、コアAPIの一部であるパブリッククラス、関数、またはファイル、あるいはコアAPIの良い例の実装を示すためにのみ使用します。値は、コアAPIページのいずれかの値である必要があります。

 @category preferences
@since

Moodleのコアライブラリに新しいクラスや関数を追加する場合(または既存のクラスに新しいメソッドを追加する場合)、@sinceタグを使用して、その追加されたMoodleのバージョンを文書化します。例:

 @since Moodle 2.1
@see

関連する別の要素(include、class、function、define、method、variable)をユーザに参照させたい場合は、URLではなく@seeタグを使用することができます。

@see some_other_function()

このタグは、phpdocコメント内でもインラインで使用できます。

  /**
   * この関数は{@see get_string()}を使用して通貨名を取得します...
   * .....
@link

外部のURLにユーザを参照させたい場合は、関連要素ではなく@linkを使用します。

 @link https://docs.moodle.org/dev/Core_APIs

このタグは、phpdocコメント内でもインラインで使用できます。

  /**
   * 下記の実装の詳細については、{@link https://docs.moodle.org/dev/Core_APIs} にアクセスし、読んでください...
   * .....
@deprecated (および@todo)

古いAPIを廃止する場合は、@deprecatedタグを使用して、どのバージョンのMoodleで廃止されたかを文書化し、できる限り@todoと@seeを追加してください。関連するMDLの問題を必ず記載してください。例えば:

/**
 * ...
 * @deprecated since Moodle 2.0 MDL-12345 - please do not use this function any more.   
 * @todo MDL-22334 This will be deleted in Moodle 2.2.
 * @see class_name::new_function()
 */

開発者がコードを更新する必要がある場合は、デバッグメッセージを繰り返して表示するために、debugging('...', DEBUG_DEVELOPER);呼び出しを追加することも検討してください。古い関数を全くサポートできなくなった場合は、coding_exceptionをスローする必要がある場合もあります。各種オプションの例については、lib/deprecatedlib.phpを参照してください。

@throws

このタグは有効であり、オプションで使用することができます。メソッドまたは関数が例外をスローすることを示すために使用されます。これにより、開発者がそのような関数からの例外を処理する必要があることを知ることができます。

その他の特定のタグ

グローバルではなく、特定の文脈でのみ許可されているタグがあります。より具体的には、以下のようになります:

  • @Given、@When、@Thenは、behatステップ定義内でのみ使用できます。
  • @covers、@coversDefaultClass、@coversNothing、@usesは、ユニットテスト内でカバレッジをより細かく制御するために使用します。
  • @dataProviderと@testWithは、ユニットテスト内で、例と期待値を提供するために使用されます。
  • @dependsは、テスト間の依存関係を表現するために使用されます。各プロデューサが返したデータがコンシューマに渡されます。詳細については、@depends examples を参照してください。
  • @groupは、PHPUnit MoodleDocsのガイドラインに従い、ユニットテストを簡単にグループ化するために使用されます。
  • @requiresは、ユニットテストの要件を指定し、満たされない場合はスキップします。詳細については、@requires usages を参照してください。
  • @runTestsInSeparateProcessesと@runInSeparateProcessは、個々のテストまたはテストケースを独立して実行するために使用されます。厳密に必要な場合にのみ使用してください。

ファイル

PHPコードを含むすべてのファイルは、PHPオープンタグの後に空行を挿入せず、トップに完全なGPL著作権声明を含める必要があります。その下には、以下の情報を含む別個のドックブロックが必要です:

  1. ファイルの簡単な一行の説明
  2. ファイルの詳細な説明
  3. @packageタグ (必須)
  4. @categoryタグ (ファイル内のすべてがコアAPIの関連である場合にのみ必要)
  5. @copyright (必須)
  6. @license (必須)

1つのアーティファクトだけを含むファイルの場合、そのアーティファクト(クラス、インターフェース、トレイトなど)が文書化されている限り、ファイルのphpdocブロックはオプションです。この場合については、以下の "クラス" のセクションを読んでください。

<?php
// このファイルはMoodleの一部です - https://moodle.org/
//
// Moodleはフリーソフトウェアであり、あなたはそれを再配布したり、
// 改変することができます。
// これはGNU General Public Licenseに従って公開されています。
// ライセンスのバージョンは、バージョン3、あるいは
// (あなたの選択により)それ以降のバージョンを使用することができます。
//
// Moodleは、役に立つことを願って配布されていますが、
// すべての保証を含めて、明示的にも黙示的にも何の保証もありません。
// 詳細については、GNU General Public Licenseを参照してください。
//
// あなたは、Moodleと共にGNU General Public Licenseのコピーを受け取るはずです。
// もし受け取っていなければ、<https://www.gnu.org/licenses/>を参照してください。

/**
 * これはファイルの簡単な一行の説明です。
 *
 * あなたはファイルのかなり長い説明も持つことができ、
 * 複数の行にまたがることもできます。
 *
 * @package    mod_mymodule
 * @category   backup
 * @copyright  2008 Kim Bloggs
 * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3またはそれ以降
 */

クラス

すべてのクラスは以下のような完全なドックブロックを持つ必要があります。

/**
 * クラスの短い説明。
 *
 * クラスの長い説明 (ある場合)。
 *
 * @package    mod_mymodule
 * @category   backup
 * @copyright  2008 Kim Bloggs
 * @license    https://www.gnu.org/copyleft/gpl.html GNU GPL v3 またはそれ以降のバージョン
 */
class policy_issue {

1つのアーティファクト (クラス、インターフェース、トレイトなど) のみを含むファイルについて、特に classes ディレクトリ内のすべてのファイル、および他の場所にある条件を満たす任意のファイルについては、クラスの phpdoc ブロックだけで十分です。ファイルの phpdoc ブロックは、クラスに優先度を与えるため、すべての効果においてオプションと見なされます。

上記の例に示されるように、@package@copyright@license タグ(およびオプションの @category タグ)は、常にファイルに存在する必要があります(どのドックブロックにあっても、すべて一緒に)。

プロパティ

すべてのプロパティには、次の最小情報を持つドックブロックが必要です。

class example {
    /** @var string この変数は何かを行います */
    protected $something;
}

または

class example {
    /**
     * この変数は何かを行い、複数行にまたがる非常に長い説明があります
     * @var string 
     */
    protected $something;
}

DocBlockテンプレートを使用しないでください。代わりに、次の例のように、すべてのプロパティを明示的に文書化してください。

class zebra {
    /** @var int 白いストライプの数 */
    protected $whitestripes = 0;

    /** @var int 黒いストライプの数 */
    protected $blackstripes = 0;

    /** @var int 赤いストライプの数 */
    protected $redstripes = 0;
}

定数

クラス定数は、次の方法で文書化する必要があります:

class sam {
   /**
    * Samが良い気分のときに使用されます。
    */
   const MOOD_GOOD = 0;
}

関数

すべての関数とメソッドには、次のように完全なドックブロックが必要です。

/**
 * 説明は最初に記述し、この例のようにアスタリスクを正確に並べます。
 * 別の関数を参照する場合は、以下のように@seeを使用してください。
 * MoodleのWeb上のドキュメントへのリンクが役立つ場合は、以下のように@linkを使用するか、
 * またはインラインで{@link https://docs.moodle.org/dev/something}のように使用できます。
 * その後、各パラメータと戻り値について次のように説明を追加します。
 *
 * @see clean_param()
 * @param int   $postid PHPのタイプに続いて変数名を記述します
 * @param array $scale PHPのタイプに続いて変数名を記述します
 * @param array $ratings PHPのタイプに続いて変数名を記述します
 * @return bool 成功または失敗を示すステータス
 */

@paramおよび/または@return行から明らかであると思われる場合でも、説明を含める必要があります。

親メソッドの意味を変更せず、同じ引数/戻り値を維持するオーバーライドされたメソッドについては、この場合はコメントを完全に省略する必要があります。@inheritdocまたは@seeタグの使用は、完全なドックブロックの代わりに明示的に禁止されています。

定義

すべての定義は、以下の方法でドキュメント化する必要があります:

/**
 * PARAM_INT - 整数のみ、数字のみを想定する場合に使用します。
 */
define('PARAM_INT', 'int');
/**

PARAM_ALPHANUM - 数字と文字のみを想定します。
*/
define('PARAM_ALPHANUM', 'alphanum');

インラインコメント

インラインコメントは、"// "(2つのスラッシュ+空白)スタイルを使用する必要があります。そのコメントがコードに収まり、整然と並ぶように配置します。コメントの最初の行は大文字で始まり(または数字、または '...')、適切な句読点文字で終わる必要があります。許可される最後の文字は、'.'、'?'、'!'のいずれかです。

function forum_get_ratings_mean($postid, $scale, $ratings = null) {
    if (!$ratings) {

        $ratings = [];     // 空の配列を初期化します。

        $rates = $DB->get_records('forum_ratings', ['post' => $postid)];

        // ... そして、それぞれの評価を処理します。
        foreach ($rates as $rate) {
            do_something_with($rate);
        }

        // 片付けが必要か?
        if (!empty($rates))
            ここで42の別の処理が行われます!
            finsh_up();
        }

良い例:

// このコードの説明をするコメント。

悪い例:

/* このコードの説明をするコメント。*/
# このコードの説明をするコメント。
// このコードの説明をするコメント(大文字と句読点なし)。


もしコメントがMDLの問題に関連している場合は、適切なMDL-12345をコメントに含めてください。これにより、決定や議論を追跡することがより簡単になります。

TODOを使用する

特に、後で取り組む必要のある問題がまだそのコードに存在することを知っている場合には、TODOとMDLコードを使用してそれをマークすることが重要です。例えば:

// TODO MDL-12345 これは機能するが、ややハック的であり、将来的に改訂する必要がある。

ほとんど完了している大きなタスクがあり、いくつかのTODOが残っている場合は、大きなタスクを完了したとマークしたい場合は、各TODOのために新しいトラッカータスクを作成し、TODOのコメントを新しい問題番号に指し示すように変更する必要があります。

"TODO チェック" を行う便利なレポートツールがあります。管理者専用で、ウェブ経由で lib/tests/other/todochecker.php で利用できます。

最後に、あなたのTODO(また、@todosも、非推奨プロセスの一部でない限り、それらは別に扱われます)で使われているMDL-l2345を "Review TODOs Epic" に加えることを忘れないでください : MDL-47779 (問題を見るにはログインが必要です)

CVS キーワード

Moodle 2.0 からは、$Id$ のような CVS キーワードの使用を完全に停止しています。

例外処理

エラーの報告には、特にライブラリコードにおいて、例外を使用してください。

例外を投げることは、print_error() を呼び出すこととほぼ同じ効果がありますが、より柔軟性があります。例えば、呼び出し元は例外をキャッチして、何らかの方法で処理することができます。また、ユニットテストを書くこともより簡単になります。

2021年以降、print_error() を廃止し、代わりに moodle_exception() をスローすることが合意されたため、注意してください。

キャッチされていない例外は、問題をユーザに報告するために適切な print_error の呼び出しをトリガーします。"エラーコード" として表される例外は、最終的なユーザに表示するために翻訳されます。

通常のコードフローに例外を乱用しないでください。例外は、異常な状況でのみ使用する必要があります。

例外クラス

カスタム例外クラスのセットを持っています。ベースクラスはmoodle_exceptionです。new moodle_exception(...)に渡す引数は、print_errorに渡す引数と非常に似ていることに気づくでしょう。特定の種類のエラーに対してより具体的なサブクラスがあります。

例外タイプの完全なリストを取得するには、 'class +\w+_exception +extends'という正規表現を検索するか、あなたのIDEにmoodle_exceptionのすべてのサブクラスをリストアップするように依頼してください。

適切な場合は、自分のコードで使用するためにmoodle_exceptionの新しいサブクラスを作成する必要があります。

いくつかの注目すべき例外タイプ:

moodle_exception
Moodleの例外の基本クラス。より特定のタイプが適切でない場合に使用します。
coding_exception
開発者のミスが原因と思われる場合にスローされます。プラグインとやり取りするコアコードによって頻繁にスローされます。このタイプの例外をスローする場合は、エラーメッセージがプラグインの作者に役立つようにし、彼らが自分のコードを修正する方法を知ることができるようにしてください。
dml_exception (およびサブクラス)
データベースクエリが失敗したときにスローされます。
file_exception
File APIによってスローされます。

危険な関数や構造体

PHPには、深刻なセキュリティ問題の原因となることが非常に多いとされている、問題のある機能が複数含まれています。

  1. eval() 関数を使用しないでください。ただし、言語パックに関しては(将来的に解決されることを前提に)例外です。
  2. preg_replace() 関数を /e 修飾子とともに使用しないでください。PHPの予期しない実行を防止するために、コールバックを使用してください。
  3. バッククォートを使用してシェルコマンドを実行しないでください。
  4. goto 文、演算子、またはラベルを使用しないでください。代わりに他のプログラミング技法を使用して実行フローを制御してください。

コーディングスタイルの修正についての方針

このコーディングスタイルガイドが定義され、合意される前に、多くのコードがすでに書かれていました。明らかに、そのようなコードはまったくコーディングスタイルに従っていません。新しいコードについては 従うことを強制します が、以前のコードの状態については過剰に心配していません。

いずれの場合でも、(進行中であり、重要でない) 移行を正規化するために、方針問題 (MDL-43233) が作成され、合意が得られました。そして、コーディングスタイルのみの変更に適用するルールは以下の通りです:

  1. 実際の問題内で関連するコーディングスタイルの変更 (同じ行、メソッド/関数内の変数、隣接するコメントなど) は許可されます。
  2. 実際の問題内で関連しないコーディングスタイルの変更(他のメソッド、ブロックのコード、コメントなど)は、マスターにのみ、別のコミットで許可されます。
  3. コーディングスタイルのみの問題は、各サイクルの最初の2か月間に限り、マスターにのみ受け入れられます。

Gitのコミット

クリアで分かりやすいコミットを作成することは、オープンソースのコード作成の重要な側面であり、コミット履歴は開発者間のコミュニケーションの重要な部分です。適切なコミットを作成するために時間をかけ、gitのツールを使用することが重要です。

Gitのコミットは以下のようにする必要があります:

  • コードが完璧に書かれた初回のような、完全で整理されたバージョンの履歴を表すこと。
  • 変更に関連するMDL-xxxxの問題番号を含めること。
  • 適切な場合にはCODE AREAを含めること。(Code areaとは、この変更が影響するMoodleの領域の短い名前です。コンポーネント名であっても構いませんが、そうである必要はありません。ここでの対象はコンピュータではなく人間であることに注意してください。コンポーネント名の省略形がより読みやすくて識別可能である場合は、そちらを使用してください。)
  • 以下の形式でフォーマットすること:
MDL-xxxx CODE AREA: 短い要約(72文字の制限)

2行目には空白行を挿入し、必要に応じて無制限の詳細な説明を続けます。このセクションには、変更の動機や以前の動作との対比が含まれる場合があります。

Gitのコミットには、以下のようなものは含めないでください:

  • 統合前に見つかったバグの修正内容
  • 1つの問題に対して同じコード行の多数の別々の修正を含める
  • 論理的に1つのセットとして扱うべき変更を、恣意的に分割する

詳細については、コミットチートシートを参照してください。

クレジット

このドキュメントは以下のソースから引用されています:

  1. オリジナルのコーディングガイドラインページ
  2. Zendのガイドライン
  3. 全てのMoodleコア開発者からのフィードバック

関連項目