Normas para o desenvolvimento do código de Moodle

Qualquer projeto colaborativo necessita de consistência e estabilidade para permanecer fortalecido.

Essas normas são um objetivo a ser alcançado por todo o código do Moodle. É verdade que existem algumas áreas com falha nos códigos antigos, mas que estas serão corrigidas aos poucos. Todo código novo deve seguir essas normas.

Regras Gerais

  1. Todos os arquivos de código devem usar a estensão .php.
  2. Todos os arquivos de modelo (template) devem usar a estensão .html.
  3. Todos os arquivos de texto devem usar a formatação de texto do estilo Unix (a maioria dos editores de texto possuem essa opção).
  4. Todos os tags php devem ser completos como <?php ?> ... e não abreviado como <? ?>.
  5. Todas as notas de direitos autorais (copyright) devem ser mantidas. Você pode adicionar as suas caso seja necessário..
  6. Cada arquivo deve incluir o arquivo conifg.php principal.
  7. Cada arquivo deve verificar se o usuário está autenticado corretamente, usando require_login() e isadmin(), isteacher(), iscreator() ou isstudent().
  8. Todos os acessos a bases de dados devem usar as funções em lib/datalib.php quando possível - isto permitirá a compatibilidade por entre os vários tipos de base de dados. Você verá que quase tudo é possível usando essas funções. Se você necessita escrever seu próprio código SQL então faça em modo que ele seja: multi-plataforma, restrito a funções específicas dentro de seu código (geralmente um arquivo lib.php) e cometado em modo claro.
  9. Não crie ou use variáveis globais exceto para os padrões $CFG, $SESSION, $THEME and $USER.
  10. Todas as variáveis devem ser inicializadas ou ao menos ter sua existência verificada usando isset() ou empty() antes de serem utilizadas.
  11. Todos os textos (strings) devem ser passíveis de tradução - crie novas entradas de texto nos arquivos em "lang/en" usando nomes em Inglês conciso e em caixa baixa e recupere-os em seu código usando get_string() ou print_string().
  12. Todos os arquivos de ajuda devem ser passíveis de tradução - crie os novos textos no diretório "en/help" directory e se refira a eles usando helpbutton().

    Caso você precise atualizar um arquivo de ajuda:

  13. Os dados originados via navegador (enviados via GET ou POST) automaticamente tem o magic_quotes aplicado (independentemente da configuração do PHP). Todos os outros dados brutos (de arquivos ou de base de dados) devem ser utilizaods com addslashes() antes de serem inseridos nas base de dados.
  14. IMPORTANTE: Todos os textos dentro do Moodle, especialmente aqueles que se originam dos usuários, devem ser impressos usando a função format_text(). Isto assegura que o texto está filtrado e devidamente limpo.

 

Estilo de redação de código

