Si tu veux participer au développement de WP Staging, familiarise-toi avec les directives de codage et les bonnes pratiques suivantes.
- Utilise PSR https://www.php-fig.org/psr/.
- Utilise la syntaxe courte des tableaux [].
- Utilise le camelCase pour les noms de variables.
- Utilise les StudlyCaps pour les noms de classes.
- Utilise les underscores dans les noms de fichiers et de dossiers.
- Évite les conditions inline.
- Utilise rarement les abréviations ! N’utilise aucune abréviation qui n’a pas été approuvée par l’équipe et n’invente pas tes propres abréviations qui ne sont pas couramment populaires lors du nommage des propriétés ou méthodes.
- Les noms de classes, méthodes, propriétés doivent expliquer exactement leur objectif.
Clean Code
- Le coût total de maintenance d’un code désorganisé s’accumule avec le temps.
- Il est très difficile de reconstruire un système legacy depuis zéro. La refactorisation et les améliorations incrémentales sont souvent la meilleure voie.
- Dans les bases de code désorganisées, des tâches qui ne devraient prendre que quelques heures peuvent prendre des jours ou des semaines.
- Prends le temps d’aller vite.
- Le code propre fait bien une chose. Le mauvais code essaie d’en faire trop.
- Le code propre est bien testé.
- En lisant du code bien écrit, chaque fonction fait à peu près ce à quoi tu t’attendais.
- Si tu n’es pas d’accord avec un principe enseigné par quelqu’un ayant des décennies d’expérience, tu ferais bien d’au moins considérer son point de vue avant de le rejeter.
- Le code est lu bien plus souvent qu’il n’est écrit.
- Le code plus facile à lire est plus facile à modifier.
- Laisse la base de code dans un meilleur état que tu ne l’as trouvée (La règle du Boy Scout).
Commentaires et docBlocks
- Les commentaires peuvent mentir. Ils peuvent être incorrects dès le départ, ou être initialement précis puis devenir obsolètes à mesure que le code associé évolue.
- Utilise les commentaires pour décrire pourquoi quelque chose est écrit d’une certaine façon, et non pour expliquer ce qui se passe.
- Les commentaires peuvent souvent être évités en utilisant des variables clairement nommées et en extrayant des sections de code dans des fonctions clairement nommées.
- Préfixe tes commentaires TODO de manière cohérente pour les retrouver plus facilement. Révise et nettoie tes commentaires TODO périodiquement.
- N’utilise pas les docBlocks juste pour les utiliser. Les commentaires décrivant ce que fait une méthode, quels arguments elle prend et ce qu’elle retourne sont souvent redondants au mieux et trompeurs au pire.
- Les commentaires doivent inclure toutes les informations et le contexte pertinents dont a besoin quelqu’un lisant le commentaire. Ne sois pas paresseux ou vague quand tu écris un commentaire.
- Les commentaires de journal et les commentaires d’auteur de fichier sont inutiles grâce au contrôle de version et git blame.
- Ne commente pas le code mort. Supprime-le simplement. Si tu penses que tu en auras besoin à l’avenir, c’est à ça que sert le contrôle de version.
- Commente autant que nécessaire, mais aussi peu que possible. Si tu ressens une forte pression pour écrire un commentaire pour ta méthode, c’est souvent que le nom de ta méthode n’est pas assez clair ou que le code fait plus d’une chose. Dans ce cas, envisage une refactorisation avant d’écrire un commentaire.
Style de code
Espaces autour des opérateurs binaires
Les opérateurs binaires ‘=’ et ‘=>’ doivent être entourés d’espaces. Il existe une option d’autoformat dans les paramètres de style de code de l’IDE qui te permet d’aligner les assignations clé-valeur comme ceci :
$array = [
$var => 'foo',
$varvar => 'foo'
];
$var = 1;
$var100 = 100;
$var2000 = 2000;
C’est une astuce pratique pour rendre de grandes portions de code similaire plus lisibles.
Conditions Yoda
Nous avons voté contre l’utilisation des conditions Yoda pour faciliter la lisibilité.
Non recommandé :
if ( true === $var ) {}
Recommandé :
if ( $var === true ) {}
Invocation de fonctions/constantes natives
L’invocation native est une technique consistant à ajouter un backslash (\) avant l’invocation d’une fonction/constante pour accélérer la résolution. Ainsi PHP n’a pas besoin de vérifier si la fonction/constante provient du namespace ou est native.
Nous avons voté contre l’utilisation de la technique d’invocation native pour faciliter la lisibilité et éviter les erreurs dans notre base de code.
Mais dans certains cas, il est permis de l’utiliser avec soin et discernement.
Non recommandé :
if ( \is_array($var) ) {}
if ( \PHP_SAPI === 'cli') {}
Recommandé :
if ( is_array($var) ) {}
if ( PHP_SAPI === 'cli') {}
Namespaces et noms de classes
Selon les principes de la Programmation Orientée Objet (POO), les noms de classes doivent être des noms communs, car ils représentent des objets ou des concepts dans le système. Cela aide à rendre le code plus lisible et compréhensible pour les autres développeurs.
Cependant, il convient de noter que certains langages de programmation, dont PHP, permettent d’utiliser des verbes comme noms de classes. Dans ces cas, le verbe est généralement utilisé pour indiquer que la classe représente une action ou un comportement plutôt qu’un objet.
Par exemple, une classe nommée « Mailer » peut représenter un objet qui envoie des e-mails, tandis qu’une classe nommée « SendMail » peut représenter un comportement qui envoie des e-mails. Bien que l’utilisation de verbes comme noms de classes soit techniquement permise, cela peut rendre le code plus difficile à lire et comprendre, et est généralement déconseillé au profit des noms communs.
- Seuls les caractères a-z, A-Z et 0-9 sont autorisés pour les noms de namespace et de classe.
- Les namespaces sont généralement écrits en UpperCamelCase, mais des variations sont permises pour les noms et abréviations bien établis.
- Les noms de classes sont toujours écrits en
UpperCamelCase. - Le nom de classe non qualifié doit avoir un sens même sans le namespace.
- L’objectif principal des namespaces est la catégorisation et l’organisation.
- Les noms de classes doivent être des noms communs, jamais des adjectifs.
- Le nom des classes abstraites doit commencer par le mot « Abstract », les noms de classes d’aspects doivent se terminer par le mot « Aspect ».
Nommage incorrect des namespaces et classes :
| Fully qualified class name | Unqualified name | Remarks |
|---|---|---|
| WPStaging\Framework\Session\Php | Php | The class is not a representation of PHP |
| WPStaging\Framework\Cache\Backend\File | File | The class doesn’t represent a file! |
| WPStaging\Framework\Session\Interface | Interface | Not allowed, « Interface » is a reserved keyword |
| WPStaging\Framework\Controller\Default | Default | Not allowed, « Default » is a reserved keyword |
| WPStaging\Framework\Objects\Manager | Manager | Just « Manager » is too fuzzy |
Nommage correct des namespaces et classes :
| Fully qualified class name | Unqualified name | Remarks |
|---|---|---|
| WPStaging\Framework\Util\FileSystem | FileSystem | That’s the FileSystem |
| WPStaging\Framework\Cache\Backend\FileBackend | FileBackend | A File Backend |
| WPStaging\Framework\Session\SessionInterface | SessionInterface | Interface for a session |
| WPStaging\Framework\StandardController | StandardController | The standard controller |
| WPStaging\Framework\ObjectManager | ObjectManager |
Cas limites dans le nommage des namespaces et classes :
| Fully qualified class name | Unqualified name | Remarks |
|---|---|---|
| WPStaging\Framework\Mvc\ControllerInterface | ControllerInterface | Consequently the interface belongs to all the controllers in the Controller sub namespace |
| WPStaging\Framework\Mvc\Controller\ControllerInterface | Better | |
| WPStaging\Framework\Cache\AbstractBackend | AbstractBackend | Same here: In reality this class belongs to the backends |
| WPStaging\Framework\Cache\Backend\AbstractBackend | Better |
Méthodes
Les noms de méthodes doivent clairement décrire ce qu’elles font, donc ils doivent commencer par un verbe comme doSomething, makeSomething, isSomething, hasSomething.
Tous les noms de méthodes sont écrits en lowerCamelCase. Pour éviter les problèmes avec différents systèmes de fichiers, seuls les caractères a-z, A-Z et 0-9 sont autorisés pour les noms de méthodes — n’utilise pas de caractères spéciaux.
Rends les noms de méthodes descriptifs, mais concis en même temps. Les constructeurs doivent toujours s’appeler __construct(), n’utilise jamais le nom de la classe comme nom de méthode.
myMethod()
someNiceMethodName()
betterWriteLongMethodNamesThanNamesNobodyUnderstands()
singYmcaLoudly()
__construct()
Propriétés & variables
Une variable doit être un nom commun ou un adjectif et jamais un verbe. Elle stocke quelque chose et doit expliquer ce qu’elle contient.
N’utilise pas le mot-clé getSomething pour une propriété. Le get est réservé pour les getters et setters et pour les méthodes qui font explicitement quelque chose.
Les noms de variables sont écrits en lowerCamelCase et doivent être :
- Auto-explicatifs.
- Pas raccourcis au-delà de la reconnaissance, mais plutôt plus longs si cela rend leur signification plus claire.
L’exemple suivant montre deux variables avec la même signification mais un nommage différent. Tu seras sûrement d’accord que les versions plus longues sont meilleures.
Bon nommage de variables
$singletonObjectsRegistry
$argumentsArray
$aLotOfHtmlCode
renderHTMLtoScreen
Mauvais nommage de variables
$sObjRgstry
$argArr
$cx
Par exception, tu peux utiliser des noms de variables comme $i, $j et $k pour les index numériques dans les boucles for si leur signification est claire au premier regard. Mais tu devrais quand même essayer de les éviter.
i18n, sprintf(), esc_html_* et gettext()
Utilise toujours d’abord les fonctions gettext() et enveloppe-les dans sprintf() quand il y a des paramètres dans une chaîne traduisible.
Incorrect :
esc_html_e(sprintf('There are %1$d monkeys in the %2$s'), $number, $string), 'text-domain');
Correct :
// 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 ) );
Si tu utilises printf ou sprintf, les guillemets simples (‘) autour de la chaîne sont obligatoires car les guillemets doubles (« ) indiqueraient à PHP d’interpréter $s comme la variable s, ce que nous ne voulons pas.
Pour standardiser avec l’outil de traduction wporg, il doit inclure un espace réservé pour le traducteur.
/* 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));
En savoir plus : https://developer.wordpress.org/plugins/internationalization/how-to-internationalize-your-plugin/#variables
Conditions If Else
Évite les conditions inline si elles nécessitent des parenthèses supplémentaires et des instructions if else ou ont plus de plusieurs états à comparer.
Sinon, il est bien de les écrire inline ou dans des conditions de retour anticipé séparées.
Mauvais :
return ((!$this->isWindowsOs() && is_executable($fileName))) && is_writable($fileName) || ($this->isWindowsOs()) && is_writable($fileName);
Bon :
if (!$this->isWindowsOs && is_executeable && is_writeable()) {
return true;
}
if ($this->isWindowsOs && is_writeable()) {
return true;
}
return false;
Actions et filtres
- Utilise une constante pour déclarer le nom du filtre, le nom de la constante doit respecter le schéma
FILTER_*. - Commence toujours un nom de filtre par
wpstg, fais de la sémantique avec des points commewpstg.backups.listing_tableoùlisting_tableest le nom de la méthode où cette action est utilisée.
Par exemple :
// Declare const for filter const FILTER_CLONING_UPDATE_ACTIVE_PLUGINS_FILTER = 'wpstg.cloning.update.active_plugins'
puis
apply_filters(self::CLONING_UPDATE_ACTIVE_PLUGINS_FILTER, $activePlugins);
Stocker des données dans wp_options
- Utilise une constante pour déclarer le nom de l’option, le nom de la constante doit respecter le schéma
OPTION_*. - Commence toujours un nom d’option de table par
wpstg, sépare les mots avec des underscores commewpstg_backup_database_settings. N’oublie pas d’ajouter la nouvelle option dans uninstall.php
Mauvais :
/**
* The option that stores the staging sites
*/
const STAGING_SITES_OPTION = 'wpstg_staging_sites';
Bon :
/**
* The option that stores the staging sites
*/
const OPTION_STAGING_SITES = 'wpstg_staging_sites';
Utiliser WPStaging*\FileObject au lieu de SplFileObject
- Utilise WPStaging\Framework\Filesystem\FileObject au lieu de SplFileObject pour un comportement cohérent de
seek()etfgets()sur toutes les versions PHP jusqu’à 8.0.1. - Utilise
readAndMoveNext()au lieu defgets()aprèsfseek()pour un comportement cohérent sur toutes les versions PHP jusqu’à PHP 8.0.1.
Gestion des chemins
- Utilise toujours l’une des constantes existantes comme
WPSTG_PLUGIN_DIRouWPSTG_PLUGIN_URLlors de la manipulation des chemins. - Utilise toujours le slash avant (/) et jamais
DIRECTORY_SEPARATOR. Le slash avant est compatible avec Linux et Windows, tandis que le slash arrière (\) ne fonctionne que sur Windows. Cela réduit la complexité, rend le code plus lisible et évite les problèmes inattendus dans les environnements hôtes mixtes ou lors de la migration de données de Linux vers Windows ou vice versa. - Utilise la fonction wp_normalize_path si nécessaire pour remplacer un slash arrière (\) par un slash avant (/).