Показаны сообщения с ярлыком WordPress. Показать все сообщения
Показаны сообщения с ярлыком WordPress. Показать все сообщения

воскресенье, 30 апреля 2017 г.

Использование символьных ссылок

При разработке плагина для WordPress удобно иметь одну директорию с плагином. Файлы, находящиеся в ней редактируются в текстовом редакторе, а сама директория является Git репозиторием. Однако, иногда нужно протестировать, как плагин работает с различными версиями WordPress, в режиме мультисайт и т.д. В этом случае у нас может быть установлено несколько версий WordPress. Без символьных ссылок, нам пришлось бы копировать директорию с плагином каждый раз, после внесения изменений в файлы плагина.

Символьные ссылки

Символьная ссылка - это специальный файл в файловой системе, который ссылается на другой файл или директорию. Символьные ссылки можно создавать как в Windows, так и в OSX и Linux. Однако, синтаксис команд для Windows и OSX/Linux различен.

OSX и Linux

// Если плагин находится в директории ~/plugin_name // Перейти в директорию с WordPress плагинами той установки WordPress, где нам нужно добавить плагин plugin_name. cd public_html/wp-content/plugins // Создать символьную ссылку ln -s ~/plugin_name plugin_name

Windows

// Если плагин находится в директории C:\plugin_name // Перейти в директорию с WordPress плагинами той установки WordPress, где нам нужно добавить плагин plugin_name. cd public_html/wp-content/plugins // Создать символьную ссылку mklink /j plugin_name C:\plugin_name

пятница, 31 марта 2017 г.

Как устроено модульное (Unit) тестирование кода в WordPress

Исходный код WordPress покрыт тестами. Для тестирования PHP кода используется PHPUnit, а для тестирования JavaScript — QUnit. В данной статье рассмотрим тестирование PHP кода.

Установка тестов

  1. Установите PHPUnit. Инструкция по установке доступна на сайте этого фреймворка.
  2. Выполните команды в консоли чтобы загрузить версию WordPress для разработчиков, включающую тесты: svn co https://develop.svn.wordpress.org/trunk/ wordpress-develop cd wordpress-develop
    Если у вас не установлена система управления версиями Subversion, вы можете скачать архив содержащий WordPress с тестами на этой странице. Это не удобно, т.к. нужно каждый раз скачивать архив чтобы иметь последнюю версию.
  3. Создайте пустую базу данных MySQL, которая будет использоваться для тестирования. Все данные будут удалены из всех таблиц во время исполнения тестов, поэтому нельзя использовать существующую базу данных.
  4. Скопируйте данные из файла wp-tests-config-sample.php в новый файл wp-tests-config.php и добавьте в него данные для доступа к базе данных, созданной на предыдущем шаге.
  5. В корневой директории, где расположены файлы wp-tests-config.php, phpunit.xml.dist, и папка tests/, выполните команду: phpunit
    или, добавьте путь к файлу, чтобы выполнить тесты находящиеся в нем, например: phpunit tests/phpunit/tests/dependencies/styles.php

О запуске различных групп тестов можно почитать в документации.

Для каждого выполненного теста в консоли отображается один из следующих символов:

  • . — тест успешно выполнен
  • F — тест не выполнен успешно. Какое либо утверждение, например assertEquals ложно.
  • E — тест не выполнен успешно из за ошибки в PHP коде: E_ERROR, E_WARNING, E_NOTICE
  • S — тест пропущен, например, с помощью метода markTestSkipped(). Обычно это означает что тест нужен только при определенных обстоятельствах, например, когда включен режим Мультисайт. Если он выключен — тест пропускается.
  • I — незаконченный тест. В нем присутствует метод markTestIncomplete() или это пустой тест без утверждений (asserts).

Устройство тестов

Классы с тестами наследуются от класса WP_UnitTestCase, который в свою очередь наследуется от класса PHPUnit_Framework_TestCase. Класс WP_UnitTestCase имеет ряд методов, упрощающих тестирование в WordPress. Например, эти методы возвращают WordPress в исходное состояние после каждого теста:

  • setUp — выполняется перед каждым методом в тестовом классе
  • tearDown — выполняется после каждого метода в тестовом классе
  • setUpBeforeClass — выполняется перед первым методом в тестовом классе
  • tearDownAfterClass после последнего метода в тестовом классе
  • assertPostConditions — выполняется перед окончанием теста, перед tearDown

Фабрики

Фабрики позволяют создавать посты, комментарии, таксономии, пользователей и т.д.