Eu sei que é chato mudar o seu estilo se você está acostumado a outro, mas pondere isso com o aborrecimento de todas as pessoas que tentam dar sentido ao código do Moodle com estilos variados. Obviamente há prós e contras em qalquer estilo que você use, mas o estilo atual simplesmente é este, por favor respeite-o.

  1. Indentação deve ser consistente de 4 espaços. Não use tab DE FORMA ALGUMA.
  2. Nomes de váriaveis devem ser fáceis de ler, ter significado e usar termos em Inglês em caixa baixa. Se você necessita usar mais de uma palavra então coloque tudo junto sem espaços, mas tente ser o mais breve possível. Use nomes plurais para arrays de objetos.

    CORRETO: $quiz
    CORRETO: $errorstring
    CORRETO: $assignments (for an array of objects)
    CORRETO: $i (but only in little loops)

    ERRADO: $Quiz
    ERRADO: $aReallyLongVariableNameWithoutAGoodReason
    ERRADO: $error_string

  3. Constantes devem ser sempre em caixa alta, e iniciar com o nome do módulo. Eles devem ter sempre as palavras separadas por traço baixo (underscore).

    define("FORUM_MODE_FLATOLDEST", 1);

  4. Nomes de funções devem ser sempre palavras em Inglês e em caixa baixa, e começar com o nome do módulo para evitar conflitos entre os módulos. As palavras devem ser separadas por traço baixo. Parâmetros devem ser padronizados na medida do possível. Observe que não há espaços entre o nome da função e o parentêses seguinte.

    function forum_set_display_mode($mode=0) {
        global
    $USER, $CFG;

        if (
    $mode) {
            
    $USER->mode = $mode;
        } else if (empty(
    $USER->mode)) {
            
    $USER->mode = $CFG->forum_displaymode;
        }
    }

  5. Blocos devem ser sempre fechados entre chaves (even if there is only one line)mesmo que seja só uma linha. Moodle usa esse estilo:

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

  6. Strings devem ser definidos por aspas simples na medida do possível, para aumentar a velocidade.

    $var = 'texto sem variáveis';
    $var = "com caracteres especiais como uma nova linha \n";
    $var = 'muito longa com uma '.$single.' variável';
    $var = "pouco $text com $many variáveis $within ";

  7. Commentários devem ser úteis e práticos para explicar a estrutura do código e a lógica das funções e das variáveis.

    /**
    * Descrição primeiro, com asteriscos posicionados em ordem
    * como neste exemplo. para referir-se a uma outra função,
    * faça isto: {@link clean_param()}. Depois acrescente descrições
    * para cada parâmetro como em seguida.
    *
    * @param int $postid The PHP type is followed by the variable name
    * @param array $scale The PHP type is followed by the variable name
    * @param array $ratings The PHP type is followed by the variable name
    * @return mixed
    */

    function forum_get_ratings_mean($postid, $scale, $ratings=NULL) {
        if (!$ratings) {
            
    $ratings = array();     // Initialize the empty array
            if (
    $rates = get_records("forum_ratings", "post", $postid)) {
                
    // Process each rating in turn
                foreach (
    $rates as $rate) {
    ....etc

  8. Espaço deve ser usado livremente - não tenha medo de expandir as coisas um pouco para ganhar clareza. Geralmente, deve haver um ou dois espaços entre os parentêses e as declarações normais, mas não há espaço entre os parentêses e variáveis ou funções:

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

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

 

Estrutura da base de dados

  1. Cada tabela deve ter um campo id (INT10) auto-incremental como index primário.
  2. A tabela principal contendo instâncias de cada módulo deve ter o mesmo nome que o módulo (ex. widget) e conter no mínimo os seguintes campos:
  3. Outras tabelas associadas com o módulo que contém informações sobre 'coisas' devem ser nomeadas como widget_things (note o plural).
  4. Nomes de colunas devem ser simples e curtas, valendo as mesmas regras para os nomes de variáveis.
  5. Quando possível, colunas que contém referência ao campo id de outra tabela (ex. widget) devem ser nomeadas como widgetid. (observe que essa convenção é recente e não foi utilizada em algumas tabelas antigas)
  6. Campos booleanos devem ser implementados como campos small integer (ex. INT4) contendo 0 ou 1, para permitir uma expansão futura dos valores, caso se torne necessário.
  7. A maior parte das tabelas deve conter um campo timemodified (INT10) que é atualizado com timestamp (rótulo de tempo) obtido com a função do PHP time() .

 

Security Issues (and handling form and URL data)

  1. Do not rely on 'register_globals'. Every variable must be properly initialised in every code file. It must be obvious where the variable came from
  2. Initialise all arrays and objects, even if empty. $a = array() or $obj = new stdClass();.
  3. Do not use the optional_variable() function. Use the optional_param() function instead. Pick the correct PARAM_XXXX value for the data type you expect. To check and set an optional value for a variable, use the set_default() function.
  4. Do not use the require_variable() function. Use the required_param() function instead. Pick the correct PARAM_XXXX value for the data type you expect.
  5. Use data_submitted(), with care. Data must still be cleaned before use.
  6. Do not use $_GET, $_POST or $_REQUEST. Use the appropriate required_param() or optional_param() appropriate to your need.
  7. Do not check for an action using something like if (isset($_GET['something'])). Use, e.g., $something = optional_param( 'something',-1,PARAM_INT ) and then perform proper test for it being in its expected range of values e.g., if ($something>=0) {....
  8. Wherever possible group all your required_param(), optional_param() and other variables initialisation at the beginning of each file to make them easy to find.
  9. Use 'sesskey' mechanism to protect form handling routines from attack. Basic example of use: when form is generated, include <input type="hidden" name="sesskey" value="<?php echo sesskey(); ?>" />. When you process the form check with if (!confirm_sesskey()) {error('Bad Session Key');}.
  10. All filenames must be 'cleaned' using the clean_filename() function, if this has not been done already by appropriate use of required_param() or optional_param()
  11. Any data read from the database must have addslashes() applied to it before it can be written back. A whole object of data can be hit at once with addslashes_object().
  12. Wherever possible, data to be stored in the database must come from POST data (from a form with method="POST") as opposed to GET data (ie, data from the URL line).
  13. Do not use data from $_SERVER if you can avoid it. This has portability issues.
  14. If it hasn't been done somewhere else, make sure all data written to the database has been through the clean_param() function using the appropriate PARAM_XXXX for the datatype.
  15. If you write custom SQL code, make very sure it is correct. In particular watch out for missing quotes around values. Possible SQL 'injection' exploit.
  16. Check all data (particularly that written to the database) in every file it is used. Do not expect or rely on it being done somewhere else.
  17. Blocks of code to be included should contain a definite PHP structure (e.g, a class declaration, function definition(s) etc.) - straight blocks of code promote uninitialised variable usage.

Moodle Documentation

Version: $Id$