Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Testing ProcessWire repeater behaviour in API use
<?php
// Bootstrap ProcessWire
require 'index.php';
// Make sure that FieldtypeRepeater is installed and ready for use
if (!wire('modules')->isInstalled('FieldtypeRepeater')) {
if (wire('modules')->isInstallable('FieldtypeRepeater')) {
wire('modules')->install('FieldtypeRepeater');
echo "Module FieldtypeRepeater installed\n";
} else {
throw new WireException("FieldtypeRepeater not installable");
}
}
// Create repeater field 'repeater' and add it to basic-page template (unless
// this field already exists and has been added to said template). The amount
// of "boilerplate code" required is interesting; would it make any sense for
// repeater fields to automatically create required templates etc.?
$field_name = 'repeater';
$field = wire('fields')->get($field_name);
if (!$field->id) {
$fieldgroup = new Fieldgroup;
$fieldgroup->name = "repeater_" . $field_name;
$fieldgroup->append(wire('fields')->get('title'));
$fieldgroup->save();
$template = new Template;
$template->name = "repeater_" . $field_name;
$template->fieldgroup = $fieldgroup;
$template->flags = Template::flagSystem;
$template->noChildren = 1;
$template->noParents = 1;
$template->noGlobal = 1;
$template->save();
$field = new Field;
$field->type = wire('modules')->get('FieldtypeRepeater');
$field->name = $field_name;
$field->parent_id = wire('pages')->get("name=for-field-{$field->id}")->id;
$field->template_id = $template->id;
$field->save();
echo substr($field->type, 9) . " field '{$field->name}' added\n";
}
$fieldgroup = wire('fieldgroups')->get('basic-page');
if (!$fieldgroup->hasField($field)) {
$fieldgroup->add($field);
$fieldgroup->save();
echo substr($field->type, 9) . " field '{$field->name}' added to fieldgroup '{$fieldgroup->name}'\n";
}
// Add new page
//
// Note: if we remove repeater field 'repeater' right after this, repeater page
// parent 'for-page-PAGE_ID' will remain in pages table, while repeater parent
// 'for-field-FIELD_ID' will be removed. Possible garbage cleaning issue?
$page = new Page;
$page->parent = wire('pages')->get('/');
$template = wire('templates')->get('basic-page');
$page->template = wire('templates')->get('basic-page');
$page->title = "a test page";
$page->save();
echo get_class($page) . " '{$page->url}' added\n";
// Add repeater item
//
// Note: if we remove repeater field 'repeater' right after this, without first
// removing $page, repeater page parent 'for-page-PAGE_ID' will remain in pages
// table, while repeater parent 'for-field-FIELD_ID' will be removed. Possible
// garbage cleaning issue?
$item = $page->repeater->getNew();
$item->title = "repeater title";
$page->save();
echo get_class($page) . " '{$page->url}' saved\n";
// Delete previously created page
//
// After this repeater page parent 'for-page-PAGE_ID' will be removed, while any
// repeater items will remain as orphans in pages table until manually deleted
// with direct SQL queries unless we also remove the repeater field. Possible
// garbage cleaning issue?
//
// It should be noted that such orphan repeater items won't be visible at admin
// and attempts to remove repeater field they belong to will results in error:
// "Can't delete template 'repeater_repeater' because it is used by 1 pages."
$page->delete();
echo get_class($page) . " '{$page->url}' deleted\n";
// Remove repeater field from fieldgroups and then delete the field itself.
//
// Note: unless we specifically find and delete all items belonging to this
// repeater field (using it's template), the field ends up in a state where
// it can't be removed until remaining repeater items are manually removed
// via database. Not necessarily a real issue, but if possible, preventing
// that would be nice..
$fieldgroups = $field->getFieldgroups();
foreach ($fieldgroups as $fieldgroup) {
$fieldgroup->remove($field);
$fieldgroup->save();
echo substr($field->type, 9) . " field '{$field->name}' removed from fieldgroup '{$fieldgroup->name}'\n";
}
foreach (wire('pages')->find("template=repeater_{$field->name}, include=all") as $page) {
$page->delete();
echo get_class($page) . " '{$page->url}' deleted\n";
}
wire('fields')->delete($field);
echo substr($field->type, 9) . " field '{$field->name}' deleted\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment