Jump to content
gebeer

Unexpected value when using new each() api method

Recommended Posts

Hello,

I'm playing with the new each() API method.

	$warning = $divesites->each(function($item) {
	  $warning = "";
	  if (!$item->marker->address) {
	  	$warning .= "<div class='alert alert-warning'>coordinates for {title} not set</div>";
	  } else {
	  	$warning .= "";
	  }
	  return $warning;
	});

$warning should return an empty string, when all dive site adresses are set. But instead it returns the page id of the last dive site in the loop.

When I do it the foreach way

        $warning = "";
	foreach ($divesites as $site) {
		if (!$site->marker->address) {
		  	$warning .= "<div class='alert alert-warning'>coordinates for {$site->title} not set</div>";
		  } else {
		  	$warning .= "";
		  }
	}

the $warning is an empty string as expected.

Why is that? Any pointers would be much appreciated.

Share this post


Link to post
Share on other sites

Just thinking out of the box here:

$warning = "";

$divesites->each(function($item) use (&$warning) {
	if (!$item->marker->address) {
		$warning .= "<div class='alert alert-warning'>coordinates for {title} not set</div>";
	}
});
  • Like 1

Share this post


Link to post
Share on other sites

Thanks for your reply.

$warning will not be available inside the each() callback function because of variable scope.

Also the callback function needs to either echo or return something.

So I'm afraid your code won't output anything and give a PHP notice like "variable $warning not defined" because you define $warning outside the callback function. This is mentioned in the link that I posted in #1

EDIT

Sorry, I overlooked the "use (&$warning)" part. So forget about what I just said

I implemented your proposed solution. But still the return value gives me the page ids of pages within the $divesites page array where I would expect it to be empty.

EDIT again

Got it. I still had $warning = $divesites->each(function...

After removing the $warning = part, it works.

Only I had to replace {title} with {$item->title}

Thanks again.

But with my limited PHP knowledge I still don't understand why that is so.

  • Like 1

Share this post


Link to post
Share on other sites

Glad it worked. :-)

It wouldn't have worked because of variable scope and attempting to assign multiple results to a single variable in one shot. In other words, the $warning = "" would have been reset each time the function executed. That's why the write access (reference) to $warning (outside the function) is needed.

I'm surprised about the {title}, though... Not sure why that had to be changed.

