Spec-Zone.ru › CodeIgniter 4

Библиотека Publisher

Библиотека Publisher предоставляет средства для копирования файлов в проекте с использованием надежного обнаружения и проверки ошибок.

  • Загрузка библиотеки
  • Концепция и использование
    • По требованию
    • Автоматизация и обнаружение
    • Безопасность
  • Примеры
    • Пример синхронизации файлов
    • Пример зависимостей ресурсов
    • Пример развертывания модуля
  • Справочник по библиотеке
    • Поддерживающие методы
    • Вывод файлов

Загрузка библиотеки

Поскольку экземпляры Publisher специфичны для своего источника и назначения, эта библиотека недоступна через Services, но должна быть создана или расширена напрямую. Например:

$publisher = new CodeIgniterPublisherPublisher();

Концепция и использование

Publisher решает ряд распространённых проблем при работе с бэкенд-фреймворком:

  • Как поддерживать ресурсы проекта с зависимостями версий?
  • Как управлять загрузками и другими «динамическими» файлами, которые должны быть доступны через веб?
  • Как обновить проект при изменении фреймворка или модулей?
  • Как компоненты могут вставлять новый контент в существующие проекты?

В самом простом виде публикация сводится к копированию файлов в проект. Publisher расширяет FileCollection для реализации цепочки команд в стиле fluent для чтения, фильтрации и обработки входных файлов, а затем копирует или объединяет их в целевое место назначения. Вы можете использовать Publisher по требованию в своих контроллерах или других компонентах, или вы можете подготовить публикации, расширив класс и используя его обнаружение с помощью spark publish.

По требованию

Получите доступ к Publisher напрямую, создав новый экземпляр класса:

$publisher = new \CodeIgniter\Publisher\Publisher();

По умолчанию источник и место назначения будут установлены в ROOTPATH и FCPATH соответственно, что даёт Publisher лёгкий доступ для копирования любого файла из вашего проекта и размещения его в веб-доступе. В качестве альтернативы вы можете передать новый источник или источник и место назначения в конструктор:

use CodeIgniter\Publisher\Publisher;

$vendorPublisher = new Publisher(ROOTPATH . 'vendor');
$filterPublisher = new Publisher('/path/to/module/Filters', APPPATH . 'Filters');

// Once the source and destination are set you may start adding relative input files
$frameworkPublisher = new Publisher(ROOTPATH . 'vendor/codeigniter4/codeigniter4');

// All "path" commands are relative to $source
$frameworkPublisher->addPath('app/Config/Cookie.php');

// You may also add from outside the source, but the files will not be merged into subdirectories
$frameworkPublisher->addFiles([
    '/opt/mail/susan',
    '/opt/mail/ubuntu',
]);
$frameworkPublisher->addDirectory(SUPPORTPATH . 'Images');

После подготовки всех файлов используйте одну из команд вывода (copy() или merge()) для обработки подготовленных файлов в их место назначения(я):

// Place all files into $destination
$frameworkPublisher->copy();

// Place all files into $destination, overwriting existing files
$frameworkPublisher->copy(true);

// Place files into their relative $destination directories, overwriting and saving the boolean result
$result = $frameworkPublisher->merge(true);

Полное описание доступных методов см. в Справочнике по библиотеке.

Автоматизация и обнаружение

Вы можете иметь задачи публикации, встроенные в развертывание или обслуживание вашего приложения. Publisher использует мощный Autoloader для поиска всех дочерних классов, подготовленных к публикации:

use CodeIgniter\CLI\CLI;
use CodeIgniter\Publisher\Publisher;

foreach (Publisher::discover() as $publisher)
{
    $result = $publisher->publish();

    if ($result === false)
    {
        CLI::error(get_class($publisher) . ' failed to publish!', 'red');
    }
}

По умолчанию discover() будет искать папку «Publishers» во всех именованных пространствах, но вы можете указать другую папку, и она вернёт все найденные дочерние классы:

$memePublishers = Publisher::discover('CatGIFs');

В большинстве случаев вам не нужно обрабатывать обнаружение самостоятельно, просто используйте предоставленную команду «publish»:

> php spark publish

По умолчанию при расширении класса publish() добавит все файлы из $source и объединит их в место назначения, перезаписывая при столкновениях.

Безопасность