// создать пользователя с ролью 'editor', вернуть идентификатор $user_id = self::factory()->user->create( array( 'role' => 'editor' ) // создать пользователя с ролью 'editor', вернуть объект класса WP_User $user = self::factory()->user->create_and_get( array( 'role' => 'editor' ) // создать 5 страниц, вернуть массив идентификаторов $post_ids = self::factory()->post->create_many( 5, array( 'post_type' => 'page' ) );

суббота, 18 февраля 2017 г.

Использование PHP CodeSniffer при разработке для WordPress

PHP CodeSniffer сканирует исходный код и выявляет несоответствие заранее определенному набору стандартов. Следование этим стандартам является правилом хорошего тона если вы разрабатываете плагин или тему. Они упрощают чтение и модификацию кода. При чтении кода, написанного разными разработчиками, но отформатированного в соответствии со стандартами, складывавается ощущение что весь этот код написан одним разработчиком.

PHP CodeSniffer состоит из двух скриптов:

  • phpcs — сканирует исходный код
  • phpcbf — исправляет ошибки, если это возможно

Установка

PHP CodeSniffer можно установить различными способами. Для установки через Composer выполните команду

composer create-project wp-coding-standards/wpcs --no-dev

Для запуска:
./wpcs/vendor/bin/phpcs ./wpcs/vendor/bin/phpcbf

Для удобства можно добавить wpcs/vendor/bin в переменную окружения PATH, и установить набор правил WordPress по умолчанию, чтобы не указывать его каждый раз при запуске
phpcs --config-set default_standard WordPress

Наборы правил

  • WordPress — все правила WordPress
  • WordPress-Core — правила для ядра WordPress
  • WordPress-Docs — правила документирования
  • WordPress-Extra — дополнительные правила, дополняющие правила WordPress-Core.
    Включают в себя WordPress-Core
  • WordPress-VIP — правила WordPress VIP.
    Включают в себя WordPress-Core

Пример

phpcs --standard=WordPress wp-load.php // найдено 13 ошибок, 4 предупреждения

phpcbf --standard=WordPress wp-load.php // исправление ошибок phpcs --standard=WordPress wp-load.php // найдено 9 ошибок, 4 предупреждения

воскресенье, 29 января 2017 г.

WP CLI — незаменимый инструмент для WordPress разработчика

WP CLI — это инструмент, который существенно увеличивает скорость и удобство разработки. Он представляет собой phar файл (исполняемый PHP архив), который запускается в командной строке и предоставляет множество команд для работы с WordPress. Хотя на сайте доступна подробная документация с примерами, я все же приведу несколько примеров использования команд, входящих в его состав.

wp search-replace — поиск и замена
wp search-replace 'existing_domain.com' 'new_domain.com' --skip-columns=guid // изменение URL блога во всех таблицах базы данных, пропуская столбец guid

wp eval — исполнение PHP кода
wp eval 'echo WP_CONTENT_DIR;' // просмотр значения константы WP_CONTENT_DIR

wp shell — интерактивная консоль в пределах среды WordPress. Здесь есть доступ к функциям, классам и глобальным переменным, которые, например, вы можете использовать при разработке плагина.
wp shell >>> get_current_blog_id() => 1 >>>

Для работы с wp shell в Windows, скачайте psysh (интерактивная PHP консоль) и подключайте его:
wp --require=psysh shell

wp plugin activate — активация плагина
wp --url=http://localhost/multisite/two plugin activate wp-amp // активация плагина wp-amp на втором сайте при использовании multisite

wp plugin toggle — переключение плагина (если плагин активен, деактивирует его, если не активен, активирует)
wp plugin toggle wp-amp amp-wp // переключение двух плагинов

wp plugin uninstall — удаление плагина
wp plugin uninstall advanced-ads-pro --skip-delete // запуск процедуры удаления плагина, при этом не удаляя файлы

wp scaffold — кодогенерация (позволяет сгенерировать плагин, тему на основе _s , создать дочернюю тему, шаблон для написания тестов к теме или плагину, custom post type или таксономию)
/* генерация нового плагина, включая: - конфигурационный файл PHPUnit - .travis.yml (конфигурационный файл Travis CI) - bin/install-wp-tests.sh ( создание конфигурации для тестирования, включая БД) - tests/test-sample.php (шаблон теста) - phpcs.ruleset.xml (правила PHP_CodeSniffer) */ wp scaffold plugin sample-plugin

wp db — операции с БД
wp db cli // интерактивная консоль MySQL

wp media regenerate — управление вложениями
wp media regenerate --yes // регенерация миниатюр

