-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Short description of the issue
When a page has a PageTable field and it's joined with e.g. $p = $pages->get('id=42, field=my_pagetable_field'), the resulting $p->my_pagetable_field is empty when the field contains exactly one page.
Expected behavior
Adding field=... should not affect the result, only performance.
Actual behavior
The only subpage is not fetched.
Screenshots/Links that demonstrate the issue
Possible cause: when the database query returns exactly one subpage, is_array returns false here:
https://github.com/processwire/processwire/blob/master/wire/modules/Fieldtype/FieldtypePageTable.module#L452
Steps to reproduce the issue
The script below creates a parent and child template, p and c, and a field c_ref in the p template. Then it adds these pages:
Parent: parent-a
Child: child-a1
Child: child-a2
Parent: parent-b
Child: child-b1
If run without GET params, it fetches all the pages and prints the above output. If run with ?join, the lone child child-b1 is not printed.
Setup/Environment
- ProcessWire version: latest dev
- (Optional) PHP version: 8.2
- (Optional) MySQL version: MariaDB 10.5.26
The script:
<?php
$processwirePath = '/var/www/html/';
include($processwirePath . 'index.php');
header('Content-Type: text/plain');
////// Install fixture templates, field and pages.
////// First, clean up previous run (if any).
// Remove pages with template 'p' or 'c'.
$pagesToRemove = $pages->find("template=p|c");
foreach ($pagesToRemove as $page) $pages->delete($page, true);
// Remove templates 'p' and 'c'.
$pTemplate = $templates->get('p');
if ($pTemplate) $templates->delete($pTemplate);
$cTemplate = $templates->get('c');
if ($cTemplate) $templates->delete($cTemplate);
// Remove field 'c_ref' if it exists.
$field = $fields->get('c_ref');
if ($field) $fields->delete($field);
// Create templates and field.
$pTemplate = $templates->add('p');
$pTemplate->save();
$cTemplate = $templates->add('c');
$cTemplate->save();
$field = $fields->makeItem();
$field->name = 'c_ref';
$field->type = 'PageTable';
$field->label = "c_ref";
$field->template_id = [$cTemplate->id];
$field->inputfield = "InputfieldPageTable";
$field->parent_id = 1;
$field->save();
$pTemplate->fields->add($field);
$pTemplate->save();
// Create pages.
$parent_a = $pages->add('p', '/', 'parent-a');
$child_a1 = $pages->add('c', '/', 'child-a1');
$parent_a->c_ref->add($child_a1);
$parent_a->save();
$child_a2 = $pages->add('c', '/', 'child-a2');
$parent_a->c_ref->add($child_a2);
$parent_a->save();
$parent_b = $pages->add('p', '/', 'parent-b');
$child_b1 = $pages->add('c', '/', 'child-b1');
$parent_b->c_ref->add($child_b1);
$parent_b->save();
//////// Now everything is set up.
$selectorSuffix = isset($_GET['join']) ? ', field=c_ref' : '';
foreach (['parent-a', 'parent-b'] as $parentName) {
$parent = $wire->pages->get("name=$parentName" . $selectorSuffix);
echo "Parent: $parentName\n";
foreach ($parent->c_ref as $child) {
echo " Child: " . $child->name . "\n";
}
}