Чтобы предотвратить внедрение вредоносного кода модулями в ваши проекты, Publisher содержит конфигурационный файл, определяющий разрешённые каталоги и шаблоны файлов в качестве мест назначения. По умолчанию файлы могут быть опубликованы только в ваш проект (чтобы предотвратить доступ к остальной файловой системе), а папка public/ (FCPATH) будет получать только файлы с указанными расширениями: * Веб-ресурсы: css, scss, js, map * Неисполняемые веб-файлы: htm, html, xml, json, webmanifest * Шрифты: tff, eot, woff * Изображения: gif, jpg, jpeg, tiff, png, webp, bmp, ico, svg

Если вам нужно добавить или изменить безопасность для вашего проекта, измените свойство $restrictions объекта Config\Publisher.

Примеры

Вот несколько примеров вариантов использования и их реализации, которые помогут вам начать работу с публикацией.

Пример синхронизации файлов

Вы хотите отобразить изображение «Фото дня» на своей домашней странице. У вас есть лента ежедневных фотографий, но вам нужно поместить сам файл в доступную по веб-адресу локацию в вашем проекте в public/images/daily_photo.jpg. Вы можете настроить Настраиваемую команду для ежедневного запуска, которая будет обрабатывать это за вас:

<?php

namespace App\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\Publisher\Publisher;
use Throwable;

class DailyPhoto extends BaseCommand
{
    protected $group       = 'Publication';
    protected $name        = 'publish:daily';
    protected $description = 'Publishes the latest daily photo to the homepage.';

    public function run(array $params)
    {
        $publisher = new Publisher('/path/to/photos/', FCPATH . 'assets/images');

        try
        {
            $publisher->addPath('daily_photo.jpg')->copy(true); // `true` to enable overwrites
        }
        catch (Throwable $e)
        {
            $this->showError($e);
        }
    }
}

Теперь, выполняя spark publish:daily, вы будете поддерживать изображение на домашней странице в актуальном состоянии. А что, если фото поступает из внешнего API? Вы можете использовать addUri() вместо addPath() для загрузки удалённого ресурса и публикации его вместо этого:

$publisher->addUri('https://example.com/feeds/daily_photo.jpg')->copy(true);

Пример зависимостей ресурсов

Вы хотите интегрировать фронтенд-библиотеку «Bootstrap» в свой проект, но частые обновления затрудняют отслеживание. Вы можете создать определение публикации в своём проекте для синхронизации фронтенд-ресурсов, расширив Publisher в своём проекте. Таким образом, app/Publishers/BootstrapPublisher.php может выглядеть следующим образом:

<?php

namespace App\Publishers;

use CodeIgniter\Publisher\Publisher;

class BootstrapPublisher extends Publisher
{
    /**
     * Tell Publisher where to get the files.
     * Since we will use Composer to download
     * them we point to the "vendor" directory.
     *
     * @var string
     */
    protected $source = 'vendor/twbs/bootstrap/';

    /**
     * FCPATH is always the default destination,
     * but we may want them to go in a sub-folder
     * to keep things organized.
     *
     * @var string
     */
    protected $destination = FCPATH . 'bootstrap';

    /**
     * Use the "publish" method to indicate that this
     * class is ready to be discovered and automated.
     *
     * @return boolean
     */
    public function publish(): bool
    {
        return $this
            // Add all the files relative to $source
            ->addPath('dist')

            // Indicate we only want the minimized versions
            ->retainPattern('*.min.*')

            // Merge-and-replace to retain the original directory structure
            ->merge(true);
    }
}

Теперь добавьте зависимость через Composer и вызовите spark publish для запуска публикации:

> composer require twbs/bootstrap
> php spark publish

… и вы получите что-то вроде этого:

public/.htaccess
public/favicon.ico
public/index.php
public/robots.txt
public/
    bootstrap/
        css/
            bootstrap.min.css
            bootstrap-utilities.min.css.map
            bootstrap-grid.min.css
            bootstrap.rtl.min.css
            bootstrap.min.css.map
            bootstrap-reboot.min.css
            bootstrap-utilities.min.css
            bootstrap-reboot.rtl.min.css
            bootstrap-grid.min.css.map
        js/
            bootstrap.esm.min.js
            bootstrap.bundle.min.js.map
            bootstrap.bundle.min.js
            bootstrap.min.js
            bootstrap.esm.min.js.map
            bootstrap.min.js.map

Пример развертывания модуля

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

<?php

namespace Math\Auth\Commands;

use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\Publisher\Publisher;
use Throwable;

class AuthPublish extends BaseCommand
{
    protected $group       = 'Auth';
    protected $name        = 'auth:publish';
    protected $description = 'Publish Auth components into the current application.';