wp cache — управление кэшем (добавление, удаление, изменение и т.д.)
wp cache add test_key test_data test_group // добавление в кэш

воскресенье, 20 ноября 2016 г.

Acceptance Тестирование WordPress сайта с помощью Codeception

Codeception — это фреймворк для тестирования веб-приложений. Тесты, написанные с использованием этого фреймворка легко писать, модифицировать и исполнять. Используя набор готовых модулей, вы можете сконцентрироваться на написании самих тестов, вместо того, чтобы изобретать тестовый фреймворк.

Codeception позволяет писать 3 вида тестов.

Приемочные (Acceptance) тесты позволяют тестировать веб-сайт с точки зрения пользователя — переходить по страницам, кликать по ссылкам, заполнять формы и т.д. Не имеет значение, какой фреймворк, база данных, язык программирования или веб-сервер используются чтобы отобразить веб-страницу. Любая веб-страница, которую вы можете посетить с помощью веб-браузера может быть покрыта такими тестами.

Функциональные (Functional) тесты позволяют тестировать веб-приложение без запуска веб-сервера. Мы можем, например, эмулировать запрос к веб-серверу, передавая $_GET  и $_POST переменные, проверяя, что мы получаем правильный ответ при данном запросе и что отправленные данные корректно сохраняются в базе данных.

Модульные (Unit) тесты позволяют изолированно тестировать отдельные функции и классы.


WordPress и Codeception


Предположим, нам нужно менять значение опции, полученной с помощью функции get_option. После каждого изменения, нам нужно загружать веб-страницу и смотреть, есть ли на экране какие-либо элементы. Данная статья рассказывает, как это реализовать.

WP-Browser  — набор модулей для Codeception облегчающий тестирование тем и плагинов для WordPress. Мы будем использовать только модуль WPBootstrapper позволяющий вызывать функции WordPress прямо в тестах.
  1. Создайте директорию и файл composer.json
    mkdir codeception_tests && cd codeception_tests touch composer.json
  2. Измените содержимое файла composer.json на:
    { "require": { "codeception/codeception": "^2.2", "lucatume/wp-browser": "~1.11" } }
  3. Выполните команду composer install
  4. Создайте псевдоним
    alias codecept='./vendor/bin/codecept'
  5. Подготовьте тестовую директорию и конфигурационные файлы
    codecept bootstrap
  6. Сгенерируйте тест
    codecept generate:cept acceptance Welcome
  7. Откройте созданный файл теста tests/acceptance/WelcomeCept.php и измените его на:
    // загрузка WordPress bootstrapWp(); // обновление описания блога update_option( 'blogdescription', 'Welcome to my blog' ); // Загрузка главной страницы $I->amOnPage('/'); // Проверка, что описание блога присутствует на странице $I->see('Welcome to my blog'); // Обновление описания блога update_option( 'blogdescription', 'Welcome again' ); // Обновление страницы $I->amOnPage('/'); // Проверка, что новое описание блога присутствует на странице $I->see('Welcome again');
  8. Добавьте следующий код в файл tests/acceptance.suite.yml
    class_name: AcceptanceTester modules: enabled: - PhpBrowser: url: http://localhost/blog // url блога - \Helper\Acceptance - WPBootstrapper: wpRootFolder: '..' // путь к директории с WordPress
  9. Запустите тест
    codecept run acceptance
  10. Тест выполнился успешно. Результат:
    Codeception PHP Testing Framework v2.2.6 Powered by PHPUnit 5.6.4 by Sebastian Bergmann and contributors. Acceptance Tests (1) ------------------------------------------------ + WelcomeCept: (14.78s) --------------------------------------------------------------------- Time: 20.15 seconds, Memory: 20.00MB OK (1 test, 2 assertions)

Вложенные Backbone представления в WordPress

Backbone — это JavaScript библиотека, которая используется в административной панели WordPress для работы с медиа, ревизиями и т.д. WordPress дополняет эту библиотеку вложенными представлениями (Subviews). Рассмотрим, как их можно использовать. Предположим, у нас есть продукты, имеющие свойства. При щелчке на названии продукта мы добавляем новое свойство в коллекцию свойств продукта.
Необходимо подключить: jquery.js, underscore.min.js, backbone.min.js, wp-util.js, wp-backbone.js

