Se queres participar no desenvolvimento do WP Staging, familiariza-te com as seguintes diretrizes de programação e melhores práticas.
Clean Code
Comentários e docBlocks
Estilo de código
Espaços em operadores binários
Os operadores binários ‘=’ e ‘=>’ devem estar rodeados por espaço. Há uma opção de autoformat nas definições de estilo de código do IDE que te permite alinhar atribuições key-value assim:
$array = [
$var => 'foo',
$varvar => 'foo'
];
$var = 1;
$var100 = 100;
$var2000 = 2000;
Este é um truque elegante para tornar maiores porções de código semelhante mais legíveis.
Yoda conditions
Votámos para não usar Yoda conditions para facilidade de leitura.
Não recomendado:
if ( true === $var ) {}
Recomendado:
if ( $var === true ) {}
Invocação nativa de funções/constantes
A invocação nativa é uma técnica para adicionar uma barra invertida (\) antes da invocação de funções/constantes para acelerar a resolução. Desta forma, o PHP não precisa de verificar se a função/constante é do namespace ou nativa.
Votámos para não usar a técnica de invocação nativa de funções/constantes para facilidade de leitura e evitar erros na nossa codebase.
Mas, em alguns casos, é permitido usar com cuidado e sabedoria.
Não recomendado:
if ( \is_array($var) ) {}
if ( \PHP_SAPI === 'cli') {}
Recomendado:
if ( is_array($var) ) {}
if ( PHP_SAPI === 'cli') {}
Namespaces e nomes de classes
De acordo com os princípios da Programação Orientada a Objetos (OOP), os nomes de classes devem ser substantivos, pois representam objetos ou conceitos no sistema. Isto ajuda a tornar o código mais legível e compreensível para outros programadores.
No entanto, vale a pena referir que algumas linguagens de programação, incluindo o PHP, permitem que verbos sejam usados como nomes de classes. Nestes casos, o verbo é geralmente usado como forma de indicar que a classe representa uma ação ou comportamento em vez de um objeto.
Por exemplo, uma classe chamada “Mailer” pode representar um objeto que envia emails, enquanto uma classe chamada “SendMail” pode representar um comportamento que envia emails. Embora seja tecnicamente permitido usar verbos como nomes de classes, isso pode tornar o código mais difícil de ler e perceber, e geralmente é desencorajado em favor do uso de substantivos.
Nomeação incorreta de namespaces e classes:
| Nome completo da classe | Nome não qualificado | Observações |
|---|---|---|
| WPStaging\Framework\Session\Php | Php | A classe não é uma representação de PHP |
| WPStaging\Framework\Cache\Backend\File | File | A classe não representa um ficheiro! |
| WPStaging\Framework\Session\Interface | Interface | Não permitido, “Interface” é uma palavra-chave reservada |
| WPStaging\Framework\Controller\Default | Default | Não permitido, “Default” é uma palavra-chave reservada |
| WPStaging\Framework\Objects\Manager | Manager | Apenas “Manager” é demasiado vago |
Nomeação correta de namespaces e classes:
| Nome completo da classe | Nome não qualificado | Observações |
|---|---|---|
| WPStaging\Framework\Util\FileSystem | FileSystem | É o FileSystem |
| WPStaging\Framework\Cache\Backend\FileBackend | FileBackend | Um File Backend |
| WPStaging\Framework\Session\SessionInterface | SessionInterface | Interface para uma sessão |
| WPStaging\Framework\StandardController | StandardController | O controlador padrão |
| WPStaging\Framework\ObjectManager | ObjectManager |
Casos limite na nomeação de namespaces e classes:
| Nome completo da classe | Nome não qualificado | Observações |
|---|---|---|
| WPStaging\Framework\Mvc\ControllerInterface | ControllerInterface | Consequentemente, a interface pertence a todos os controladores no sub-namespace Controller |
| WPStaging\Framework\Mvc\Controller\ControllerInterface | Melhor | |
| WPStaging\Framework\Cache\AbstractBackend | AbstractBackend | O mesmo aqui: na realidade esta classe pertence aos backends |
| WPStaging\Framework\Cache\Backend\AbstractBackend | Melhor |
Métodos
Os nomes dos métodos devem descrever claramente o que fazem, por isso devem começar com um verbo como doSomething, makeSomething, isSomething, hasSomething.
Todos os nomes de métodos são escritos em lowerCamelCase. Para evitar problemas com diferentes sistemas de ficheiros, apenas os caracteres a-z, A-Z e 0-9 são permitidos para nomes de métodos — não uses caracteres especiais.
Faz os nomes de métodos descritivos, mas mantém-nos concisos ao mesmo tempo. Os construtores devem sempre chamar-se __construct(), nunca uses o nome da classe como nome de método.
myMethod()
someNiceMethodName()
betterWriteLongMethodNamesThanNamesNobodyUnderstands()
singYmcaLoudly()
__construct()
Propriedades e variáveis
Uma variável deve ser um substantivo ou adjetivo, nunca um verbo. Armazena algo e deve explicar o que contém.
Não uses a palavra-chave getSomething para uma propriedade. O get está reservado para getters e setters e para métodos que explicitamente fazem algo e onde não há melhor palavra-chave do que get.
Os nomes de variáveis são escritos em lowerCamelCase e devem ser:
O exemplo seguinte mostra duas variáveis com o mesmo significado, mas com nomes diferentes. Vais certamente concordar que as versões mais longas são melhores (não vais…?).
Boa nomeação de variáveis
$singletonObjectsRegistry
$argumentsArray
$aLotOfHtmlCode
renderHTMLtoScreen
Má nomeação de variáveis
$sObjRgstry
$argArr
$cx
Como exceção especial, podes usar nomes de variáveis como $i, $j e $k para índices numéricos em ciclos for, se for claro o que significam à primeira vista. Mas mesmo nesses casos, deves tentar evitá-los.
i18n, sprintf(), esc_html_* e gettext()
Usa sempre primeiro as funções gettext() e envolve-as em sprintf() quando houver parâmetros numa string traduzível.
Errado:
esc_html_e(sprintf('There are %1$d monkeys in the %2$s'), $number, $string), 'text-domain');
Correto:
// Correct (multi-line): sprintf( /* translators: number of monkeys, location. */ __( 'There are %1$d monkeys in the %2$s', 'text-domain' ), (int) $number, esc_html( $string ) ); // Correct (single-line): /* translators: number of monkeys, location. */ printf( __( 'There are %1$d monkeys in the %2$s', 'text-domain' ), intval( $number ), esc_html( $string ) );
Se usares printf ou sprintf, as aspas simples (‘) à volta da string são obrigatórias, porque as aspas duplas (“) indicam ao php para interpretar o $s como a variável s, o que não é o pretendido.
Para uniformizar com a ferramenta de tradução wporg, tem de incluir um placeholder para o tradutor.
/* translators: %s: name */
sprintf(esc_html__('string %s to translate', 'text-domain'), esc_html($string));
/* translators: %1$s = name1, %2$s = name2 */
sprintf(esc_html__('string %1$s to translate for %2$s', 'text-domain'), esc_html($string1), esc_html($string2));
Condições If Else
Evita condições inline se exigirem parênteses extra e instruções if-else, ou se tiverem mais do que vários estados a comparar.
Caso contrário, está tudo bem escrevê-las inline ou em condições separadas de early return.
Mau:
return ((!$this->isWindowsOs() && is_executable($fileName))) && is_writable($fileName) || ($this->isWindowsOs()) && is_writable($fileName);
Bom:
if (!$this->isWindowsOs && is_executeable && is_writeable()) {
return true;
}
if ($this->isWindowsOs && is_writeable()) {
return true;
}
return false;
Actions e Filters
Por exemplo:
// Declare const for filter const FILTER_CLONING_UPDATE_ACTIVE_PLUGINS_FILTER = 'wpstg.cloning.update.active_plugins'
e depois
apply_filters(self::CLONING_UPDATE_ACTIVE_PLUGINS_FILTER, $activePlugins);
Guardar dados em wp_options
Mau:
/**
* The option that stores the staging sites
*/
const STAGING_SITES_OPTION = 'wpstg_staging_sites';
Bom:
/**
* The option that stores the staging sites
*/
const OPTION_STAGING_SITES = 'wpstg_staging_sites';