Getting Associated Entries | express_entry_list -> template -> boats.php

Permalink
I created Express Data Objects and entered all the data through the interface. I also made the one to many Associations. Now I need to output it all in my template. What is the right code for the boat location (MarinaName)?

<?php
   $boatImage = $item->getEntry()->getBoatImage();
   if (is_object($boatImage)) { ?>
      <img src="<?php echo $boatImage->getRelativePath(); ?>" alt="">
   <?php } ?>
<h3><?=$item->getEntry()->getBoatName();?></h3>
<h4><?=$item->getEntry()->getBoatDescription();?></h4>
<p>Stock: <?=$item->getEntry()->getBoatStock();?></p>
<p>Fuel Type: <?=$item->getEntry()->getBoatFuelType();?></p>
<p>Color: <?=$item->getEntry()->getBoatColor();?></p>
<p>Location: <?=$item->getEntry()->getMarinaName();?></p>

View Replies:
hutman replied on at Permalink Reply
hutman
Can you give us some more background about the entities and the relationships?
lukrecija replied on at Permalink Reply
I followed exactly what Andrew did in the videos:
https://documentation.concrete5.org/developers/express/creating-expr...
https://documentation.concrete5.org/developers/express/using-the-exp...

But his example shows how to do the express_entry_detail page template.