<div id="container"></div> <!-- шаблон для продукта --> <script id="tmpl-product" type="text/html"> <p style="cursor: pointer">{{data.name}}</p> <ul class="properties"></ul> </script> <!-- шаблон для свойства продукта --> <script id="tmpl-property" type="text/html">{{{data.name}}}</script> <script> // создаем главное представление var main_view = wp.Backbone.View.extend({ prepare: function() { return this.model.toJSON(); } }); // модель для свойства продукта var property_model = Backbone.Model.extend({}); // коллекция моделей свойств продукта var property_collection = Backbone.Collection.extend({ model: property_model }); // представление для свойства продукта var property_view = main_view.extend({ tagName: 'li', template: wp.template( 'property' ), }); // модель для продукта var product_model = Backbone.Model.extend({ // коллекция свойств продукта properties: {}, initialize: function() { this.properties = new property_collection(); }, }); // представление для продукта var product_view = main_view.extend({ className: "product", template: wp.template( 'product' ), events: { // добавляем новое свойство в коллекцию свойств продукта 'click p': 'add_property' }, initialize: function() { // при добавлении нового свойства к продукту, добавляем вложенное представление this.listenTo( this.model.properties, 'add', function( property ) { this.views.add( '.properties', new property_view({ model: property }) ); } ); // рендер this.render(); jQuery( '#container' ).html( this.el ); this.views.ready(); }, add_property: function() { this.model.properties.add( {name: 'property ' + Math.random() } ); }, }); // создаем представление и передаем ему модель одиного продукта без свойств new product_view( { model: new product_model( { 'name': 'product 1', } ) } ); </script>

воскресенье, 6 ноября 2016 г.

Новый класс WP_List_Util в WordPress 4.7

В WordPress есть удобные функции для работы с массивом объектов или массивов. Создадим массив, работа с которым будет рассмотрена далее:

$array = array (
    array ( 'order' => 5, 'title' => 'five' ),
    array ( 'order' => 3, 'title' => 'three' ),
    array ( 'order' => 1, 'title' => 'two' ),
    array ( 'order' => 1, 'title' => 'one' ),
    array ( 'order' => 4, 'title' => 'four' ),
);


wp_list_filter позволяет фильтровать массив на основе набора пар ключ => значение
Аргументы:
  1. фильтруемый массив
  2. массив условий в форме пар ключ => значение
  3. оператор: AND (по умолчанию), OR, NOT
// ключ 'title' равен 'four'
$result = wp_list_filter( $array, array( 'title' => 'four' ) );

array (
    array ( 'order' => 4, 'title' => 'four' ),
);

// ключ 'order' не равен 1
 $result = wp_list_filter( $array, array( 'order' => 1 ), 'NOT' );

array (
    array ( 'order' => 5, 'title' => 'five' ),
    array ( 'order' => 3, 'title' => 'three' ),
    array ( 'order' => 4, 'title' => 'four' ),
);


wp_list_pluck позволяет:
  • взять определенное свойство из каждого объекта, находящегося в массиве
  • взять определенный элемент из каждого массива, находящегося а массиве

$result = wp_list_pluck( $array, 'title' );

array ( 'five', 'three', 'two', 'one', 'four' );


wp_filter_object_list позволяет применить wp_list_filter, затем wp_list_pluck


в WordPress 4.7 было добавлена новая функция wp_list_sort, которая позволяет сортировать массив:
  • массивов, по ключу из этих массивов
  • объектов, по свойству из этих объектов

// сортировка по ключу 'order'
$result = wp_list_sort( $array, 'order', 'ASC');

array (
    array ( 'order' => 1, 'title' => 'two' ),
    array ( 'order' => 1, 'title' => 'one' ),
    array ( 'order' => 3, 'title' => 'three' ),
    array ( 'order' => 4, 'title' => 'four' ),
    array ( 'order' => 5, 'title' => 'five' ),
);

// сортировка по ключу 'order', затем по ключу 'title'.
$result = wp_list_sort( $array, array( 'order' => 'ASC', 'title' => 'ASC' ) );

array (
    array ( 'order' => 1, 'title' => 'one' ),
    array ( 'order' => 1, 'title' => 'two' ),
    array ( 'order' => 3, 'title' => 'three' ),
    array ( 'order' => 4, 'title' => 'four' ),
    array ( 'order' => 5, 'title' => 'five' ),
);


В WordPress 4.7 также появился новый класс WP_List_Util, позволяющий применять рассмотренные функции в определенной последовательности. Например, функция wp_filter_object_list может делать следующее (при передаче соответствующих аргументов):

// исключить элементы с ключом 'order' равным 1, затем выбрать значения по ключу 'title'
$util = new WP_List_Util( $array );
$util->filter( array( 'order' => 1 ), 'NOT' );
$util->pluck( 'title' );
$result = $util->get_output();

array ( 'five', 'three', 'four' );