    public function run(array $params)
    {
        // Use the Autoloader to figure out the module path
        $source = service('autoloader')->getNamespace('Math\\Auth');

        $publisher = new Publisher($source, APPATH);

        try
        {
            // Add only the desired components
            $publisher->addPaths([
                'Controllers',
                'Database/Migrations',
                'Models',
            ])->merge(false); // Be careful not to overwrite anything
        }
        catch (Throwable $e)
        {
            $this->showError($e);
            return;
        }

        // If publication succeeded then update namespaces
        foreach ($publisher->getPublished() as $file)
        {
            // Replace the namespace
            $contents = file_get_contents($file);
            $contents = str_replace('namespace Math\\Auth', 'namespace ' . APP_NAMESPACE, );
            file_put_contents($file, $contents);
        }
    }
}

Теперь, когда пользователи вашего модуля запускают php spark auth:publish, они получат следующее дополнение в свой проект:

app/Controllers/AuthController.php
app/Database/Migrations/2017-11-20-223112_create_auth_tables.php.php
app/Models/LoginModel.php
app/Models/UserModel.php

Справочник по библиотеке

Примечание

Publisher является расширением FileCollection, поэтому имеет доступ ко всем этим методам для чтения и фильтрации файлов.

Поддерживающие методы

[static] discover(string $directory = ‘Publishers’): Publisher[]

Обнаруживает и возвращает все Publisher в указанном каталоге пространства имён. Например, если существуют как app/Publishers/FrameworkPublisher.php, так и myModule/src/Publishers/AssetPublisher.php, и оба являются расширениями Publisher, то Publisher::discover() вернёт экземпляр каждого из них.

publish(): bool

Обрабатывает полную цепочку вход-обработка-вывод. По умолчанию это эквивалентно вызову addPath($source) и merge(true), но дочерние классы, как правило, предоставляют собственную реализацию. publish() вызывается для всех обнаруженных Publisher при запуске spark publish. Возвращает результат успешного или неудачного выполнения.

getScratch(): string

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

getErrors(): array<string,Throwable>

Возвращает все ошибки из последней операции записи. Ключи массива — это файлы, вызвавшие ошибку, а значения — пойманные исключения Throwable. Используйте getMessage() на исключении Throwable, чтобы получить сообщение об ошибке.

addPath(string $path, bool $recursive = true) addPaths(array $path, bool $recursive = true)

Добавляет все файлы, указанные относительными путями. Пути — это ссылки на реальные файлы или каталоги, относительные к $source. Если относительный путь разрешается на каталог, то $recursive будет включать подкаталоги.

addUri(string $uri) addUris(array $uris)

Загружает содержимое URI с помощью CURLRequest во временную рабочую область, а затем добавляет полученный файл в список.

Примечание

Выполняемый запрос CURL является простым GET и использует тело ответа для содержимого файла. Для некоторых удалённых файлов может потребоваться настроить специальный запрос для правильной обработки.

Вывод файлов

wipe()

Удаляет все файлы, каталоги и подкаталоги из $destination.

Важно

Используйте с осторожностью.

copy(bool $replace = true): bool

Копирует все файлы в $destination. Структура каталогов не воссоздаётся, поэтому каждый файл из текущего списка окажется в одном и том же каталоге назначения. Использование $replace приведёт к перезаписи файлов, когда уже существует файл с таким же именем. Возвращает результат успешного или неудачного выполнения, используйте getPublished() и getErrors() для устранения неполадок. Имейте в виду потенциальные коллизии с одинаковыми базовыми именами, например:

$publisher = new Publisher('/home/source', '/home/destination');
$publisher->addPaths([
    'pencil/lead.png',
    'metal/lead.png',
]);

// This is bad! Only one file will remain at /home/destination/lead.png
$publisher->copy(true);

merge(bool $replace = true): bool

Копирует все файлы в $destination в соответствующих относительных подкаталогах. Любые файлы, соответствующие $source будут помещены в аналогичные каталоги в $destination, эффективно выполняя операцию «зеркального отображения» или «rsync». Использование $replace приведёт к перезаписи файлов, когда уже существует файл; так как каталоги объединяются, это не повлияет на другие файлы в месте назначения. Возвращает результат успешного или неудачного выполнения, используйте getPublished() и getErrors() для устранения неполадок.

Пример:

$publisher = new Publisher('/home/source', '/home/destination');
$publisher->addPaths([
    'pencil/lead.png',
    'metal/lead.png',
]);

// Results in "/home/destination/pencil/lead.png" and "/home/destination/metal/lead.png"
$publisher->merge();

© 2014–2020 British Columbia Institute of Technology
Licensed under the MIT License.
https://codeigniter.com/user_guide/libraries/publisher.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API