Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Joining a PageTable field results in an empty value when the field has exactly one page #1988

Open
tuomassalo opened this issue Nov 5, 2024 · 1 comment

Comments

@tuomassalo
Copy link

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";
    }
}
ryancramerdesign added a commit to processwire/processwire that referenced this issue Nov 14, 2024
@ryancramerdesign
Copy link
Member

Thanks @tuomassalo, you were right about the source of the issue, I've pushed a fix for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants