Установка WordPress через Composer

Установка WordPress через Composer

В данной статье мы поговорим про установку WordPress через Composer. Пройдемся пошагово как это сделать. Рассмотрим варианты с установкой WordPress в отдельную директорию, и классический вариант со стандартной файловой структурой.

Использование Composer для установки WordPress дает ряд преимуществ:

  • Удобно обновлять WordPress
    Больше никаких копирований файлов, если вы отключили обновление WP через админ панель. Для того чтобы поменять версию WordPress, нам необходимо только поменять номер версии WordPress в файле composer.json и выполнить консольную команду composer install .
  • Гибкость при изменении версии WordPress
    Забудьте про обновление только на latest версию WordPress. При использовании Composer, вы сможете указать версию WordPress какую захотите, будь-то patch, minor или major версия.
  • Простой Code Review
    Забудьте о тысячи строк изменений в PullRequest при обновлении WordPress. Ваши коллеги будуит видеть только строки с изменением версии WordPress в composer.json и composer.lock .
  • Файлы ядра WordPress никогда не будут изменены
    Файлы ядра по случайности или специально никогда не смогут быть изменены и закомичены в GIT. WordPress будет устанавливаться через Composer. Вы всегда будите уверены что новая версия WordPress была получена из официального репозитория без изменений.
  • Меньший размер репозитория
    При использовании Composer, файлы ядра WordPress не будут храниться в репозитории. Это позволит уменьшить размер репозитория, что благоприятно повлияет на клонирование репозитория и деплои.
  • Возможность использовать разные версии WordPress в монорепозитории
    С этим нам тоже может помочь установка WordPress через Composer, но данное решение выходит за рамки статьи.

Для того чтобы начать устанавливать WP через Composer необходимо провести небольшое конфигурирование проекта, о котором я расскажу в этой статье. Но вначале давайте поговорим о том что такое Composer.

Что такое Composer

Composer — это инструмент для управления зависимостями на языке PHP. Он позволяет объявить библиотеки от которых зависит ваш проект и будет управлять зависимостями (устанавливать/обновлять) за вас. Composer так-же обеспечивает правильное разрешение конфликтов зависимостей библиотек.

Для использования Composer локально есть 2 варианта:

  • Использовать официальную документацию с установкой бинарника Composer локально https://getcomposer.org/download/
    (Этот вариант предпочтительнее если вы не работали с Docker)
  • Работать с Composer из-под готового Docker Container следуя инструкции из README.md

Далее давайте поговорим про установку WordPress через Composer.

Установка WordPress через Composer

Для установки WordPress через Composer, нам для начала нужно создать файл composer.json в корне проекта.
Сделать это можно воспользовавшись командой composer init или создать файл вручную, вставив в composer.json код примера ниже:

{
    "name": "wp-yoda/composer-with-wordpress",
    "description": "Example of using Composer for installing WordPress core and plugins",
    "require": {}
}

Далее нам необходимо добавить директиву repositories .

Что такое директива repositories в composer.json

Repository в Composer это источник пакета. При установке пакетов композер будет смотреть во все репозитории composer файла, чтобы найти требуемый пакет для проекта.
По умолчанию, только репозиторий Packagist.org зарегистрирован в Composer. Но вы можете добавить больше репозиториев для вашего проекта объявив их в директиве repositories файла composer.json

Подробнее о Composer’s repository по ссылке

Composer.json файл будет выглядеть следующим образом:

{
    "name": "wp-yoda/composer-with-wordpress",
    "description": "Example of using Composer for installing WordPress core and plugins",
    "repositories": [
        {
            "type": "package",
            "package": {
                "name": "wordpress/wordpress",
                "version": "6.2.2",
                "type": "wordpress-core",
                "dist": {
                    "type": "zip",
                    "url": "https://github.com/WordPress/WordPress/archive/refs/tags/6.2.2.zip"
                }
            }
        }
    ],
    "require": {}
}

Теперь при подключении пакета wordpress/wordpress , Composer найдет пакет в добавленном репозитории и установит его.

