Testing ProcessWire repeater behaviour in API use
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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