Виджеты WordPress: начиная со стандартов
Цель этой серии — начать более глубокое погружение в работу с объектно-ориентированным программированием в контексте WordPress.
А поскольку WordPress Widgets API является одним из API, использующих объектно-ориентированные подходы, логично начать с него. Кроме того, это даст нам некоторые основополагающие методы, которые мы можем использовать для применения в будущей работе, поскольку мы увидим, как создавать больше объектно-ориентированных проектов на WordPress в будущих сериях.
До сих пор мы рассмотрели следующее:
- Виджеты WordPress: объектно-ориентированный подход. Widgets API — это надежная лакмусовая бумажка и пример того, как начать работу с объектно-ориентированным программированием в WordPress.
- Виджеты WordPress: как обнаружить объектно-ориентированное программирование. Цель состоит в том, чтобы вооружить вас всем необходимым для обнаружения объектно-ориентированных практик.
Если вы еще не догнали, сейчас прекрасное время, чтобы сделать это. И если да, то, как вы помните, из прошлого поста мы заканчивали следующим примечанием:
То есть мы вернемся к WordPress Widget Boilerplate, и я собираюсь провести его рефакторинг в его текущем состоянии, чтобы принять более современные стандарты PHP.
Чтобы приступить к обновлению шаблона виджетов WordPress в соответствии с указанными стандартами, нам нужно сделать несколько вещей:
- создать ветку из существующего шаблона,
- установить инструменты качества кода,
- убедитесь, что наша IDE правильно настроена,
- и начать рефакторинг кода в соответствии с указанными стандартами.
И это то, что мы собираемся начать делать с этим постом.
Начиная со стандартов
Если вы уже некоторое время являетесь участником этого сайта, то знаете, что я предпочитаю использовать Visual Studio Code. Если нет, у меня есть целый набор статей, посвященных тому, как я его использую (и, следовательно, как мы будем его использовать в этой серии постов).
И если вас интересует освещение стандартов кодирования, отладки, IDE, сред разработки и т. д., ознакомьтесь с The Independent WordPress Developer.
Тем не менее, я предполагаю, что если вы читаете это, то вы прочитали вышеприведенный материал или вам удобно проходить весь вышеизложенный материал.
С учетом сказанного, давайте начнем.
Загрузка репозитория
Первое, что вам нужно сделать, это клонировать копию репозитория. Я предпочитаю делать это через командную строку.
Кроме того, я также думаю, что стоит сделать это с последней версией WordPress. Если у вас нет копии основной копии Subversion WordPress, вы можете прочитать, как ее настроить здесь; однако это необязательно. Вы можете следовать остальной части этого руководства с любой версией WordPress, которая вам нравится.
Для этого
- Убедитесь, что вы находитесь в каталоге плагинов вашей установки WordPress.
- А затем введите следующие команды в копию вашего терминала
$
Это создаст каталог WordPress-Widget-Boilerplate в вашем каталоге плагинов. Вы можете перейти к нему, просто набрав:
$ cd WordPress-Widget-Boilerplate
Результаты клонирования репозитория должны выглядеть примерно так:
Затем вам нужно убедиться, что вы перешли на ветку разработки, которую я создал. Это очень легко сделать. Но прежде чем мы это сделаем, почему бы не настроить проект в Visual Studio?
Настройка кода Visual Studio
Шаги по настройке проекта в Visual Studio Code просты:
- Перетащите каталог Boilerplate в IDE,
- Откройте встроенный терминал,
- Поменять местами ветки
Так же, как я сделал выше, я предоставлю скринкаст о том, как все это сделать. Перетаскивание каталога в Visual Studio Code должно быть достаточно простым, но перестановка ветвей в командной строке может немного отличаться.
Сначала настроим проект в Visual Studio Code:
Обратите внимание, что я также открываю встроенный терминал, нажимая сочетание клавиш CMD+P (у меня macOS, поэтому ваш ярлык может отличаться). Затем я ввожу команду, чтобы проверить ветку разработки .
Как только вы это сделаете, ваш локальный репозиторий должен переключиться на ветку разработки. Вы можете подтвердить, что это ветка, с которой вы работаете, набрав:
$ git branch
А затем просмотрите содержимое терминала. Строго говоря, следует выделить развитие .
На этом этапе мы собираемся добавить в проект несколько новых файлов. В конце этого урока вы можете создать запрос, чтобы получить все, что я собираюсь здесь задокументировать. Но поскольку цель того, что мы делаем, двояка, важно убедиться, что мы делаем это в правильной последовательности, потому что первый шаг — это то, что я использую в каждом отдельном проекте для WordPress на данный момент.
Итак, с учетом сказанного, давайте посмотрим.
Композитор и качество кода
Первое, что я хотел бы сделать, это настроить ряд инструментов для обеспечения качества кода. Это достигается различными пакетами Composer. Это включает:
- GrumPHP. Инструмент качества кода PHP. Не стоит недооценивать ясность и степень наполненности этого репозитория информацией. Если вы когда-нибудь застрянете с любым из других инструментов, упомянутых здесь, сначала просмотрите документацию в этом репозитории.
- Исправление PHP CS. Инструмент для автоматического исправления проблем со стандартами кодирования PHP.
- Параллельный анализ PHP. Этот инструмент проверяет синтаксис файлов 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, которые я предпочитаю держать под рукой.
Вы заметите, что я также добавил в конец файла файл vendor и composer.
Настроить 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,
- Ямль,
- 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).
И именно с этого мы начнем в следующем посте этой серии.


