Віджети WordPress: починаючи зі стандартів
Мета цієї серії — почати глибше занурюватися в роботу з об’єктно-орієнтованим програмуванням у контексті WordPress.
І оскільки WordPress Widgets API є одним із API, який використовує об’єктно-орієнтовані практики, це логічне місце для початку. Крім того, це дасть нам деякі базові прийоми, які ми можемо використовувати для подальшої роботи, коли побачимо, як створювати більше об’єктно-орієнтованих проектів на WordPress у майбутніх серіалах.
Наразі ми розглянули наступне:
- Віджети WordPress: об’єктно-орієнтований підхід. Widgets API є надійним лакмусовим папірцем і прикладом того, як почати роботу з об’єктно-орієнтованим програмуванням у WordPress.
- Віджети WordPress: як виявити об’єктно-орієнтоване програмування. Мета полягає в тому, щоб озброїти вас усім необхідним для виявлення об’єктно-орієнтованих практик.
Якщо ви не наздогнали, зараз чудовий час це зробити. І якщо у вас є, то ви пам’ятаєте, з останнього допису ми закінчили такою приміткою:
Тобто ми переглянемо шаблон віджетів WordPress, і я збираюся відредагувати його в його поточному стані, щоб прийняти більш сучасні стандарти PHP.
Щоб розпочати оновлення WordPress Widget Boilerplate відповідно до зазначених стандартів, нам потрібно зробити кілька речей:
- створити відгалуження від існуючого шаблону,
- встановити інструменти якості коду,
- переконайтеся, що наша IDE правильно налаштована,
- і почати рефакторинг коду відповідно до зазначених стандартів.
І це те, що ми збираємося почати робити з цієї публікації.
Починаючи зі стандартів
Якщо ви були учасником цього сайту протягом деякого часу, то ви знаєте, що я віддаю перевагу використанню Visual Studio Code. Якщо ні, у мене є цілий набір статей, присвячених тому, як я його використовую (і, отже, як ми будемо використовувати його в цій серії публікацій).
А якщо вас цікавить інформація про стандарти кодування, налагодження, IDE, середовища розробки тощо, ознайомтеся з The Independent WordPress Developer.
Однак я припускаю, що якщо ви читаєте це, ви прочитали матеріал вище або вам зручно переглядати весь матеріал вище.
З огляду на це, давайте почнемо.
Завантаження репозиторію
Перше, що ви захочете зробити, це клонувати копію репозиторію. Я вважаю за краще робити це за допомогою командного рядка.
Крім того, я також вважаю, що варто робити це проти останньої версії WordPress. Якщо у вас немає копії магістральної копії WordPress Subversion, ви можете прочитати, як це налаштувати тут; однак це необов’язково. Ви можете виконувати решту цього підручника з будь-якою версією WordPress, яку хочете.
Робити так,
- Переконайтеся, що ви перебуваєте в каталозі плагінів вашої інсталяції WordPress
- А потім введіть наступні команди в копію вашого терміналу
$
Це створить каталог WordPress-Widget-Boilerplate у вашому каталозі плагінів. Ви можете перейти до нього, просто ввівши:
$ cd WordPress-Widget-Boilerplate
Результати клонування сховища мають виглядати приблизно так:
Далі вам потрібно переконатися, що ви перейшли на гілку розробки, яку я створив. Зробити це дуже просто. Але перш ніж ми це зробимо, чому б не налаштувати проект у Visual Studio?
Налаштування коду Visual Studio
Кроки для налаштування проекту в Visual Studio Code прості:
- Перетягніть каталог для Boilerplate в IDE,
- Відкрийте вбудований термінал,
- Поміняти гілки
Так само, як я робив вище, я запропоную скрінкаст того, як усе це зробити. Перетягнути каталог у код Visual Studio має бути досить легко, але заміна гілок у командному рядку може бути дещо іншою.
По-перше, налаштування проекту в Visual Studio Code:
Зверніть увагу, що я також відкриваю інтегрований термінал, натискаючи комбінацію клавіш CMD+P (у мене macOS, тому ваша комбінація клавіш може бути іншою). Потім я вводжу команду перевірки гілки розробки.
Після цього ваш локальний репозиторій має перейти до гілки розробки. Ви можете підтвердити, що це гілка, з якою ви працюєте, ввівши:
$ git branch
А потім перегляньте вміст терміналу. Власне кажучи, слід виділити розвивати .
На цьому етапі ми збираємося ввести кілька нових файлів у проект. Наприкінці цього підручника ви можете сформувати залучення, щоб отримати все, що я збираюся тут задокументувати. Але оскільки мета того, що ми робимо, двояка, важливо переконатися, що ми робимо це в правильній послідовності, тому що перший крок — це те, що я використовую в кожному окремому проекті для WordPress на цьому етапі.
Отже, з цим сказаним, давайте подивимось.
Композитор і якість коду
Перше, що мені подобається робити, це налаштовувати ряд інструментів для забезпечення якості коду. Це досягається за допомогою різноманітних пакетів Composer. До них належать:
- GrumPHP. Інструмент для підвищення якості коду PHP. Не варто недооцінювати роз’яснення та ступінь заповненості цього сховища інформацією. Якщо ви коли-небудь зіткнетеся з будь-яким із згаданих тут інструментів, спочатку перегляньте документацію в цьому репозиторії.
- PHP CS Fixer. Інструмент для автоматичного вирішення проблем зі стандартами кодування PHP.
- PHP Parallel Lint. Цей інструмент перевіряє синтаксис PHP-файлів швидше, ніж послідовна перевірка, з вишуканішим результатом.
- PHPMD. Ця утиліта бере задану базу вихідного коду PHP і шукає кілька потенційних проблем у цьому джерелі
- Парсер PHP. Синтаксичний аналізатор корисний для статичного аналізу, маніпулювання кодом і, в основному, для будь-якої іншої програми, що працює з кодом програмно.
- Менеджер проксі. Ця бібліотека має на меті забезпечити абстракцію для генерації різних видів проксі-класів.
Я хочу пояснити дві речі:
- Наведені вище інструменти — це мінімум, який я використовую, і ви, ймовірно, побачите, що я використовую додаткові інструменти в майбутньому,
- інструменти вище допоможуть забезпечити дотримання правил якості коду перед перевіркою коду в репозиторій. Це доповнює налаштування у вашому IDE.
Щоб налаштувати та запустити ці інструменти в проекті, нам потрібно створити файл composer.json, який виглядає так :
{
"name": "wordpress-widget-boilerplate/wordpress-widget-boilerplate",
"description": "An organized, maintainable boilerplate for building widgets using WordPress best practices.",
"type": "wordpress-plugin",
"license": "GPL-3.0-or-later",
"homepage": "https://github.com/tommcfarlin/WordPress-Widget-Boilerplate",
"authors": [
{
"name": "Tom McFarlin",
"email": "tom@pressware.co",
"homepage": "https://pressware.co"
}
],
"support": {
"issues": "https://github.com/tommcfarlin/WordPress-Widget-Boilerplate/issues"
},
"config": {
"preferred-install": "dist",
"platform": {
"php": "7.1"
}
},
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
}
],
"require": {
"php": "7.1",
"composer/installers": "^1.4"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.13.1",
"jakub-onderka/php-parallel-lint": "^1.0.0",
"phpmd/phpmd": "^v2.6.0",
"nikic/php-parser": "^4.0",
"ocramius/proxy-manager": "^2.0.0",
"phpro/grumphp": "^0.13.1"
},
"scripts": {
"test": [
"./vendor/bin/grumphp run"
]
},
"minimum-stability": "stable"
}
Пам’ятайте, що ви можете зняти це вручну в кінці цієї публікації. Однак якщо ви бажаєте продовжувати, можете зробити це вручну. Я ніколи не хотів би відмовляти вас від цього. 🙂
Створивши файл composer.json, переконайтеся, що ви запустили таку команду з терміналу:
$ composer install
Це може зайняти деякий час; однак, як тільки це буде зроблено, ви повинні отримати таке повідомлення:
Стережись! GrumPHP нюхає ваші коміти!
Щоб запустити його насухо, введіть таку команду у свій термінал:
$ vendor/bin/grumphp run
Залежно від того, як ви працюєте з проектом, ви можете побачити результат, який виглядає приблизно так:
Але є ще багато роботи. А саме, нам потрібно:
- оновіть наш файл .gitignore ,
- представити конфігурацію для GrumPHP
- представити конфігурацію для PHPMD,
- представити конфігурацію для PHPCS,
- зрештою, реструктуризуйте структуру каталогів шаблону.
Усе, аж до останнього кроку, ми збираємося зробити в цій публікації.
Оновлення файлу ігнорування
По-перше, ми не хочемо фіксувати каталог постачальника або файл блокування композитора. Вони можуть бути згенеровані щоразу, коли користувач завантажує каталог. Вони можуть легко вийти з синхронізації, і вони додають величезний розмір до каталогу проекту.
Для цього ваш файл gitignore має виглядати так :
*.DS_Store
*.log
wp-config.php
wp-content/advanced-cache.php
wp-content/backup-db/
wp-content/backups/
wp-content/blogs.dir/
wp-content/cache/
wp-content/upgrade/
wp-content/uploads/
wp-content/mu-plugins/
wp-content/wp-cache-config.php
wp-content/plugins/hello.php
/.htaccess
/license.txt
/readme.html
/sitemap.xml
/sitemap.xml.gz
vendor/
composer.lock
Це вказує плагіну ігнорувати все, окрім того, що знаходиться в кореневому каталозі плагіна (і деяких каталогів, які ми створимо), а також деяких основних файлів, які ми звикли бачити в інсталяціях WordPress.
Деякі з того, що ви бачите, як-от wp-config.php або wp-content/backups, ви навряд чи побачите в контексті плагіна, але це стандартні директиви ігнорування WordPress, які я хочу тримати під рукою.
Ви помітите, що я також додав постачальника та файл блокування композитора внизу файлу.
Налаштувати GrumPHP
GrumPHP може зробити багато, і якщо ви витратили час на перегляд репозиторію, перш ніж прочитати це далеко, то ви, мабуть, це знаєте; однак я збираюся зробити його максимально простим, щоб він надавав інструкції, необхідні для інструментів, які ми використовуємо , і нічого більше.
parameters:
git_dir: .git
bin_dir: vendor/bin
process_timeout: 120
tasks:
securitychecker:
composer:
jsonlint:
xmllint:
yamllint:
phplint:
exclude:
- vendor/
phpcs:
metadata:
priority: 200
phpcsfixer2:
allow_risky: true
config: '.php_cs.dist'
metadata:
priority: 300
phpparser:
visitors:
forbidden_function_calls:
blacklist:
- "exit"
- "var_dump"
phpversion:
project: '7.1'
phpmd:
exclude: ['vendor']
ruleset: ['phpmd.xml']
Коротше кажучи, це означає запустити різноманітні перевірки для:
- безпека,
- композитор,
- JSON,
- XML,
- Yaml,
- PHP,
- PHPCS,
- Парсер PHP,
- PHPMD,
- і більше.
Коли ми завершимо налаштування всього іншого, я обов’язково покажу вам, як усе це поєднується. Але спочатку давайте завершимо налаштування решти наших утиліт.
PHPCS
Тут використовуються два окремі файли – файл dist і XML -файл – кожен із яких служить різним, але дуже корисним цілям.
Перший файл, php_cs.dist, який ви побачите в репозиторії в кінці цієї публікації, містить заголовок, який застосовується до всіх файлів PHP у нашому проекті. Він також забезпечує дотримання деяких інших правил, які покращують якість коду.
Правила зрозумілі самі за себе, і ви можете побачити, що вони застосовуватимуть, просто переглянувши кожне з визначених правил.
<?php
$header = <<<'EOF'
This file is part of the WordPress Widget Boilerplate
(c) Tom McFarlin <tom@tommcfarlin.com>
This source file is subject to the GPL license that is bundled
with this source code in the file LICENSE.
EOF;
return PhpCsFixerConfig::create()
->setRiskyAllowed(true)
->setRules([
'@PHP56Migration' => true,
'@Symfony' => true,
'@Symfony:risky' => true,
'align_multiline_comment' => true,
'array_syntax' => ['syntax' => 'short'],
'blank_line_before_statement' => true,
'combine_consecutive_issets' => true,
'combine_consecutive_unsets' => true,
// one should use PHPUnit methods to set up expected exception instead of annotations
'general_phpdoc_annotation_remove' => ['annotations' => ['expectedException', 'expectedExceptionMessage', 'expectedExceptionMessageRegExp']],
'header_comment' => ['header' => $header],
'heredoc_to_nowdoc' => true,
'list_syntax' => ['syntax' => 'long'],
'method_argument_space' => ['ensure_fully_multiline' => true],
'method_chaining_indentation' => false,
'no_extra_consecutive_blank_lines' => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']],
'no_null_property_initialization' => true,
'no_short_echo_tag' => true,
'no_unneeded_curly_braces' => true,
'no_unneeded_final_method' => true,
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_construct' => true,
'php_unit_test_class_requires_covers' => true,
'php_unit_dedicate_assert' => true,
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_order' => true,
'phpdoc_types_order' => ['null_adjustment' => 'always_last'],
'semicolon_after_instruction' => true,
'single_line_comment_style' => true,
'visibility_required' => ['const', 'property', 'method'],
'yoda_style' => true,
])
->setFinder(
PhpCsFixerFinder::create()
->exclude(__DIR__. '/vendor/*')
->in([
__DIR__. '/src'
])) ;
Далі ви також захочете створити файл XML, щоб доповнити файл вище. Ви помітите, що у файлі, який я надаю, це те, що я використовую для своєї роботи в Pressware. Крім того, він також розпізнає каталог тестів .
На даний момент у нас немає написаних модульних тестів, але якщо ви вирішите додати їх у свій віджет, він буде готовий для належної обробки.
<?xml version="1.0"?>
<ruleset name="Pressware">
<description>Pressware, LLC Coding Standards</description>
<!-- Scan all files in directory -->
<file>./src</file>
<file>./tests</file>
<exclude-pattern>./tests/phpunit/*</exclude-pattern>
<!-- Scan only PHP files -->
<arg name="extensions" value="php"></arg>
<!-- Show colors in console -->
<arg value="-colors"></arg>
<!-- Show sniff codes in all reports -->
<arg value="ns"></arg>
<!-- Use PSR-2 as a base -->
<rule ref="PSR2"></rule>
<rule ref="Generic.Arrays.DisallowLongArraySyntax.Found" ></rule>
<!-- Force 2 spaces indentation -->
<rule ref="Generic.WhiteSpace.ScopeIndent">
<properties>
<property name="indent" value="4"></property>
<property name="tabIndent" value="false"></property>
</properties>
</rule>
</ruleset>
Я вказую тут лише невеликий набір конфігурацій, але я вважаю, що його більш ніж достатньо для моїх потреб. Коли я дізнаюся більше або вирішу використовувати більше, я обов’язково оновлю вміст у наступних публікаціях.
Налаштуйте PHPMD
І, нарешті, нам потрібно налаштувати PHP Mess Detector (або PHPMD). На щастя, тут використовується XML-файл, який використовуватиме набори правил, визначені в пакеті, встановленому Composer. Усе, що нам потрібно зробити, це посилатися на правило у файлі конфігурації.
По-друге, ми також надамо невелике виключення для імені ShortVariable, як ви побачите в наступній суті :
<?xml version="1.0" encoding="UTF-8" ?>
<ruleset
name="VersionEyeModule rules"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd"
>
<rule ref="rulesets/cleancode.xml" ></rule>
<rule ref="rulesets/codesize.xml" ></rule>
<rule ref="rulesets/controversial.xml" ></rule>
<rule ref="rulesets/design.xml" ></rule>
<rule ref="rulesets/unusedcode.xml" ></rule>
<rule ref="rulesets/naming.xml">
<exclude name="ShortVariable"></exclude>
</rule>
<rule ref="rulesets/naming.xml/ShortVariable"
since="0.2"
message="Avoid variables with short names like {0}. Configured minimum length is {1}."
class="PHPMDRuleNamingShortVariable"
externalInfoUrl="http://phpmd.org/rules/naming.html#shortvariable">
<priority>3</priority>
<properties>
<property name="minimum" description="Minimum length for a variable, property or parameter name" value="3"></property>
<property name="exceptions" value="id,q,w,i,j,v,e,f,fp" ></property>
</properties>
</rule>
</ruleset>
І як тільки все це буде встановлено, ми зможемо знову запустити GrumPHP із командного рядка й отримати дещо інший набір результатів.
Знову запускаємо GrumPHP
Введіть наступне у свій термінал:
$ vendor/bin/grumphp run
І ви повинні побачити щось на зразок цього:
Інші результати, ніж у перший раз, га? Це тому, що ми порушуємо деякі правила та стандарти, які є сучасною частиною PHP та об’єктно-орієнтованої розробки.
І це те, що ми збираємося очистити в наступній публікації.
Скоро
Тож звідки ця об’єктно-орієнтована природа? До цього моменту ми говорили про використання Widgets API як об’єктно-орієнтованої моделі для написання об’єктно-орієнтованого коду в WordPress.
Дещо з того, що ми зробили до цього часу, було саме таким (розповідаючи про його принципи, дивлячись, як він викладений, тощо).
Але, як я вже згадував на початку цієї публікації, створення інструментів якості коду спочатку дає нам основу, яку ми можемо використовувати під час рефакторингу шаблону (що нам явно потрібно зробити, враховуючи кількість червоного кольору, показаного GrumPHP).
І саме з цього ми почнемо в наступній публікації цієї серії.


