CodeIgniter4/libraries/publisher.html
2025-02-07 17:48:15 +00:00

878 lines
73 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html class="writer-html5" lang="en">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.19: https://docutils.sourceforge.io/" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Publisher &mdash; CodeIgniter 4.6.0 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/css/citheme.css" />
<link rel="stylesheet" type="text/css" href="../_static/css/citheme_dark.css" />
<link rel="shortcut icon" href="../_static/favicon.ico"/>
<!--[if lt IE 9]>
<script src="../_static/js/html5shiv.min.js"></script>
<![endif]-->
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/sphinx_highlight.js"></script>
<script src="../_static/js/citheme.js"></script>
<script src="../_static/js/carbon.js"></script>
<script src="../_static/js/theme.js"></script>
<link rel="index" title="Index" href="../genindex.html" />
<link rel="search" title="Search" href="../search.html" />
<link rel="next" title="Security" href="security.html" />
<link rel="prev" title="Pagination" href="pagination.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="../index.html">
<img src="../_static/ci-logo-text.svg" class="logo" alt="Logo"/>
</a>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="../search.html" method="get">
<input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../intro/index.html">Welcome to CodeIgniter4</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../intro/index.html">Welcome to CodeIgniter4</a></li>
<li class="toctree-l2"><a class="reference internal" href="../intro/requirements.html">Server Requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="../intro/credits.html">Credits</a></li>
<li class="toctree-l2"><a class="reference internal" href="../intro/psr.html">PSR Compliance</a></li>
<li class="toctree-l2"><a class="reference internal" href="../license.html">License Agreement</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../installation/index.html">Installation</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../installation/installing_composer.html">Composer Installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/installing_manual.html">Manual Installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/running.html">Running Your App</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/troubleshooting.html">Troubleshooting</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/deployment.html">Deployment</a></li>
<li class="toctree-l2"><a class="reference internal" href="../changelogs/index.html">Change Logs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/upgrading.html">Upgrading From a Previous Version</a></li>
<li class="toctree-l2"><a class="reference internal" href="../installation/repositories.html">CodeIgniter Repositories</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../tutorial/index.html">Build Your First Application</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../tutorial/static_pages.html">Static Pages</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorial/news_section.html">News Section</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorial/create_news_items.html">Create News Items</a></li>
<li class="toctree-l2"><a class="reference internal" href="../tutorial/conclusion.html">Conclusion</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../concepts/index.html">CodeIgniter4 Overview</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../concepts/structure.html">Application Structure</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/mvc.html">Models, Views, and Controllers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/autoloader.html">Autoloading Files</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/services.html">Services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/factories.html">Factories</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/http.html">Working with HTTP Requests</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/security.html">Security Guidelines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../concepts/goals.html">Design and Architectural Goals</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../general/index.html">General Topics</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../general/configuration.html">Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/urls.html">CodeIgniter URLs</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/helpers.html">Helper Functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/common_functions.html">Global Functions and Constants</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/logging.html">Logging Information</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/errors.html">Error Handling</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/caching.html">Web Page Caching</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/ajax.html">AJAX Requests</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/modules.html">Code Modules</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/managing_apps.html">Managing your Applications</a></li>
<li class="toctree-l2"><a class="reference internal" href="../general/environments.html">Handling Multiple Environments</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../incoming/index.html">Controllers and Routing</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../incoming/routing.html">URI Routing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/controllers.html">Controllers</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/filters.html">Controller Filters</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/auto_routing_improved.html">Auto Routing (Improved)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/message.html">HTTP Messages</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/request.html">Request Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/incomingrequest.html">IncomingRequest Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/content_negotiation.html">Content Negotiation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/methodspoofing.html">HTTP Method Spoofing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../incoming/restful.html">RESTful Resource Handling</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../outgoing/index.html">Building Responses</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/views.html">Views</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/view_renderer.html">View Renderer</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/view_layouts.html">View Layouts</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/view_cells.html">View Cells</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/view_parser.html">View Parser</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/view_decorators.html">View Decorators</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/table.html">HTML Table Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/response.html">HTTP Responses</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/api_responses.html">API Response Trait</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/csp.html">Content Security Policy</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/localization.html">Localization</a></li>
<li class="toctree-l2"><a class="reference internal" href="../outgoing/alternative_php.html">Alternate PHP Syntax for View Files</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../database/index.html">Working with Databases</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../database/examples.html">Quick Start: Usage Examples</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/configuration.html">Database Configuration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/connecting.html">Connecting to a Database</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/queries.html">Running Queries</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/results.html">Generating Query Results</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/helpers.html">Query Helper Methods</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/query_builder.html">Query Builder Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/transactions.html">Transactions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/metadata.html">Getting Metadata</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/call_function.html">Custom Function Calls</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/events.html">Database Events</a></li>
<li class="toctree-l2"><a class="reference internal" href="../database/utilities.html">Database Utilities</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../models/index.html">Modeling Data</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../models/model.html">Using CodeIgniter's Model</a></li>
<li class="toctree-l2"><a class="reference internal" href="../models/entities.html">Using Entity Classes</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../dbmgmt/index.html">Managing Databases</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../dbmgmt/forge.html">Database Forge</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dbmgmt/migration.html">Database Migrations</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dbmgmt/seeds.html">Database Seeding</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dbmgmt/db_commands.html">Database Commands</a></li>
</ul>
</li>
</ul>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="index.html">Library Reference</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="caching.html">Caching Driver</a></li>
<li class="toctree-l2"><a class="reference internal" href="cookies.html">Cookies</a></li>
<li class="toctree-l2"><a class="reference internal" href="cors.html">Cross-Origin Resource Sharing (CORS)</a></li>
<li class="toctree-l2"><a class="reference internal" href="curlrequest.html">CURLRequest Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="email.html">Email Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="encryption.html">Encryption Service</a></li>
<li class="toctree-l2"><a class="reference internal" href="files.html">Working with Files</a></li>
<li class="toctree-l2"><a class="reference internal" href="file_collections.html">File Collections</a></li>
<li class="toctree-l2"><a class="reference internal" href="honeypot.html">Honeypot Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="images.html">Image Manipulation Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="pagination.html">Pagination</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">Publisher</a></li>
<li class="toctree-l2"><a class="reference internal" href="security.html">Security</a></li>
<li class="toctree-l2"><a class="reference internal" href="sessions.html">Session Library</a></li>
<li class="toctree-l2"><a class="reference internal" href="throttler.html">Throttler</a></li>
<li class="toctree-l2"><a class="reference internal" href="time.html">Times and Dates</a></li>
<li class="toctree-l2"><a class="reference internal" href="typography.html">Typography</a></li>
<li class="toctree-l2"><a class="reference internal" href="uploaded_files.html">Working with Uploaded Files</a></li>
<li class="toctree-l2"><a class="reference internal" href="uri.html">Working with URIs</a></li>
<li class="toctree-l2"><a class="reference internal" href="user_agent.html">User Agent Class</a></li>
<li class="toctree-l2"><a class="reference internal" href="validation.html">Validation</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../helpers/index.html">Helpers</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../helpers/array_helper.html">Array Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/cookie_helper.html">Cookie Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/date_helper.html">Date Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/filesystem_helper.html">Filesystem Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/form_helper.html">Form Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/html_helper.html">HTML Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/inflector_helper.html">Inflector Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/number_helper.html">Number Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/security_helper.html">Security Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/test_helper.html">Test Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/text_helper.html">Text Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/url_helper.html">URL Helper</a></li>
<li class="toctree-l2"><a class="reference internal" href="../helpers/xml_helper.html">XML Helper</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../testing/index.html">Testing</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../testing/overview.html">Getting Started</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/database.html">Database</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/fabricator.html">Generating Data</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/controllers.html">Controller Testing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/feature.html">HTTP Testing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/response.html">Testing Responses</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/cli.html">Testing CLI Commands</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/mocking.html">Mocking</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/benchmark.html">Benchmarking</a></li>
<li class="toctree-l2"><a class="reference internal" href="../testing/debugging.html">Debugging Your Application</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../cli/index.html">Command Line Usage</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../cli/cli_overview.html">CLI Overview</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cli/cli_controllers.html">Running Controllers via CLI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cli/spark_commands.html">Spark Commands</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cli/cli_commands.html">Creating Spark Commands</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cli/cli_generators.html">CLI Generators</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cli/cli_library.html">CLI Library</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cli/cli_request.html">CLIRequest Class</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../extending/index.html">Extending CodeIgniter</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../extending/core_classes.html">Creating Core System Classes</a></li>
<li class="toctree-l2"><a class="reference internal" href="../extending/common.html">Replacing Common Functions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../extending/events.html">Events</a></li>
<li class="toctree-l2"><a class="reference internal" href="../extending/basecontroller.html">Extending the Controller</a></li>
<li class="toctree-l2"><a class="reference internal" href="../extending/authentication.html">Authentication</a></li>
<li class="toctree-l2"><a class="reference internal" href="../extending/composer_packages.html">Creating Composer Packages</a></li>
<li class="toctree-l2"><a class="reference internal" href="../extending/contributing.html">Contributing to CodeIgniter</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="official_packages.html">Official Packages</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="../index.html">CodeIgniter</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<a class="btn btn-neutral float-right" href="https://github.com/codeigniter4/CodeIgniter4/edit/develop/user_guide_src/source/libraries/publisher.rst">Edit this page</a>
<div role="navigation" aria-label="Page navigation">
<ul class="wy-breadcrumbs">
<li><a href="../index.html" class="icon icon-home" aria-label="Home"></a></li>
<li class="breadcrumb-item"><a href="index.html">Library Reference</a></li>
<li class="breadcrumb-item active">Publisher</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<section id="publisher">
<h1>Publisher<a class="headerlink" href="#publisher" title="Permalink to this heading"></a></h1>
<p>The Publisher library provides a means to copy files within a project using robust detection and error checking.</p>
<nav class="contents local" id="contents">
<ul class="simple">
<li><p><a class="reference internal" href="#loading-the-library" id="id2">Loading the Library</a></p></li>
<li><p><a class="reference internal" href="#concept-and-usage" id="id3">Concept and Usage</a></p>
<ul>
<li><p><a class="reference internal" href="#on-demand" id="id4">On Demand</a></p></li>
<li><p><a class="reference internal" href="#automation-and-discovery" id="id5">Automation and Discovery</a></p></li>
<li><p><a class="reference internal" href="#security" id="id6">Security</a></p></li>
</ul>
</li>
<li><p><a class="reference internal" href="#examples" id="id7">Examples</a></p>
<ul>
<li><p><a class="reference internal" href="#file-sync-example" id="id8">File Sync Example</a></p></li>
<li><p><a class="reference internal" href="#asset-dependencies-example" id="id9">Asset Dependencies Example</a></p></li>
<li><p><a class="reference internal" href="#module-deployment-example" id="id10">Module Deployment Example</a></p></li>
</ul>
</li>
<li><p><a class="reference internal" href="#library-reference" id="id11">Library Reference</a></p>
<ul>
<li><p><a class="reference internal" href="#support-methods" id="id12">Support Methods</a></p></li>
<li><p><a class="reference internal" href="#outputting-files" id="id13">Outputting Files</a></p></li>
<li><p><a class="reference internal" href="#modifying-files" id="id14">Modifying Files</a></p></li>
</ul>
</li>
</ul>
</nav>
<section id="loading-the-library">
<h2><a class="toc-backref" href="#id2" role="doc-backlink">Loading the Library</a><a class="headerlink" href="#loading-the-library" title="Permalink to this heading"></a></h2>
<p>Because Publisher instances are specific to their source and destination this library is not available
through <code class="docutils literal notranslate"><span class="pre">Services</span></code> but should be instantiated or extended directly. E.g.:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\CodeIgniter\Publisher\Publisher</span><span class="p">();</span>
</pre></div>
</div>
</section>
<section id="concept-and-usage">
<h2><a class="toc-backref" href="#id3" role="doc-backlink">Concept and Usage</a><a class="headerlink" href="#concept-and-usage" title="Permalink to this heading"></a></h2>
<p><code class="docutils literal notranslate"><span class="pre">Publisher</span></code> solves a handful of common problems when working within a backend framework:</p>
<ul class="simple">
<li><p>How do I maintain project assets with version dependencies?</p></li>
<li><p>How do I manage uploads and other “dynamic” files that need to be web accessible?</p></li>
<li><p>How can I update my project when the framework or modules change?</p></li>
<li><p>How can components inject new content into existing projects?</p></li>
</ul>
<p>At its most basic, publishing amounts to copying a file or files into a project. <code class="docutils literal notranslate"><span class="pre">Publisher</span></code> extends <code class="docutils literal notranslate"><span class="pre">FileCollection</span></code>
to enact fluent-style command chaining to read, filter, and process input files, then copies or merges them into the target destination.
You may use <code class="docutils literal notranslate"><span class="pre">Publisher</span></code> on demand in your Controllers or other components, or you may stage publications by extending
the class and leveraging its discovery with <code class="docutils literal notranslate"><span class="pre">spark</span> <span class="pre">publish</span></code>.</p>
<section id="on-demand">
<h3><a class="toc-backref" href="#id4" role="doc-backlink">On Demand</a><a class="headerlink" href="#on-demand" title="Permalink to this heading"></a></h3>
<p>Access <code class="docutils literal notranslate"><span class="pre">Publisher</span></code> directly by instantiating a new instance of the class:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\CodeIgniter\Publisher\Publisher</span><span class="p">();</span>
</pre></div>
</div>
<p>By default the source and destination will be set to <code class="docutils literal notranslate"><span class="pre">ROOTPATH</span></code> and <code class="docutils literal notranslate"><span class="pre">FCPATH</span></code> respectively, giving <code class="docutils literal notranslate"><span class="pre">Publisher</span></code>
easy access to take any file from your project and make it web-accessible. Alternatively you may pass a new source
or source and destination into the constructor:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$vendorPublisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="nx">ROOTPATH</span> <span class="o">.</span> <span class="s1">&#39;vendor&#39;</span><span class="p">);</span>
<span class="nv">$filterPublisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="s1">&#39;/path/to/module/Filters&#39;</span><span class="p">,</span> <span class="nx">APPPATH</span> <span class="o">.</span> <span class="s1">&#39;Filters&#39;</span><span class="p">);</span>
<span class="c1">// Once the source and destination are set you may start adding relative input files</span>
<span class="nv">$frameworkPublisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="nx">ROOTPATH</span> <span class="o">.</span> <span class="s1">&#39;vendor/codeigniter4/codeigniter4&#39;</span><span class="p">);</span>
<span class="c1">// All &quot;path&quot; commands are relative to $source</span>
<span class="nv">$frameworkPublisher</span><span class="o">-&gt;</span><span class="na">addPath</span><span class="p">(</span><span class="s1">&#39;app/Config/Cookie.php&#39;</span><span class="p">);</span>
<span class="c1">// You may also add from outside the source, but the files will not be merged into subdirectories</span>
<span class="nv">$frameworkPublisher</span><span class="o">-&gt;</span><span class="na">addFiles</span><span class="p">([</span>
<span class="s1">&#39;/opt/mail/susan&#39;</span><span class="p">,</span>
<span class="s1">&#39;/opt/mail/ubuntu&#39;</span><span class="p">,</span>
<span class="p">]);</span>
<span class="nv">$frameworkPublisher</span><span class="o">-&gt;</span><span class="na">addDirectory</span><span class="p">(</span><span class="nx">SUPPORTPATH</span> <span class="o">.</span> <span class="s1">&#39;Images&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>Once all the files are staged use one of the output commands (<strong>copy()</strong> or <strong>merge()</strong>) to process the staged files
to their destination(s):</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="c1">// Place all files into $destination</span>
<span class="nv">$frameworkPublisher</span><span class="o">-&gt;</span><span class="na">copy</span><span class="p">();</span>
<span class="c1">// Place all files into $destination, overwriting existing files</span>
<span class="nv">$frameworkPublisher</span><span class="o">-&gt;</span><span class="na">copy</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="c1">// Place files into their relative $destination directories, overwriting and saving the boolean result</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nv">$frameworkPublisher</span><span class="o">-&gt;</span><span class="na">merge</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
</pre></div>
</div>
<p>See the <a class="reference internal" href="#reference"><span class="std std-ref">Library Reference</span></a> for a full description of available methods.</p>
</section>
<section id="automation-and-discovery">
<h3><a class="toc-backref" href="#id5" role="doc-backlink">Automation and Discovery</a><a class="headerlink" href="#automation-and-discovery" title="Permalink to this heading"></a></h3>
<p>You may have regular publication tasks embedded as part of your application deployment or upkeep. <code class="docutils literal notranslate"><span class="pre">Publisher</span></code> leverages
the powerful <code class="docutils literal notranslate"><span class="pre">Autoloader</span></code> to locate any child classes primed for publication:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\CLI\CLI</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nx">Publisher</span><span class="o">::</span><span class="na">discover</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$publisher</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$result</span> <span class="o">=</span> <span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">publish</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$result</span> <span class="o">===</span> <span class="k">false</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">CLI</span><span class="o">::</span><span class="na">error</span><span class="p">(</span><span class="nv">$publisher</span><span class="o">::</span><span class="na">class</span> <span class="o">.</span> <span class="s1">&#39; failed to publish!&#39;</span><span class="p">,</span> <span class="s1">&#39;red&#39;</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>By default <code class="docutils literal notranslate"><span class="pre">discover()</span></code> will search for the “Publishers” directory across all namespaces, but you may specify a
different directory and it will return any child classes found:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$memePublishers</span> <span class="o">=</span> <span class="nx">Publisher</span><span class="o">::</span><span class="na">discover</span><span class="p">(</span><span class="s1">&#39;CatGIFs&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>Most of the time you will not need to handle your own discovery, just use the provided “publish” command:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">php spark publish</span>
</pre></div>
</div>
<p>By default on your class extension <code class="docutils literal notranslate"><span class="pre">publish()</span></code> will add all files from your <code class="docutils literal notranslate"><span class="pre">$source</span></code> and merge them
out to your destination, overwriting on collision.</p>
<section id="discovery-in-a-specific-namespace">
<span id="id1"></span><h4>Discovery in a specific namespace<a class="headerlink" href="#discovery-in-a-specific-namespace" title="Permalink to this heading"></a></h4>
<div class="versionadded">
<p><span class="versionmodified added">New in version 4.6.0.</span></p>
</div>
<p>Since v4.6.0, you can also scan a specific namespace. This not only reduces the number of files to be scanned,
but also avoids the need to rerun a Publisher. All you need to do is specify the desired root namespace in the
second parameter of the <code class="docutils literal notranslate"><span class="pre">discover()</span></code> method.</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$memePublishers</span> <span class="o">=</span> <span class="nx">Publisher</span><span class="o">::</span><span class="na">discover</span><span class="p">(</span><span class="s1">&#39;Publishers&#39;</span><span class="p">,</span> <span class="s1">&#39;Namespace\Vendor\Package&#39;</span><span class="p">);</span>
</pre></div>
</div>
<p>The specified namespace must be known to CodeIgniter. You can check the list of all namespaces using the “spark namespaces” command:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">php spark namespaces</span>
</pre></div>
</div>
<p>The “publish” command also offers the <code class="docutils literal notranslate"><span class="pre">--namespace</span></code> option to define the namespace when searching for Publishers that might come from a library.</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">php spark publish --namespace Namespace\Vendor\Package</span>
</pre></div>
</div>
</section>
</section>
<section id="security">
<h3><a class="toc-backref" href="#id6" role="doc-backlink">Security</a><a class="headerlink" href="#security" title="Permalink to this heading"></a></h3>
<p>In order to prevent modules from injecting malicious code into your projects, <code class="docutils literal notranslate"><span class="pre">Publisher</span></code> contains a config file
that defines which directories and file patterns are allowed as destinations. By default, files may only be published
to your project (to prevent access to the rest of the filesystem), and the <strong>public/</strong> folder (<code class="docutils literal notranslate"><span class="pre">FCPATH</span></code>) will only
receive files with the following extensions:</p>
<ul class="simple">
<li><p>Web assets: css, scss, js, map</p></li>
<li><p>Non-executable web files: htm, html, xml, json, webmanifest</p></li>
<li><p>Fonts: ttf, eot, woff, woff2</p></li>
<li><p>Images: gif, jpg, jpeg, tif, tiff, png, webp, bmp, ico, svg</p></li>
</ul>
<p>If you need to add or adjust the security for your project then alter the <code class="docutils literal notranslate"><span class="pre">$restrictions</span></code> property of <code class="docutils literal notranslate"><span class="pre">Config\Publisher</span></code> in <strong>app/Config/Publisher.php</strong>.</p>
</section>
</section>
<section id="examples">
<h2><a class="toc-backref" href="#id7" role="doc-backlink">Examples</a><a class="headerlink" href="#examples" title="Permalink to this heading"></a></h2>
<p>Here are a handful of example use cases and their implementations to help you get started publishing.</p>
<section id="file-sync-example">
<h3><a class="toc-backref" href="#id8" role="doc-backlink">File Sync Example</a><a class="headerlink" href="#file-sync-example" title="Permalink to this heading"></a></h3>
<p>You want to display a “photo of the day” image on your homepage. You have a feed for daily photos but you
need to get the actual file into a browsable location in your project at <strong>public/images/daily_photo.jpg</strong>.
You can set up <a class="reference internal" href="../cli/cli_commands.html"><span class="doc">Custom Command</span></a> to run daily that will handle this for you:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">namespace</span> <span class="nx">App\Commands</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">CodeIgniter\CLI\BaseCommand</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Throwable</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">DailyPhoto</span> <span class="k">extends</span> <span class="nx">BaseCommand</span>
<span class="p">{</span>
<span class="k">protected</span> <span class="nv">$group</span> <span class="o">=</span> <span class="s1">&#39;Publication&#39;</span><span class="p">;</span>
<span class="k">protected</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">&#39;publish:daily&#39;</span><span class="p">;</span>
<span class="k">protected</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">&#39;Publishes the latest daily photo to the homepage.&#39;</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">run</span><span class="p">(</span><span class="k">array</span> <span class="nv">$params</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="s1">&#39;/path/to/photos/&#39;</span><span class="p">,</span> <span class="nx">FCPATH</span> <span class="o">.</span> <span class="s1">&#39;assets/images&#39;</span><span class="p">);</span>
<span class="k">try</span> <span class="p">{</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addPath</span><span class="p">(</span><span class="s1">&#39;daily_photo.jpg&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">copy</span><span class="p">(</span><span class="k">true</span><span class="p">);</span> <span class="c1">// `true` to enable overwrites</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">Throwable</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">showError</span><span class="p">(</span><span class="nv">$e</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now running <code class="docutils literal notranslate"><span class="pre">spark</span> <span class="pre">publish:daily</span></code> will keep your homepages image up-to-date. What if the photo is
coming from an external API? You can use <code class="docutils literal notranslate"><span class="pre">addUri()</span></code> in place of <code class="docutils literal notranslate"><span class="pre">addPath()</span></code> to download the remote
resource and publish it out instead:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addUri</span><span class="p">(</span><span class="s1">&#39;https://example.com/feeds/daily_photo.jpg&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">copy</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
</pre></div>
</div>
</section>
<section id="asset-dependencies-example">
<h3><a class="toc-backref" href="#id9" role="doc-backlink">Asset Dependencies Example</a><a class="headerlink" href="#asset-dependencies-example" title="Permalink to this heading"></a></h3>
<p>You want to integrate the frontend library “Bootstrap” into your project, but the frequent updates makes it a hassle
to keep up with. You can create a publication definition in your project to sync frontend assets by extending
<code class="docutils literal notranslate"><span class="pre">Publisher</span></code> in your project. So <strong>app/Publishers/BootstrapPublisher.php</strong> might look like this:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">namespace</span> <span class="nx">App\Publishers</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">BootstrapPublisher</span> <span class="k">extends</span> <span class="nx">Publisher</span>
<span class="p">{</span>
<span class="sd">/**</span>
<span class="sd"> * Tell Publisher where to get the files.</span>
<span class="sd"> * Since we will use Composer to download</span>
<span class="sd"> * them we point to the &quot;vendor&quot; directory.</span>
<span class="sd"> *</span>
<span class="sd"> * @var string</span>
<span class="sd"> */</span>
<span class="k">protected</span> <span class="nv">$source</span> <span class="o">=</span> <span class="nx">VENDORPATH</span> <span class="o">.</span> <span class="s1">&#39;twbs/bootstrap/&#39;</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * FCPATH is always the default destination,</span>
<span class="sd"> * but we may want them to go in a sub-folder</span>
<span class="sd"> * to keep things organized.</span>
<span class="sd"> *</span>
<span class="sd"> * @var string</span>
<span class="sd"> */</span>
<span class="k">protected</span> <span class="nv">$destination</span> <span class="o">=</span> <span class="nx">FCPATH</span> <span class="o">.</span> <span class="s1">&#39;bootstrap&#39;</span><span class="p">;</span>
<span class="sd">/**</span>
<span class="sd"> * Use the &quot;publish&quot; method to indicate that this</span>
<span class="sd"> * class is ready to be discovered and automated.</span>
<span class="sd"> */</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">publish</span><span class="p">()</span><span class="o">:</span> <span class="nx">bool</span>
<span class="p">{</span>
<span class="k">return</span> <span class="nv">$this</span>
<span class="c1">// Add all the files relative to $source</span>
<span class="o">-&gt;</span><span class="na">addPath</span><span class="p">(</span><span class="s1">&#39;dist&#39;</span><span class="p">)</span>
<span class="c1">// Indicate we only want the minimized versions</span>
<span class="o">-&gt;</span><span class="na">retainPattern</span><span class="p">(</span><span class="s1">&#39;*.min.*&#39;</span><span class="p">)</span>
<span class="c1">// Merge-and-replace to retain the original directory structure</span>
<span class="o">-&gt;</span><span class="na">merge</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>Directory <code class="docutils literal notranslate"><span class="pre">$destination</span></code> must be created before executing the command.</p>
</div>
<p>Now add the dependency via Composer and call <code class="docutils literal notranslate"><span class="pre">spark</span> <span class="pre">publish</span></code> to run the publication:</p>
<div class="highlight-console notranslate"><div class="highlight"><pre><span></span><span class="go">composer require twbs/bootstrap</span>
<span class="go">php spark publish</span>
</pre></div>
</div>
<p>… and youll end up with something like this:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="k">public</span><span class="o">/.</span><span class="nx">htaccess</span>
<span class="k">public</span><span class="o">/</span><span class="nx">favicon</span><span class="o">.</span><span class="nx">ico</span>
<span class="k">public</span><span class="o">/</span><span class="nx">index</span><span class="o">.</span><span class="nx">php</span>
<span class="k">public</span><span class="o">/</span><span class="nx">robots</span><span class="o">.</span><span class="nx">txt</span>
<span class="k">public</span><span class="o">/</span>
<span class="nx">bootstrap</span><span class="o">/</span>
<span class="nx">css</span><span class="o">/</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span>
<span class="nx">bootstrap</span><span class="o">-</span><span class="nx">utilities</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span><span class="o">.</span><span class="nx">map</span>
<span class="nx">bootstrap</span><span class="o">-</span><span class="nx">grid</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nx">rtl</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span><span class="o">.</span><span class="nx">map</span>
<span class="nx">bootstrap</span><span class="o">-</span><span class="nx">reboot</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span>
<span class="nx">bootstrap</span><span class="o">-</span><span class="nx">utilities</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span>
<span class="nx">bootstrap</span><span class="o">-</span><span class="nx">reboot</span><span class="o">.</span><span class="nx">rtl</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span>
<span class="nx">bootstrap</span><span class="o">-</span><span class="nx">grid</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">css</span><span class="o">.</span><span class="nx">map</span>
<span class="nx">js</span><span class="o">/</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nx">esm</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">js</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nx">bundle</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">js</span><span class="o">.</span><span class="nx">map</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nx">bundle</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">js</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">js</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nx">esm</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">js</span><span class="o">.</span><span class="nx">map</span>
<span class="nx">bootstrap</span><span class="o">.</span><span class="nb">min</span><span class="o">.</span><span class="nx">js</span><span class="o">.</span><span class="nx">map</span>
</pre></div>
</div>
</section>
<section id="module-deployment-example">
<h3><a class="toc-backref" href="#id10" role="doc-backlink">Module Deployment Example</a><a class="headerlink" href="#module-deployment-example" title="Permalink to this heading"></a></h3>
<p>You want to allow developers using your popular authentication module the ability to expand on the default behavior
of your Migration, Controller, and Model. You can create your own module “publish” command to inject these components
into an application for use:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">namespace</span> <span class="nx">Math\Auth\Commands</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">CodeIgniter\CLI\BaseCommand</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="k">use</span> <span class="nx">Throwable</span><span class="p">;</span>
<span class="k">class</span> <span class="nc">AuthPublish</span> <span class="k">extends</span> <span class="nx">BaseCommand</span>
<span class="p">{</span>
<span class="k">protected</span> <span class="nv">$group</span> <span class="o">=</span> <span class="s1">&#39;Auth&#39;</span><span class="p">;</span>
<span class="k">protected</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s1">&#39;auth:publish&#39;</span><span class="p">;</span>
<span class="k">protected</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s1">&#39;Publish Auth components into the current application.&#39;</span><span class="p">;</span>
<span class="k">public</span> <span class="k">function</span> <span class="nf">run</span><span class="p">(</span><span class="k">array</span> <span class="nv">$params</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// Use the Autoloader to figure out the module path</span>
<span class="nv">$source</span> <span class="o">=</span> <span class="nx">service</span><span class="p">(</span><span class="s1">&#39;autoloader&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getNamespace</span><span class="p">(</span><span class="s1">&#39;Math\\Auth&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="nv">$source</span><span class="p">,</span> <span class="nx">APPPATH</span><span class="p">);</span>
<span class="k">try</span> <span class="p">{</span>
<span class="c1">// Add only the desired components</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addPaths</span><span class="p">([</span>
<span class="s1">&#39;Controllers&#39;</span><span class="p">,</span>
<span class="s1">&#39;Database/Migrations&#39;</span><span class="p">,</span>
<span class="s1">&#39;Models&#39;</span><span class="p">,</span>
<span class="p">])</span><span class="o">-&gt;</span><span class="na">merge</span><span class="p">(</span><span class="k">false</span><span class="p">);</span> <span class="c1">// Be careful not to overwrite anything</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">Throwable</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$this</span><span class="o">-&gt;</span><span class="na">showError</span><span class="p">(</span><span class="nv">$e</span><span class="p">);</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">// If publication succeeded then update namespaces</span>
<span class="k">foreach</span> <span class="p">(</span><span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">getPublished</span><span class="p">()</span> <span class="k">as</span> <span class="nv">$file</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Replace the namespace</span>
<span class="nv">$contents</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$file</span><span class="p">);</span>
<span class="nv">$contents</span> <span class="o">=</span> <span class="nb">str_replace</span><span class="p">(</span><span class="s1">&#39;namespace Math\\Auth&#39;</span><span class="p">,</span> <span class="s1">&#39;namespace &#39;</span> <span class="o">.</span> <span class="nx">APP_NAMESPACE</span><span class="p">,</span> <span class="nv">$contents</span><span class="p">);</span>
<span class="nb">file_put_contents</span><span class="p">(</span><span class="nv">$file</span><span class="p">,</span> <span class="nv">$contents</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
</div>
<p>Now when your module users run <code class="docutils literal notranslate"><span class="pre">php</span> <span class="pre">spark</span> <span class="pre">auth:publish</span></code> they will have the following added to their project:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="nx">app</span><span class="o">/</span><span class="nx">Controllers</span><span class="o">/</span><span class="nx">AuthController</span><span class="o">.</span><span class="nx">php</span>
<span class="nx">app</span><span class="o">/</span><span class="nx">Database</span><span class="o">/</span><span class="nx">Migrations</span><span class="o">/</span><span class="mi">2017</span><span class="o">-</span><span class="mi">11</span><span class="o">-</span><span class="mi">20</span><span class="o">-</span><span class="mi">223112</span><span class="nx">_create_auth_tables</span><span class="o">.</span><span class="nx">php</span><span class="o">.</span><span class="nx">php</span>
<span class="nx">app</span><span class="o">/</span><span class="nx">Models</span><span class="o">/</span><span class="nx">LoginModel</span><span class="o">.</span><span class="nx">php</span>
<span class="nx">app</span><span class="o">/</span><span class="nx">Models</span><span class="o">/</span><span class="nx">UserModel</span><span class="o">.</span><span class="nx">php</span>
</pre></div>
</div>
</section>
</section>
<section id="library-reference">
<span id="reference"></span><h2><a class="toc-backref" href="#id11" role="doc-backlink">Library Reference</a><a class="headerlink" href="#library-reference" title="Permalink to this heading"></a></h2>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p><code class="docutils literal notranslate"><span class="pre">Publisher</span></code> is an extension of <a class="reference internal" href="files.html"><span class="doc">FileCollection</span></a> so has access to all those methods for reading and filtering files.</p>
</div>
<section id="support-methods">
<h3><a class="toc-backref" href="#id12" role="doc-backlink">Support Methods</a><a class="headerlink" href="#support-methods" title="Permalink to this heading"></a></h3>
<section id="static-discover-string-directory-publishers-publisher">
<h4>[static] discover(string $directory = Publishers): Publisher[]<a class="headerlink" href="#static-discover-string-directory-publishers-publisher" title="Permalink to this heading"></a></h4>
<p>Discovers and returns all Publishers in the specified namespace directory. For example, if both
<strong>app/Publishers/FrameworkPublisher.php</strong> and <strong>myModule/src/Publishers/AssetPublisher.php</strong> exist and are
extensions of <code class="docutils literal notranslate"><span class="pre">Publisher</span></code> then <code class="docutils literal notranslate"><span class="pre">Publisher::discover()</span></code> would return an instance of each.</p>
</section>
<section id="publish-bool">
<h4>publish(): bool<a class="headerlink" href="#publish-bool" title="Permalink to this heading"></a></h4>
<p>Processes the full input-process-output chain. By default this is the equivalent of calling <code class="docutils literal notranslate"><span class="pre">addPath($source)</span></code>
and <code class="docutils literal notranslate"><span class="pre">merge(true)</span></code> but child classes will typically provide their own implementation. <code class="docutils literal notranslate"><span class="pre">publish()</span></code> is called
on all discovered Publishers when running <code class="docutils literal notranslate"><span class="pre">spark</span> <span class="pre">publish</span></code>.
Returns success or failure.</p>
</section>
<section id="getscratch-string">
<h4>getScratch(): string<a class="headerlink" href="#getscratch-string" title="Permalink to this heading"></a></h4>
<p>Returns the temporary workspace, creating it if necessary. Some operations use intermediate storage to stage
files and changes, and this provides the path to a transient, writable directory that you may use as well.</p>
</section>
<section id="geterrors-array-string-throwable">
<h4>getErrors(): array&lt;string, Throwable&gt;<a class="headerlink" href="#geterrors-array-string-throwable" title="Permalink to this heading"></a></h4>
<p>Returns any errors from the last write operation. The array keys are the files that caused the error, and the
values are the Throwable that was caught. Use <code class="docutils literal notranslate"><span class="pre">getMessage()</span></code> on the Throwable to get the error message.</p>
</section>
<section id="addpath-string-path-bool-recursive-true">
<h4>addPath(string $path, bool $recursive = true)<a class="headerlink" href="#addpath-string-path-bool-recursive-true" title="Permalink to this heading"></a></h4>
<p>Adds all files indicated by the relative path. Path is a reference to actual files or directories relative
to <code class="docutils literal notranslate"><span class="pre">$source</span></code>. If the relative path resolves to a directory then <code class="docutils literal notranslate"><span class="pre">$recursive</span></code> will include sub-directories.</p>
</section>
<section id="addpaths-array-paths-bool-recursive-true">
<h4>addPaths(array $paths, bool $recursive = true)<a class="headerlink" href="#addpaths-array-paths-bool-recursive-true" title="Permalink to this heading"></a></h4>
<p>Adds all files indicated by the relative paths. Paths are references to actual files or directories relative
to <code class="docutils literal notranslate"><span class="pre">$source</span></code>. If the relative path resolves to a directory then <code class="docutils literal notranslate"><span class="pre">$recursive</span></code> will include sub-directories.</p>
</section>
<section id="adduri-string-uri">
<h4>addUri(string $uri)<a class="headerlink" href="#adduri-string-uri" title="Permalink to this heading"></a></h4>
<p>Downloads the contents of a URI using <code class="docutils literal notranslate"><span class="pre">CURLRequest</span></code> into the scratch workspace then adds the resulting
file to the list.</p>
</section>
<section id="adduris-array-uris">
<h4>addUris(array $uris)<a class="headerlink" href="#adduris-array-uris" title="Permalink to this heading"></a></h4>
<p>Downloads the contents of URIs using <code class="docutils literal notranslate"><span class="pre">CURLRequest</span></code> into the scratch workspace then adds the resulting
files to the list.</p>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>The CURL request made is a simple <code class="docutils literal notranslate"><span class="pre">GET</span></code> and uses the response body for the file contents. Some
remote files may need a custom request to be handled properly.</p>
</div>
</section>
</section>
<section id="outputting-files">
<h3><a class="toc-backref" href="#id13" role="doc-backlink">Outputting Files</a><a class="headerlink" href="#outputting-files" title="Permalink to this heading"></a></h3>
<section id="wipe">
<h4>wipe()<a class="headerlink" href="#wipe" title="Permalink to this heading"></a></h4>
<p>Removes all files, directories, and sub-directories from <code class="docutils literal notranslate"><span class="pre">$destination</span></code>.</p>
<div class="admonition important">
<p class="admonition-title">Important</p>
<p>Use wisely.</p>
</div>
</section>
<section id="copy-bool-replace-true-bool">
<h4>copy(bool $replace = true): bool<a class="headerlink" href="#copy-bool-replace-true-bool" title="Permalink to this heading"></a></h4>
<p>Copies all files into the <code class="docutils literal notranslate"><span class="pre">$destination</span></code>. This does not recreate the directory structure, so every file
from the current list will end up in the same destination directory. Using <code class="docutils literal notranslate"><span class="pre">$replace</span></code> will cause files
to overwrite when there is already an existing file. Returns success or failure, use <code class="docutils literal notranslate"><span class="pre">getPublished()</span></code>
and <code class="docutils literal notranslate"><span class="pre">getErrors()</span></code> to troubleshoot failures.
Be mindful of duplicate basename collisions, for example:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="s1">&#39;/home/source&#39;</span><span class="p">,</span> <span class="s1">&#39;/home/destination&#39;</span><span class="p">);</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addPaths</span><span class="p">([</span>
<span class="s1">&#39;pencil/lead.png&#39;</span><span class="p">,</span>
<span class="s1">&#39;metal/lead.png&#39;</span><span class="p">,</span>
<span class="p">]);</span>
<span class="c1">// This is bad! Only one file will remain at /home/destination/lead.png</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">copy</span><span class="p">(</span><span class="k">true</span><span class="p">);</span>
</pre></div>
</div>
</section>
<section id="merge-bool-replace-true-bool">
<h4>merge(bool $replace = true): bool<a class="headerlink" href="#merge-bool-replace-true-bool" title="Permalink to this heading"></a></h4>
<p>Copies all files into the <code class="docutils literal notranslate"><span class="pre">$destination</span></code> in appropriate relative sub-directories. Any files that
match <code class="docutils literal notranslate"><span class="pre">$source</span></code> will be placed into their equivalent directories in <code class="docutils literal notranslate"><span class="pre">$destination</span></code>, effectively
creating a “mirror” or “rsync” operation. Using <code class="docutils literal notranslate"><span class="pre">$replace</span></code> will cause files
to overwrite when there is already an existing file; since directories are merged this will not
affect other files in the destination. Returns success or failure, use <code class="docutils literal notranslate"><span class="pre">getPublished()</span></code> and
<code class="docutils literal notranslate"><span class="pre">getErrors()</span></code> to troubleshoot failures.</p>
<p>Example:</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="s1">&#39;/home/source&#39;</span><span class="p">,</span> <span class="s1">&#39;/home/destination&#39;</span><span class="p">);</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addPaths</span><span class="p">([</span>
<span class="s1">&#39;pencil/lead.png&#39;</span><span class="p">,</span>
<span class="s1">&#39;metal/lead.png&#39;</span><span class="p">,</span>
<span class="p">]);</span>
<span class="c1">// Results in &quot;/home/destination/pencil/lead.png&quot; and &quot;/home/destination/metal/lead.png&quot;</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">merge</span><span class="p">();</span>
</pre></div>
</div>
</section>
</section>
<section id="modifying-files">
<span id="publisher-modifying-files"></span><h3><a class="toc-backref" href="#id14" role="doc-backlink">Modifying Files</a><a class="headerlink" href="#modifying-files" title="Permalink to this heading"></a></h3>
<section id="replace-string-file-array-replaces-bool">
<h4>replace(string $file, array $replaces): bool<a class="headerlink" href="#replace-string-file-array-replaces-bool" title="Permalink to this heading"></a></h4>
<div class="versionadded">
<p><span class="versionmodified added">New in version 4.3.0.</span></p>
</div>
<p>Replaces the <code class="docutils literal notranslate"><span class="pre">$file</span></code> contents. The second parameter <code class="docutils literal notranslate"><span class="pre">$replaces</span></code> array specifies the search strings as keys and the replacements as values.</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$source</span> <span class="o">=</span> <span class="nx">service</span><span class="p">(</span><span class="s1">&#39;autoloader&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getNamespace</span><span class="p">(</span><span class="s1">&#39;CodeIgniter\\Shield&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="nv">$source</span><span class="p">,</span> <span class="nx">APPPATH</span><span class="p">);</span>
<span class="nv">$file</span> <span class="o">=</span> <span class="nx">APPPATH</span> <span class="o">.</span> <span class="s1">&#39;Config/Auth.php&#39;</span><span class="p">;</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">replace</span><span class="p">(</span>
<span class="nv">$file</span><span class="p">,</span>
<span class="p">[</span>
<span class="s1">&#39;use CodeIgniter\Config\BaseConfig;&#39;</span> <span class="o">.</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span> <span class="o">=&gt;</span> <span class="s1">&#39;&#39;</span><span class="p">,</span>
<span class="s1">&#39;class App extends BaseConfig&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;class App extends \Some\Package\SomeConfig&#39;</span><span class="p">,</span>
<span class="p">],</span>
<span class="p">);</span>
</pre></div>
</div>
</section>
<section id="addlineafter-string-file-string-line-string-after-bool">
<h4>addLineAfter(string $file, string $line, string $after): bool<a class="headerlink" href="#addlineafter-string-file-string-line-string-after-bool" title="Permalink to this heading"></a></h4>
<div class="versionadded">
<p><span class="versionmodified added">New in version 4.3.0.</span></p>
</div>
<p>Adds <code class="docutils literal notranslate"><span class="pre">$line</span></code> after a line with specific string <code class="docutils literal notranslate"><span class="pre">$after</span></code>.</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$source</span> <span class="o">=</span> <span class="nx">service</span><span class="p">(</span><span class="s1">&#39;autoloader&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getNamespace</span><span class="p">(</span><span class="s1">&#39;CodeIgniter\\Shield&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="nv">$source</span><span class="p">,</span> <span class="nx">APPPATH</span><span class="p">);</span>
<span class="nv">$file</span> <span class="o">=</span> <span class="nx">APPPATH</span> <span class="o">.</span> <span class="s1">&#39;Config/App.php&#39;</span><span class="p">;</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addLineAfter</span><span class="p">(</span>
<span class="nv">$file</span><span class="p">,</span>
<span class="s1">&#39; public int $myOwnConfig = 1000;&#39;</span><span class="p">,</span> <span class="c1">// Adds this line</span>
<span class="s1">&#39;public bool $CSPEnabled = false;&#39;</span><span class="p">,</span> <span class="c1">// After this line</span>
<span class="p">);</span>
</pre></div>
</div>
</section>
<section id="addlinebefore-string-file-string-line-string-after-bool">
<h4>addLineBefore(string $file, string $line, string $after): bool<a class="headerlink" href="#addlinebefore-string-file-string-line-string-after-bool" title="Permalink to this heading"></a></h4>
<div class="versionadded">
<p><span class="versionmodified added">New in version 4.3.0.</span></p>
</div>
<p>Adds <code class="docutils literal notranslate"><span class="pre">$line</span></code> before a line with specific string <code class="docutils literal notranslate"><span class="pre">$after</span></code>.</p>
<div class="highlight-html+php notranslate"><div class="highlight"><pre><span></span><span class="o">&lt;?</span><span class="nx">php</span>
<span class="k">use</span> <span class="nx">CodeIgniter\Publisher\Publisher</span><span class="p">;</span>
<span class="nv">$source</span> <span class="o">=</span> <span class="nx">service</span><span class="p">(</span><span class="s1">&#39;autoloader&#39;</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">getNamespace</span><span class="p">(</span><span class="s1">&#39;CodeIgniter\\Shield&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="nv">$publisher</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Publisher</span><span class="p">(</span><span class="nv">$source</span><span class="p">,</span> <span class="nx">APPPATH</span><span class="p">);</span>
<span class="nv">$file</span> <span class="o">=</span> <span class="nx">APPPATH</span> <span class="o">.</span> <span class="s1">&#39;Config/App.php&#39;</span><span class="p">;</span>
<span class="nv">$publisher</span><span class="o">-&gt;</span><span class="na">addLineBefore</span><span class="p">(</span>
<span class="nv">$file</span><span class="p">,</span>
<span class="s1">&#39; public int $myOwnConfig = 1000;&#39;</span><span class="p">,</span> <span class="c1">// Add this line</span>
<span class="s1">&#39;public bool $CSPEnabled = false;&#39;</span><span class="p">,</span> <span class="c1">// Before this line</span>
<span class="p">);</span>
</pre></div>
</div>
</section>
</section>
</section>
</section>
</div>
</div>
<footer><div class="rst-footer-buttons" role="navigation" aria-label="Footer">
<a href="pagination.html" class="btn btn-neutral float-left" title="Pagination" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
<a href="security.html" class="btn btn-neutral float-right" title="Security" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
</div>
<hr/>
<div role="contentinfo">
<p>&#169; Copyright 2019-2025 CodeIgniter Foundation.
<span class="lastupdated">Last updated on Feb 07, 2025.
</span></p>
</div>
Built with <a href="https://www.sphinx-doc.org/">Sphinx</a> using a
<a href="https://github.com/readthedocs/sphinx_rtd_theme">theme</a>
provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script>
jQuery(function () {
SphinxRtdTheme.Navigation.enable(false);
});
</script>
</body>
</html>