Официального WordPress пакета на packagist.org нет на данный момент

Самый надежный в плане безопасности способ установки WordPress через Composer на данный момент — это вариант описанный в статье через подключение официального WordPress GitHub репозитория в composer.json .
Вариант с использованием неофициальных репозиториев Composer Repository for WordPress core instalation или пакетов roots/wordpress, johnpbloch/wordpress могут быть ненадежными, но более удобными в сочетании с Composer.

После того как мы добавили источник откуда будет скачиваться WordPress (официальный репозиторий), я предлагаю добавить WordPress как Composer зависимость.
Выполним следующую команду в терминале:

composer require wordpress/wordpress

Composer этой командой подключит пакет wordpress/wordpress в composer.json и установит его в наш проект в ./vendor директорию.

Вы должны увидеть у себя следующую файловую структуру:

установка WordPress через Composer
внутри директории ./vendor/wordpress будет лежать ядро WordPress

Не забудьте добавить /vendor/ в .gitignore файл, чтобы файлы ./vendor директории не индексировались GIT.

Теперь в нашем проекте есть установленный WordPress, но он находится в директории vendor, чтобы наш проект заработал его нужно переместить в другое место. Но в какое?

Есть 2 варианта как можно это сделать:

Классическая структура WordPress

.
├── index.php
├── composer.json
├── composer.lock
├── vendor/
│   ├── autoload.php
│   └── ......
├── wp-admin/
│   ├── about.php
│   ├── admin-ajax.php
│   ├── admin-functions.php
│   └── ......
├── wp-content/
│   ├── mu-plugins/
│   ├── plugins/
│   ├── themes/
│   └── uploads/
├── wp-cron.php
├── wp-config.php
├── wp-includes
│   ├── admin-bar.php
│   ├── author-template.php
│   ├── block-editor.php
│   ├── block-i18n.json
│   ├── block-patterns/
│   ├── block-patterns.php
│   ├── block-supports
│   ├── block-template-utils.php
│   ├── block-template.php
│   ├── wp-db.php
│   └── ......
├── wp-links-opml.php
├── wp-load.php
├── wp-login.php
├── wp-mail.php
├── wp-settings.php
├── wp-signup.php
├── wp-trackback.php
└── xmlrpc.php

WordPress в отдельной директории

.
├── index.php
├── composer.json
├── composer.lock
├── vendor/
│   ├── autoload.php
│   └── .....
├── wp/
│   ├── index.php
│   ├── wp-activate.php
│   ├── wp-admin/
│   ├── wp-blog-header.php
│   ├── wp-comments-post.php
│   ├── wp-config-sample.php
│   ├── wp-cron.php
│   ├── wp-includes/
│   ├── wp-links-opml.php
│   ├── wp-load.php
│   ├── wp-login.php
│   ├── wp-mail.php
│   ├── wp-settings.php
│   ├── wp-signup.php
│   ├── wp-trackback.php
│   └── xmlrpc.php
├── wp-config.php
└── wp-content/
    ├── mu-plugins/
    ├── plugins/
    ├── themes/
    └── uploads/

Какой подход вам больше подойдет вы узнаете, когда прочитаете в статье про оба варианта.
Вначале рассмотрим установку WordPress через Composer с классической файловой структурой.

Установка WordPress с классической файловой структурой

Классическая структура WordPress проекта — это вариант когда мы располагаем все файлы ядра WordPress в корне проекта, вместе с файлами проекта. Нет разделения между ядром WP и кодом который пишем мы.
У этого варианта есть свои преимущества и недостатки.

Преимущества:

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

Недостатки:

  • Файлы ядра WordPress лежат вперемешку с файлами проекта, что создает трудности при работе с проектом.

Настройка composer.json

Чтобы переместить директорию из vendor в корневую директорию проекта воспользуемся Composer Script events.

Composer scripts events — это события Composer, которые запускают кастомные команды до/ после выполнения Composer команд. Например можно выполнить команду после composer install .

Подробнее вы можете почитать по ссылке.

