Call to a member function photo() on boolean

Hey there,

I just updated to Kirby 2.4.0 and got an error on code that used to work in 2.3

Whoops \ Exception \ ErrorException (E_ERROR) Call to a member function photo() on boolean
event.php:25

Here’s the offending code:

        <?php if ( $event->speaker()->isNotEmpty() ) : ?>
            <h3 class="sr-only">Conférenciers</h3>
            <ul class="event__speakers">
                <?php foreach ( $event->speaker()->split(', ') as $speaker ) : $speaker = page('conferenciers')->children()->visible()->find($speaker); ?>
                    <li>
                        <?php if ( $speaker->photo()->isNotEmpty() ) : ?>
                            <img class="event__speaker-photo" width="48" height="48" src="<?= $speaker->photo()->toFile()->resize(48, 48)->url(); ?>" alt="Portrait de <?= $speaker->title()->html() . ', ' . $speaker->suffix()->html(); ?>">
                        <?php endif; ?>
                        <h4 class="event__speaker-name">
                            <a href="<?= $speaker->url(); ?>"><?= $speaker->title()->html(); ?>
                                <br>
                                <small>
                                    <?= $speaker->suffix()->html() ?><?php if ( $speaker->suffix()->isNotEmpty() && $speaker->profession()->isNotEmpty() ) { echo ', '; } ?>
                                    <?= $speaker->profession()->html(); ?>
                                </small>
                            </a>
                        </h4>
                    </li>
                <?php endforeach; ?>
            </ul>
        <?php endif; ?>

It crashes at $speaker->photo()->isNotEmpty().

$event->speaker() is a comma separated list of page slugs
$speaker = page('conferenciers')->children()->visible()->find($speaker) goes find the appropriate page for each speaker
$speaker->photo() is not a boolean. It’s the filename for the person’s photo.

No idea what’s going on.

Any ideas?

Need more info?

Thanks!

Looks like the page you are looking for does not exist, so $speaker returns false.

It’s always advisable to check if an object exists before trying to call a method on it. Same holds true for the image further down the line, btw.

But the pages do exist. I have similar code returning the $speaker name, photo, etc. in other pages.

I haven’t touched this snippet and problems only started when I upgraded from 2.3 to 2.4.

What do you get if you var_dump($speaker) ?

Edit: Try without the extra space in the split(',') method;

I’ve revised the code for debugging. Here’s what I’m running right now.

Here’s an example of what $event->speaker() looks like.

Speaker: denis-masse
Speaker: nadia-dubreuil, france-lauzon

        <?php if ( $event->speaker()->isNotEmpty() ) : ?>
            <div style="display:none;">
                <?php foreach ( $event->speaker()->split(', ') as $speaker ) : $speaker = page('conferenciers')->children()->visible()->find($speaker); ?>
                    <?php print_r($speaker); ?>
                <?php endforeach; ?>
            </div>
        <?php endif; ?>

print_r prints out this page object, which is good.