My situation is very similar to the website he did for the salon. There is stylist page where it lists all the stylists and the locations associated to them (http://www.gingersalon.com/stylists).
https://documentation.concrete5.org/developers/express/overview...
hutman replied on at Permalink Reply
hutman
From that video and no background about what you actually setup it looks like you should be able to do $item->getLocations(); which will return you the location object and you can do a foreach loop on the locations to output the information.
lukrecija replied on at Permalink Reply
Thank you @hutman for the help. I still need guidance on this. $item->getLocations(); (in my case, $item->getMarinaName();) didn’t work. Here is some more background.
Boat have the fields “Name”->BoatName (text), “Description”->BoatDescription (textarea), “Stock”->BoatStock (number), “Fuel Type“->BoatFuelType (select), “Color“->BoatColor (select). I made the association many to one to the Marina object.
Marina have one field "Name"->MarinaName (text). Marina is related to a Boat through a one to many connection.

I have created the forms. For Boat form I have 2 field sets: Basics (name, description, stock, fuel type and color) and Marina association as a second set.

For Marina form, I have name and the boat association.

What is the php to pull the marina association on the boats page?
hutman replied on at Permalink Reply
hutman
I believe it should be

$item->getMarina()->getName();
lukrecija replied on at Permalink Reply
So the difference for the associated object is getMarina vs getEntry.
<p>Color: <?=$item->getEntry()->getBoatColor();?></p>
<p>Location: <?=$item->getMarina()->getMarinaName();?></p>

Also I thought that I need getMarinaName(); (handle is marina_name) vs getName();?

Unfortunately both ways I am getting an error: Call to undefined method Concrete\Core\Express\Entry\Search\Result\Item::getMarina()
hutman replied on at Permalink Reply
hutman
Just so I'm understanding what is your $item? Is it a Boat or is it a Marina?

I'm wondering if you don't have to do

$item->getEntry()->getMarina()->getMarinaName();
lukrecija replied on at Permalink Reply 1 Attachment
My $item is Boat. I am able to output all boat attributes (name, photo, description) to front-end, but not the associated object, which is Marina. See the screenshot for more clarification.

I am still getting an error for $item->getEntry()->getMarina()->getMarinaName();
Call to undefined method Concrete\Core\Entity\Attribute\Value\Value\SelectValue::getMarinaName()
hutman replied on at Permalink Reply
hutman
I'm sorry, I don't know what to tell you. Without having access to your setup I can't make any more suggestions.
studio108 replied on at Permalink Reply
studio108
Hi Lukrecija,

I know this post is 4 years old and you might not be part of the C5 community anymore but if you are did you ever get an answer to your question?

I have the same question even in 2021! I have all trawled through all old and new postings asking the same question but never with any success.
mnakalay replied on at Permalink Reply
mnakalay
Technically $item->getMarina()->getMarinaName(); should have worked.

What is your specific situation @studio108? Could you share your object and attribute handles and relations?
studio108 replied on at Permalink Reply
studio108
Hi mnakalay,

yes, you are correct. Thank you for your reply. This did work for me eventually but I had to make sure all the boats were assigned to a Marina despite it not being set as required information field. Once I did this the errors stopped.
The marina then associated to each boat appeared in the listing.

I am now stuck on the reverse method of how to list the boats assigned to each Marina on the Marina page?
mnakalay replied on at Permalink Reply
mnakalay
I guess this should work
$boats = $marina->getBoats(); // here use the plural handle since it's on the many side
foreach ($boats as $boat) {
    $boat->getBoatName(); // or whatever attribute you have for boats
}
studio108 replied on at Permalink Reply
studio108
Hi and thank you again,
I still get a "Call to a member function getBoats() on null" error message ?
<?php
            $i = 0;
            foreach($result->getItems() as $item) { ?>
                <?php $i++; ?>
                <div class="col-md-3 col-sm-6 bottommargin">
                <div class="boats">
                <?php 
                $marina_name = $item->getEntry()->getMarinaName();
                $boats = $marina->getBoats();// here use the plural handle since it's on the many side
                foreach ($boats as $boat) {
                $boat->getBoatName(); // or whatever attribute you have for boats
                }
                ?>


The above code works until I try to pull in the 'boats' data?
mnakalay replied on at Permalink Reply
mnakalay
in your code, $marina doesn't exist. You have $item so it should be $item->getBoats()

unless you defined $marina elsewhere?
studio108 replied on at Permalink Reply
studio108
Hi, when I change $marina to $item
<?php
            $i = 0;
            foreach($result->getItems() as $item) { ?>
                <?php $i++; ?>
                <div class="col-md-3 col-sm-6 bottommargin">
                <div class="boats">
                <?php 
                $marina_name = $item->getEntry()->getMarinaName();
                $boats = $item->getBoats();// here use the plural handle since it's on the many side
                foreach ($boats as $boat) {
                $boat->getBoatName(); // or whatever attribute you have for boats
                }
?>


I get the error message -

Call to undefined method Concrete\Core\Express\Entry\Search\Result\Item::getBoats()


Thank you for your help it is appreciated.
mnakalay replied on at Permalink Reply
mnakalay
So try
$boats = $item->getEntry()->getBoats();
studio108 replied on at Permalink Reply
studio108
Hi,
I now don't get an error but where the boat names should appear I get the word 'array' ?
mnakalay replied on at Permalink Reply
mnakalay
Yes $boats should be an array. That's why we then use the foreach to get each boat out of the array. Isn't it what you're doing?
studio108 replied on at Permalink Reply 1 Attachment
studio108
Hi mnakalay,
I literally mean I am getting the word 'array' as the outputted result.

I have attached a screengrab.
mnakalay replied on at Permalink Reply
mnakalay
When you echo something and it prints the word array" it means it's literally an array.

So you have an array.

What I don't understand is what array is that? What are you echoing to get that. It would really help if you shared your exact code.
studio108 replied on at Permalink Reply
studio108
Hi mnakalay,
here is the code I have been working with. It has been adapted from an example that was posted up on the forum a while back.

<?php defined('C5_EXECUTE') or die(_("Access Denied."));
$c = Page::getCurrentPage();
if ($tableName) { ?>
    <h2><?php echo $tableName?></h2>
    <?php if ($tableDescription) {  ?>
        <p><?php echo $tableDescription?></p>
    <?php } ?>
<?php }
if ($entity) { ?>
    <?php if ($enableSearch) { ?>
        <form method="get" action="<?php echo $c->getCollectionLink()?>">
            <div class="form-inline">
                <div class="form-group">
                    <?php echo $form->label('keywords', t('Keyword Search'))?>
                    <?php echo $form->text('keywords')?>
mnakalay replied on at Permalink Reply
mnakalay
So like I said, you're getting an array which is what's expected. $boats contains several boats, hence the array. That's why in my code I said to run a foreach loop

foreach ($boats as $boat) {
    // do whatever with $boat. Example:
   echo $boat->getName() // only works if $boat has an attribute with handle "name"
}
studio108 replied on at Permalink Reply
studio108
That's got it!!

Thank you so much for your time.
mnakalay replied on at Permalink Reply
mnakalay
Glad I could help :)