Добавим директиву scripts в composer.json с событием post-install-cmd , которое срабатывает после composer install

    "scripts": {
        "post-install-cmd": "cp -r ./vendor/wordpress/wordpress/* ./"
    }

В событии "post-install-cmd" мы копируем содержимое установленного WordPress в vendor директорию в наш рабочий каталог ./ .

Теперь выполните команду в терминале:

composer install

После этого мы видим у себя в проекте файлы WordPress. Теперь давайте добавим в .gitignore файлы ядра, чтобы они не попадали в репозиторий.

Настройка .gitignore

Для того чтобы файлы ядра не попали в git index, необходимо добавить следующие правила в .gitignore

.idea
/vendor/

# ignore WordPress files
/index.php
/license.txt
/readme.html
/wp-activate.php
/wp-blog-header.php
/wp-comments-post.php
/wp-config-sample.php
/wp-config.php
/wp-cron.php
/wp-links-opml.php
/wp-load.php
/wp-login.php
/wp-mail.php
/wp-settings.php
/wp-signup.php
/wp-trackback.php
/xmlrpc.php

/wp-includes
/wp-admin

/wp-content/*
!/wp-content

/wp-content/plugins/*
!/wp-content/plugins/
!/wp-content/plugins/YourCustomPluginName

/wp-content/themes/*
!/wp-content/themes/
!/wp-content/themes/YourCutsomTheme

Теперь файлы ядра индексироваться не будут.

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

# new plugin
!/wp-content/plugins/YourCustomPluginName

# new theme
!/wp-content/themes/YourCutsomTheme

Где YourCustomPluginName или YourCustomTheme имя директории вашего WP плагина или темы.

Исходный код

Исходный код установки WordPress с классической структурой доступен по ссылке на GitHub. Вы можете его развернуть локально, следуя инструкции в README.md.

Установка WordPress в отдельную директорию

Установка WordPress в отдельную директорию — это вариант установки WordPress через Composer, когда мы располагаем все файлы ядра в отдельной директории, в стороне от файлов проекта.

.
├── index.php
├── composer.json
├── composer.lock
├── vendor/
│   ├── autoload.php
│   └── .....
├── wp/
│   ├── wp-activate.php
│   ├── wp-admin/
│   ├── wp-blog-header.php
│   ├── wp-includes/
│   ├── wp-load.php
│   └── .....
├── wp-config.php
└── wp-content/
    ├── mu-plugins/
    ├── plugins/
    ├── themes/
    └── uploads/

У этого варианта есть свои преимущества и недостатки. Давайте поговорим о них.

Преимущества:

  • Удобная структура кода, ничего не мешает и не отвлекает от разработки. Вы работаете только с ./wp-content директорией, темами и плагинами, файлы ядра вас не отвлекают при работе, т.к. они скрыты в директории ./wp
  • Если ядро WP хранится в отдельной директории, то его обновление менее болезненно, так как необходимо только заменить файлы ядра в каталоге ./wp. И у нас отсутствует вероятность перезатереть файлы проекта (темы, плагины), файлами ядра.

Недостатки:

  • Некоторые «не по стандартам WP написанные» плагины могут не работать из-за жестко прописанных путей полагаясь на «классическую структуру проекта».
  • Нужно настраивать константы wp-config.php в WordPress, чтобы урлы и пути WordPress на правильные директории.
  • Необходимо добавить файл index.php в корень проекта.

Давайте перейдем к найстройке composer.json.

Настройка composer.json

Что такое Composer Scripts — я описал в классическом варинте установки WordPress в этой статье.

Чтобы использовать этот вариант, необходимо добавить директиву scripts с событием post-install-cmd , которое срабатывает после install :

    "scripts": {
        "post-install-cmd": "mkdir -p ./wp && cp -r ./vendor/wordpress/wordpress/* ./wp"
    }

в скрипте "post-install-cmd" мы копируем содержимое установленного WordPress из vendor директории в каталог ./wp . Именно в каталоге ./wp будет храниться наше ядро WordPress.

Теперь мы можем выполнить установку WordPress через Composer:

composer install

и вы увидите у себя директорию ./wp в корне проекта с содержимым ядра WordPress.

Настройка .gitignore

Для того чтобы файлы ядра не попали в git index, необходимо добавить следующие правила в .gitignore

.idea
/vendor/

# ignore WordPress files
/wp

/wp-content/*
!/wp-content
!/wp-content/index.php

!/wp-content/mu-plugins/
!/wp-content/plugins/
!/wp-content/themes/

После добавления этих строк, WordPress core, cache в wp-content, uploads и другие системные файлы WordPress индексироваться не будут.

Если вы хотите добаваить в индекс GIT файл или директорию из wp-content, просто исключите эту директорию из .gitignore c помощью ! знака перед этой директорией: !/wp-content/new-directory/ .

Перейдем к добавленю файла index.php.

Добавим index.php

Т.к. наше ядро лежит в wp директории, в корне проекта у нас отсутствует файл index.php . Следовательно ядро WP не будет загружено для клиентских запросов. Из-за отсутствия главного файла index.php .
Для этого создадим файл index.php и добавим в него следующий код:

<?php

define( 'WP_USE_THEMES', true );

/** Loads the WordPress Environment and Template */
require __DIR__ . '/wp/wp-blog-header.php';