Page Object
(
    [title] => Denis Massé
    [id] => conferenciers/denis-masse
    [uid] => denis-masse
    [slug] => denis-masse
    [parent] => conferenciers
    [uri] => conferenciers/denis-masse
    [url] => http://domain.ca/conferenciers/denis-masse
    [contentUrl] => http://domain.ca/content/2-conferenciers/2-denis-masse
    [tinyUrl] => http://domain.ca/x/1i3bhmn
    [root] => /var/www/html/content/2-conferenciers/2-denis-masse
    [dirname] => 2-denis-masse
    [diruri] => 2-conferenciers/2-denis-masse
    [depth] => 2
    [num] => 2
    [hash] => 1i3bhmn
    [modified] => c
    [template] => speaker
    [intendedTemplate] => speaker
    [isVisible] => 1
    [isOpen] => 
    [isActive] => 
    [isHomePage] => 
    [isErrorPage] => 
    [isCachable] => 1
    [isWritable] => 1
    [content] => Content Object
        (
            [root] => /var/www/html/content/2-conferenciers/2-denis-masse/speaker.fr.txt
            [fields] => Array
                (
                    [prefix] => 
                    [title] => Denis Massé
                    [suffix] => HD
                    [text] => Gradué hygiéniste dentaire en 1980, ses 20 premières années seront principalement dédiées à l’avancée de l’orthodontie préventive et interceptive. L’an 2000 marquera pour lui son ‘virage paro’. Constamment motivé à offrir les meilleurs soins possibles à ses patients, il est depuis à l’affût des avancées et découvertes en parodontie interceptive. Clinicien et conférencier passionné, il vient partager avec nous le fruit des différentes lectures et formations suivies ces dernières années dans ce champ d’expertise.

(youtube: https://www.youtube.com/watch?v=Jb_tikHlSZM width: 560 height: 315)
                    [photo] => denis-masse-portrait.jpg
                    [profession] => Hygiéniste dentaire
                )

        )

    [headers] => 
    [children] => Children Object
        (
        )

    [siblings] => Children Object
        (
            [0] => conferenciers/dr-jacques-veronneau
            [1] => conferenciers/julie-garceau
            [2] => conferenciers/dr-jean-barbeau
            [3] => conferenciers/dre-sarah-theberge
            [4] => conferenciers/dr-koi-ha-ngoc
            [5] => conferenciers/france-lavoie
            [6] => conferenciers/nadia-dubreuil
            [7] => conferenciers/louise-bourassa
            [8] => conferenciers/nancy-lehoux
            [9] => conferenciers/me-philippe-coderre
            [10] => conferenciers/dr-martin-valois
            [11] => conferenciers/dr-jason-battah
            [12] => conferenciers/dr-nabil-ouatik
            [13] => conferenciers/dre-houda-lallali
            [14] => conferenciers/dr-georges-jammal
            [15] => conferenciers/danny-tremblay
            [16] => conferenciers/dre-quynh-anh-pham
            [17] => conferenciers/dr-claude-morissette
            [18] => conferenciers/dr-phuc-huynh
            [19] => conferenciers/denise-hetu
            [20] => conferenciers/dr-peter-tawil
            [21] => conferenciers/ron-ruffner
        )

    [files] => Files Object
        (
            [0] => denis-masse-portrait.jpg
        )

)

Everything seems there for it to work correctly.

EDIT: Forgot to mention. event.php line 25 is <?php if ( $speaker->photo()->isNotEmpty() ) : ?>

Looks good, I wonder if the error only occurs with a list of multiple speakers, or also with a single speaker? Maybe dump $event->speaker()->split(', ') as well.

A list of multiple speakers outputs multiple Page Objects. Here’s an excerpt:

Page Object
(
    [title] => France Lavoie
    [id] => conferenciers/france-lavoie
    [uid] => france-lavoie
    [slug] => france-lavoie
    [parent] => conferenciers
    [uri] => conferenciers/france-lavoie
[...]

Page Object
(
    [title] => Nadia Dubreuil
    [id] => conferenciers/nadia-dubreuil
    [uid] => nadia-dubreuil
    [slug] => nadia-dubreuil
    [parent] => conferenciers
    [uri] => conferenciers/nadia-dubreuil
[...]
Page Object
(
    [title] => Louise Bourassa
    [id] => conferenciers/louise-bourassa
    [uid] => louise-bourassa
    [slug] => louise-bourassa
    [parent] => conferenciers
    [uri] => conferenciers/louise-bourassa
[...]

That’s weird. Do the other fields work (if you remove all code regarding the photo)?

Whoops\Exception\ErrorException 
/var/www/html/site/snippets/event.php26

Now its <a href="<?= $speaker->url(); ?>"><?= $speaker->title()->html(); ?> that doesn’t work.

I think for some reason $speaker returns a boolean?

That’s what I said above, but if you var_dump() it, you seem to get a page, not a boolean, that’s why that’s very strange.

I tried print_r on $speaker->photo() and I get the same error.

Is $speaker unrecognized as a Page Object? Do I need to put something between my variable and the field name?

EDIT: I tried adding toPage() after find($speaker) and I get the same error:

Whoops \ Exception \ ErrorException (E_ERROR)
Call to a member function toPage() on boolean

It’s like the end result isn’t interpreted the same way by Kirby and print_r.

Have you tried to remove the extra space in the split(',') method as I suggested above?

Just tried it. Same outcome. Error with full code but correct var_dump.

Does none of the pages return any result? Are all child pages visible?

The code as such should work in Kirby 2.4.0.

This is an “archive” page, so all child pages are visible.

The structure is as follows: This page lists all events. Each event has 0 to 3 speakers. If it has 1 or more speaker, it’s a conference. If it has speakers, show their photo and link to their pages.

Did you find a solution to this? I ran into the same problem. Var_dump gives me a page object but if I try to access the title or url it complains about boolean.

@lauri Could you please post your code, together with the content of the page where the error occurs and the content folder structure. I’m pretty sure that you only get this error if there is no page object. Alternatively, you can zip your projects and PM me a download link for testing.

Sorry, I didn’t. I removed the code and ended up remaking the website.

You’re right. I just tested a bit more and indeed there was no page object for each item in the for loop. Problem solved, thanks!

In any case, always add a check to make sure that the objects you expect really exist. No matter if they are images, page objects or whatever else. You never know in advance if a page or other object still exists at runtime, for example because a page or an image was deleted but is still referenced in the content file.