Developer API
Feeder exposes its export functionality through a console command (for
cron, CI, and deploy scripts), a set of PHP services reachable from CP
controllers, Twig, or other plugins, and the craft.feeder Twig variable.
Console command
./craft feeder/export/list
./craft feeder/export/fields --feed=3
./craft feeder/export/run --feed=3 [--path=/path/to/file] [--stdout]
./craft feeder/export/queue --feed=3 [--path=/path/to/file]
./craft feeder/export/run-due
| Action | Options | Purpose |
|---|---|---|
list (default, feeder/export) | — | Lists every feed with its ID, name, output format, source, site, and enabled state. |
fields | --feed/-f (required) | Prints the feed's saved mapped fields and, separately, the suggested fields available from its source — useful for building or checking a feed's field list before running it. |
run | --feed/-f (required), --path/-p, --stdout | Runs the export synchronously in the current process. Without --path, writes to the feed's default export path (Settings → Default export path, or its site override). With --stdout, prints the generated content instead of writing a file (no delivery or history logging in that mode). Otherwise writes the file, attempts FTP/FTPS/SFTP delivery if configured, and logs a history row on success or failure (subject to Enable history logging). |
queue | --feed/-f (required), --path/-p | Pushes the export onto Craft's queue instead of running it inline — the same path used by the CP's Generate feed button. Prints the queued job ID. |
run-due | — | Evaluates every enabled feed's execute_mode/schedule_pattern against the current time and queues an export job for each one that's due. See Scheduling. |
Exit codes follow Yii console conventions: 0 on success, non-zero with a
stderr message on failure (missing --feed, an unknown feed ID, or an
exception during export/delivery) — safe to check in a deploy script or
cron wrapper.
Scheduling
Feeder does not run its own background scheduler process — a feed with
Generate feed: By Schedule only actually runs when something calls
feeder/export/run-due. Wire that into the server's system cron (or an
equivalent scheduled-task runner) to evaluate all due feeds on an interval,
for example every 5 minutes:
*/5 * * * * /path/to/craft feeder/export/run-due >> /dev/null 2>&1
run-due compares each enabled feed's schedule_pattern (a standard cron
expression, evaluated via Cron\CronExpression) against the current time
and queues (not runs inline) an export job for every feed that's due —
actual generation then happens through Craft's queue runner, same as a
manually queued export.
craft.feeder Twig variable
craft.feeder resolves to the plugin instance itself, so any registered
service is reachable as craft.feeder.<service>:
{{ craft.feeder.settings.defaultExportPath }}
{% for source in craft.feeder.source.getAllSources() %}
{{ source.label }}
{% endfor %}
PHP services
Get the plugin instance via yui\feeder\Plugin::getInstance() (or
yui\feeder\Plugin::$plugin), then a component:
Service (Plugin::getInstance()->get...()) | Purpose |
|---|---|
getFeed() — FeedService | CRUD for feed profiles (getAllFeeds(), getFeedById(), saveFeed(), deleteFeedById()), plus static helpers for the option lists used in the CP (getExecuteModes(), getTransferProtocols(), getTransferModes(), currency/decimal/thousand-separator option lists, getElementTypeLabel()). |
getExport() — ExportService | Builds and writes export output: buildRows(FeedModel $feed) (normalized, field-mapped rows), buildPayload(FeedModel $feed) (rendered content + row count, respecting template mode), createDownloadResponse(FeedModel $feed) (streams the export as a browser download and logs history), and the chunked prepareQueuedExport()/processQueuedExportChunk() pair used by the queue job. |
getFieldMap() — FieldMapService | Reads/writes a feed's saved field list (getMappedFields(), saveMappedFields()) and parses output=source|modifier:arg definitions (parseFieldDefinitions()) into the structure ExportService applies per row. |
getMapping() — MappingService | CRUD for mapping profiles and their value rows, and the lookup used by the map: field modifier. |
getModifier() — ModifierService | Applies a single modifier (apply($value, $modifier, $args)) or a full pipeline (applyPipeline($value, $modifiers)) — the same modifiers documented in Usage → Fields, template mode and modifiers. |
getRule() — RuleService | CRUD for rule profiles (getRuleById(), getAllRules(), saveRule(), deleteRuleById()). |
getHistory() — HistoryService | Reads/writes export run history (logRun(), getAllHistory(), getHistoryByFeedId(), getHistoryRunById()). |
getDelivery() — DeliveryService | deliver(FeedModel $feed, string $localPath) — uploads a generated file via FTP, FTPS, or SFTP per the feed's delivery settings, or returns ['target' => 'local'] when delivery isn't enabled. Throws \RuntimeException on connection/auth/upload failure (caught by the console run action and CP export flow, which log the failure to history). |
getScheduler() — SchedulerService | queueFeed(int $feedId, ?string $path = null) pushes an ExportFeedJob onto the queue; isDue(FeedModel $feed, string $currentTime = 'now') and runDue(string $currentTime = 'now') implement the cron-pattern check used by export/run-due; getDefaultExportPath(FeedModel $feed, string $extension) resolves the effective output path from Settings. |
getSource() — SourceService | Enumerates registered export sources (getAllSources()) and resolves one by element type or key. |
use yui\feeder\Plugin as FeederPlugin;
$feed = FeederPlugin::getInstance()->getFeed()->getFeedById(3);
$payload = FeederPlugin::getInstance()->getExport()->buildPayload($feed);
// $payload['content'], $payload['rowCount']
Queued export job (ExportFeedJob)
queueFeed() (called by the CP's Generate feed button, export/queue,
and run-due) pushes yui\feeder\jobs\ExportFeedJob onto Craft's queue.
The job doesn't build the whole export in one pass — it processes one chunk
of Default chunk size (Settings) elements per
execute() call, then re-queues a copy of itself with the same feedId,
path, and statePath until ExportService::processQueuedExportChunk()
reports complete. This is what keeps a queue worker request small even for
feeds with a very large source element count.
Progress and resumability are tracked in a per-feed JSON state file (offset,
processed row count, output paths), written by ExportService under the
feed's resolved export path. prepareQueuedExport() reuses an existing state
file for that feed ID instead of starting over, so re-queuing the same feed
after a failed or interrupted run resumes from its last completed chunk
rather than re-processing rows from the beginning — the state file is only
removed once the export finishes (processQueuedExportChunk() returns
complete) or a caller inspects/clears it manually. Because the state file
is keyed by feed ID, queueing the same feed a second time while an earlier
job for it is still running shares that state file rather than starting an
independent parallel export.
When Enable history logging is on, the job logs a history row and
transitions its status as it works: queued when first pushed (unless a
history row was already supplied), processing at the start of each chunk,
then success or failed on the run that finishes it. On an unhandled
exception, ExportFeedJob calls ExportService::failQueuedExport() (marks
the state file's failedAt, but does not delete it — see resumability
above), records the failure in history when logging is enabled, and
rethrows, so the queue worker reports the job as failed rather than
silently swallowing the error.
Adding a custom export source
Export sources implement yui\feeder\export\sources\SourceAdapterInterface
and are currently registered from SourceService::getAllSources() — Craft
core sources (Entry, Category, User, Asset) are always added; the
commerce-backed sources (Product, Order, Customer, Variant) are added only
when their element type class exists. There is no public event to append a
custom adapter from another plugin in this release; a custom source
currently requires extending or wrapping SourceService.
Notes for integrators
ftp_passwordand other feed credentials are stored as plain model attributes — use Craft's standardApp::parseEnv()-compatible environment-variable references where the field accepts them if you want to keep secrets out of the database/project config, the same convention used by other plugins in this ecosystem.runwith--stdoutskips both delivery and history logging — use it for quick output inspection, not as a way to test the full pipeline (delivery, history) a scheduled or queued run will actually go through.- A disabled feed (Enable this feed off) is skipped by
run-dueand byqueueFeed()/the scheduler, but the consolerun/fieldsactions will still look it up directly by ID if you--feedit explicitly.