Этот стандартный файл index.php от WP за одним исключением, мы поменяли путь до файла wp-blog-header.php .

Перейдем к создании wp-content/ директории и настройке.

Добавим wp-content директорию

Ядро WordPress находится в директории ./wp , а разрабатываемые темы и плагины будут находиться в ./wp-content .
Для такой структуры нам необходимо создать директорию ./wp-content в корне проекта, со следующим содержимым.

.
├── wp/
└── wp-content/
     ├── index.php
     ├── mu-plugins/
     ├── plugins/
     ├── themes/
     └── uploads/

Вы можете скопировать wp-content из ./wp директории и вставить в корень проекта удалив все лишнее.
Теперь вы можете добавить необходимые вам плагины и темы в ./wp-content/themes или ./wp-content/plugins .

После добавления wp-content директории, нам нужно задать правильные константы для WordPress.

Пропишем константы с ссылками и путями

Для того чтобы WordPress понял по какому адресу и путям находится ядро WordPress и wp-content директория нам нужно задать константы с правильными значениями.

Но перед этим, нужно создать файл wp-config.php в корне проекта.
Для этого мы можем скопировать wp-config.php из ./wp/ в корень проекта с именем wp-config.php .

После того как wp-config.php создан, добавим следующие константы в конец файла wp-config.php , но перед строкой require_once ABSPATH . 'wp-settings.php';