I think the {title} had to be changed because that seems to only be worked with after the function has returned a value. It can't just guess.

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By ngrmm
      I have a page with a table. Each table row has a page-reference field and a checkbox.
      The Page sends emails to all users (page-refrence->email-field) and change the value of the checkbox in a row to 1.
      It works with this:
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?> But i have to use a variable in my emailbody.inc which i'm able to get in the table-loop.
      So i do the including of the body inside my loop. But this doesn't work anymore. Page sends out the emails but is unable to change the value of the checkbox.
      I get no errors!
      I'm using ProTable
      <?php // event ID fron url query $eventID = $input->get('eventID','int'); // get event-page $event = $pages->get($eventID); // config $fromEmail = $event->event_mail_from; $fromName = $event->event_mail_from_name; $emailSubject = $event->event_subject; // loop through table and send out emails foreach($event->event_clients_list as $event_table_row) { // get client page $clientPage = $event_table_row->client_name; // get client email $clientEmail = $clientPage->email; // email html body ob_start(); include('./_inc/emailbody.inc'); $emailBody = ob_get_clean(); // make event-page editable $event->of(false); // if client isn't invited yet (checkbox not checked) if($event_table_row->client_invited == '') { // send email $m = new WireMail(); $m->to($clientEmail); $m->from($fromEmail, $fromName); $m->subject($emailSubject); $m->bodyHTML($emailBody); $m->send(); // mark client as invited $event_table_row->client_invited = 1; $event->save('event_clients_list'); } } ?>  
    • By Lmwt
      Hello,
      and one more beginner question: I am using the multi-language site profile and having troubles targeting the region I want to populate in my templates due to delayed output. The list is now appearing on top of the nav bar 🙂 and the values of the fields on one line down the title. I want these fields to be displayed in a list underneath the title of the page, and I also would like the name of the field to be displayed as a string in front of the value... I dont know how to do this. Can someone help?
      right now my code looks like this: 
      <?php namespace ProcessWire;?> <!DOCTYPE html> <html> <li class="Pub-profile-info"><?php $content .=page()->Location?></li> <li class="Pub-profile-info"><?php $content .=page()->Pub_country?></li> <li class="Pub-profile-info"><?php $content .=page()->Since?></li> <li class="Pub-profile-info"><?php $content .=page()->Contact?></li> <li class="Pub-profile-info"><?php $content .=page()->Focus?></li> <li class="Pub-profile-info"><?php $content .=page()->Members?></li> <li class="Pub-profile-info"><?php $content .=page()->Location?></li> <li class="Pub-profile-info"><?php $content .=page()->Decision_making?></li> <li class="Pub-profile-info"><?php $content .=page()->Financing?></li> <li class="Pub-profile-info"><?php $content .=page()->History?></li> <li class="Pub-profile-info"><?php $content .=page()->images?></li> <li class="Pub-profile-info"><?php $content .=page()->logo?></li> </html> and the screen looks like that:
      Thanks for helping!

    • By Hubris
      Hi there!
      I'm using some page reference fields to create lists of tags, categories, years, etc.. I'm able to find the pages like so:
      $pages->find("template=project, {$filter}={$page->title}"); Which dynamically does something like: 
      $pages->find("template=project, tags=Experimental"); Only if the value (the page name, like "Experimental") starts with letters. If it starts with numbers, find returns nothing.
      Why is this and how can I fix it?
    • By cosmicsafari
      Hi all,
      This is my first foray into a multi lingual PW site, what i'm unsre about is whether the frontend output is translated automatically or do I have to provide the content in another language also?
      As it stands I have installed the following modules:

      And have created and uploaded the Chinese language pack.

      At this point I can successfully change my profile and the backend successfully displays in Chinese.
      However I am confused about how I now get that translation to work on the frontend?
      I have setup the alternative url for the page I wish to view in Chinese

      So as a basic test I tried adding the following into the template used for the page above.

      However both urls still display the message in English?
      I take it I have missed something, do I then need to enter the frontend output in Chinese in another field within the backend to enable Chinese url to output the content?
      Any ideas would be greatly appreciated.
       
    • By louisstephens
      So, I am not even sure if this is possible, but I thought I would ask anyway. I was building a "system" that would make some modals (izimodal) using a few fields. A user would select the color combo they want, enter a title, fill out the body, and then I was going to pass this (in the template) to fill in the modal. I have this all working pretty flawlessly.
      <div id="example-modal" class="model" data-izimodal-autoopen data-izimodal-transitionin="fadeInDown" data-izimodal-iframeURL="<?php echo $page->example->url; ?>"></div> <script type="text/javascript"> $("#ca-entrance-modal").iziModal({ title: 'Custom Title Here', subtitle: '', headerColor: 'Custom Color Here', history: false, iframe : true, fullscreen: false, loop: false, width: 350, iframeHeight: 350, top: null, bottom: null, borderBottom: false, closeButton: true, }); </script> However, I have hit a road block. The modals are using iframes to pull in the corresponding modal page, but the javascript options are not being iframed (so the modal will actually launch etc). My thought was the user can just copy the page link to the modal, and insert it into the iframe and simply adding the js code, the modal would work (which it does).
      I guess here is my actually problem. Since the user is selecting several options to "customize" the modal, the javascript is custom and differs between each modal. Is there a way to "disable" a textarea, and output the "custom" javascript inside the textarea so they can copy it for inclusion on their actual pages?
       
      Or, is this something that I should just output in the frontend view for users.
×
×
  • Create New...