define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] ); // Site URL for the front-of-site
define( 'WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] . '/wp' ); // URL address with WP core (which is for the admin)

define( 'WP_CONTENT_DIR', __DIR__ . '/wp-content' );
define( 'WP_CONTENT_URL', WP_HOME . '/wp-content' );

WP_SITEURL и WP_HOME переопределяют значение опции siteurl и home в таблице wp_options соответственно. Но они не изменяют эти значения в базе данных.

* siteurl — это URL адрес, по которому находятся ядро WordPress.
* home — это URL сайта (фронт-энд).

Подробнее можно прочитать на wp-kama по ссылке

Константы WP_CONTENT_DIR и WP_CONTENT_URL необходимы чтобы указать путь до директории ./wp-content в нашем проекте, т.к. ядро WordPress было размещено в директории ./wp .
Если мы не укажем этим константы, то WP будет искать wp-content в ./wp директории.

Когда вы перейдете на сайт то должны увидеть следующую ошибку

Установка WordPress в отдельной директории

это будет означать что вам необхоимо заполнить константы подключения к БД в wp-config.php . После того как вы это заполните, перейдите в админку и активируйте добавленную тему в админке.

Панель администратора доступна по адресу /wp/wp-admin

Исходный код

Полный код Установки WordPress в отдельной директории доступен в репозитории по ссылке на GitHub.

Другие варианты установки WordPress через Composer

У примера с использованием официального репозитория есть один недостаток: мы не можем использовать задуманную в Composer версионность при composer update.
Например: мы не можем указать в composer.json версию 6.3.* и чтобы при использовании composer update версия WordPress автоматически обновилась до последних патчей (security, bugfixes) ядра. Каждый раз нам необходимо будет обновиться — нам нужно будет обновлять версии в composer.json в репозитории и пакете вручную, что может вызывать трудности если вы используете автообновление пакетов.

Чтобы избавиться от этого недостатка можно использовать подход описанный в репозитории Composer Repository for WordPress core instalation.

Пример как это выглядит:

{
    "repositories": [
        {
            "type": "composer",
            "url": "https://raw.githubusercontent.com/doiftrue/wordpress-composer-repo/main/repo/new-bundled"
        }
    ],
    "require": {
        "wordpress/wordpress": "6.3.*"
    },
    "scripts": {
        "post-autoload-dump": "rsync -a --exclude={wp-content/,wp-config-sample.php} ./vendor/wordpress/wordpress/* ./"
    }
}

Этот способ позволит при использовании composer update, обновить WP до новой версии патча, если он появится.

Конечно этот вариант предоставляет несомненное удобство и нативную возможность обновления ядра WordPress через composer update, но у него так-же есть один недостаток — безопасность.
Репозитории могут быть взломаны, код изменен, пакеты обновлены, а сайты которые их используют будут зажарены.

Так или иначе мы все-равно используем неизвестные пакеты или open source скрипты в наших проектах. И каким вариантом пользоваться, полностью зависит от требований вашего проекта или от одобрения команды security.

Подводя итог

Какой вариант больше подходит конечно же решать вам. Если у вас уже устоявшийся проект, развивающийся не один год, а вы не тот разработчик который ведет его с самого основания, то я бы не рекомендовал вам переходить на вариант с «Установкой WordPress в отдельную директорию». Лучше рассмотреть вариант с «Классической структурой файлов». В этом случае у вас риск что-то сломать отсутствует.
В то время как вариант «Установки WP в отдельную директорию» больше подойдет для новых проектов. С ним вы сможете огранизовать более удобную файловую структуру проекта, не боясь сломать.

Не стейсняйтесь рассказывать своим коллегам об этом подходе и применять на проектах.

Это первая статья из серии двух статей Использование Composer в WordPress.
Вторая статья про установку плагинов через WordPress повится чуть позже.

4 комментария на «“Установка WordPress через Composer”»

  1. Файл composer.json не нужно создавать руками, нужно просто выполнить:

    composer init

    И ответить на вопросы.

    Для копирования ядра в нужную папку можно использовать composer/installers, тогда папку для установки можно задачь через:

    "extra": {
    "wordpress-install-dir": "core"
    },

    • Про создание файла composer.json поправил, спасибо.
      composer/installers не поддерживает тип wordpress-core. Возможно ты имел ввиду johnpbloch/wordpress-core-installer, но с ним была раньше проблема, что в случае удаления директории ядра WP, то installer повторно не установит его и начинаются танцы с бубном. Именно по этой причине мне нравится вариант с composer scripts, который гарантированно после composer install скопирует файлы WordPress из vendor и заменит их в целевой директории:

      "scripts": {
      "post-install-cmd": "mkdir -p ./wp && cp -r ./vendor/wordpress/wordpress/* ./wp"
      }

  2. Событие `post-install-cmd` не срабатывает при `composer update`, только при `composer install`.

    Тут наверное `post-autoload-dump` событие лучше подходит. Из доки:

    > post-autoload-dump: occurs after the autoloader has been dumped, either during install/update, or via the dump-autoload command.

  3. Так как тут мы вручную создаем репозиторий, то думаю можно вместо
    "type": "wordpress-core",
    Указать
    "type": "wordpress-dropin",
    wordpress-dropin все равно используется чуть чаще чем никогда.

    И тогда можно будет использовать родной composer/installers так:

    "extra": {
    "installer-paths": {
    "wp/": ["wordpress/wordpress"]
    }
    },

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *