Jump to content
tinacious

Trying to get the first object with a condition

Recommended Posts

Hi everyone, thanks in advance for your help.

I have an Event set up using a datetime field. I'm trying to grab the earliest event that has not yet passed, e.g. soonest upcoming event.

This is what I have so far.

<?php 
	$today = mktime(0,0,0,date("m"),date("d"),date("Y"));

	$events = $pages->find("template=calendar-event, sort=calendar_event");
	foreach($events as $event) {
		$date = $event->getUnformatted('calendar_event');
		if($date > $today) {
			echo $event->first()->render();
		}
	}
?>

The first() part is throwing an error but I put it here so you can see what I'm trying to do.

What would be the best way to go about doing this?

Thanks for your help.

Share this post


Link to post
Share on other sites
Shouldn't that be $events->first() ?

I haven't tried your suggestion but wouldn't it get the first event based on sorting order (ascending)? I want to get that but using the condition that the date is no earlier than today, i.e. "get events sorted by date in ascending order, from that get the first event but only if the date hasn't past yet." I want to get the soonest upcoming event.

Share this post


Link to post
Share on other sites
(Sorry tinacious, formatting code and quotes just doesn't work for me atm...)
 
You could do it the way you've described with a little change:
if($date > $today) {
    // now you've got what you're looking for in $event
    $firstUpcomingEvent = $event;
    // break out of the loop
    break;
}
 
 
What would be the best way to go about doing this?
 
 
While the example above would do it, I'd say the best way to go is using a single get() with the right kind of selector . This is all you need:
 
$today = mktime(0,0,0,date("m"),date("d"),date("Y"));
$firstUpcomingEvent = $pages->get("template=calendar-event, calendar_event>$today, sort=calendar_event");
Although, it's a bit confusing to me when you've got a date field called 'calendar_event' in a template called 'calendar-event'. I would definitely make a mistake with that kind of setup one day myself . I'd change the name of the field to something else, like 'calendar_event_date' or whatever that makes the selectors understandable. But that's just me, the selector does work as it is.
 
Maybe it's just a snippet and there's some html coming up in the actual template file or something, but just in case: it's a good practice to omit the closing PHP tag (at the end of the file) to prevent accidental whitespace, see http://php.net/manual/en/language.basic-syntax.phptags.php
 
(
Edit 1: I don't get it, since the forum update editing code and/or quotes just does not work. Is it just me? Using Chrome on a Mac.
Edit 2: Let's see if I got it right after second edit... Going to use plain text editor from now on.
Edit 3: Nope, not even that works anymore. Without any tags then?
)
  • Like 2

Share this post


Link to post
Share on other sites

@Pete: Nope, didn't help. Even when I replaced the whole post with a plain text version (with code/quote tags with square brackets around them), divs and other html markup appeared after save. I don't think that has anything to do with js, although I haven't got a clue how this piece of software has been implemented.

It looks like others are having same kind of problems as well, see this for example: http://processwire.com/talk/topic/2616-iteration-problem-insert-element-every-nth-loop/

Share this post


Link to post
Share on other sites

Good point - what browser/OS are you on nik?

Share this post


Link to post
Share on other sites

Not sure, but I think it was 2009 when nik changed to mosaic from lynx...

  • Like 1

Share this post


Link to post
Share on other sites

Browser? You're using browsers, graphical ones?

No no, I'm using a self-written TCP/IP stack and then:

>telnet processwire.com 80

Trying 207.58.138.35...
Connected to processwire.com.
Escape character is '^]'.
GET /talk/ HTTP/1.0
Host: processwire.com
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.101 Safari/537.11
 
HTTP/1.0 200 OK
...
 
No wonder you're always faster than me with your replies...
  • Like 3

Share this post


Link to post
Share on other sites
I have an Event set up using a datetime field. I'm trying to grab the earliest event that has not yet passed, e.g. soonest upcoming event.
$event = $pages->get("template=calendar-event, sort=calendar_event, calendar_event>today"); 

if($event->id) {
  // you got one
}

That's repeating what nik already said. But I wanted to mention that you can just type "today" in the selector (no need for the mktime). PW runs any non-integer you put in there through PHP's strtotime(), so you can do things like "today", "yesterday", "next week", "+3 hours" etc. 

  • Like 2

Share this post


Link to post
Share on other sites
That's repeating what nik already said. But I wanted to mention that you can just type "today" in the selector (no need for the mktime). PW runs any non-integer you put in there through PHP's strtotime(), so you can do things like "today", "yesterday", "next week", "+3 hours" etc. 

Wow that's good to know... very nice.

The time before ProcessWire when I had to write the sql queries myself... don't miss them ;)

Share this post


Link to post
Share on other sites
(Sorry tinacious, formatting code and quotes just doesn't work for me atm...)
 
You could do it the way you've described with a little change:
if($date > $today) {
    // now you've got what you're looking for in $event
    $firstUpcomingEvent = $event;
    // break out of the loop
    break;
}

Thanks Nik, using a break within the foreach loop worked (without the $firstUpcomingEvent line). I used this code:

<?php 
$today = mktime(0,0,0,date("m"),date("d"),date("Y"));

$events = $pages->find("template=calendar-event, sort=calendar_event");
foreach($events as $event) {
	$date = $event->getUnformatted('calendar_event');
	if($date > $today) {
		echo $event->render();
		break;
	}
}
?>

I did not try your other suggestion because I tried your first one and it worked, but it does look like a more efficient, less bloated way to accomplish the same task.

Thanks for your help!  :lol:

Share this post


Link to post
Share on other sites
$event = $pages->get("template=calendar-event, sort=calendar_event, calendar_event>today"); 

if($event->id) {
  // you got one
}

That's repeating what nik already said. But I wanted to mention that you can just type "today" in the selector (no need for the mktime). PW runs any non-integer you put in there through PHP's strtotime(), so you can do things like "today", "yesterday", "next week", "+3 hours" etc. 

Thanks! I didn't realize ProcessWire could do that! That's great! :lol:  

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Elchin
      Hi.
      I want select pages where now between date and end_date or now bigger than date and end_date is empty.
      I have five tried variants:
      $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("foo=(date<$start,date_end=''),bar=(date<$start,date_end>=$start),sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("date<$start,(date_end='',date_end>=$start),sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("date_end=''|date_end>=$start,date<$start,sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("!date_end|date_end>=$start,date<$start,sort=-date,limit=12"); $start = strtotime(date('Y-m-d') . " 00:00:00"); $results = $page->children("date_end>=$start|!date_end,date<$start,sort=-date,limit=12"); All this variants not worked for me and returned zero results.
    • By MateThemes
      Hello everyone.
      I have a question that i can't find a way to solve.
      I have following function in _uikit.php 
      $date = $page->get('date|createdStr'); $dateModified = $page->get('datemodified'); But I need to output the $date in to different formats.
      My further function looks like this
      // return the blog post article markup return " <div> <article class='uk-article blog-post $class'> <meta property='name' content='$page->title'> <meta property='author' typeof='Person' content='Arra Lifte Harmanschlag'> <meta property='dateModified' content='$dateModified'> <meta property='datePublished' content='$date'> <meta class='uk-margin-remove-adjacent' property='articleSection' content='News'> <div property='image' typeof='ImageObject'> $featuredBlogPostImage </div> $heading <ul class='mt25 uk-margin-remove-bottom uk-subnav uk-subnav-divider'> <li class='uk-article-meta'> <time datetime='$date'>$byline</time> </li> </ul> <div class='mt25' property='text'> $body </div> </article> </div> "; Now I need to output the meta property in this format 2019-03-02CET05:23:00 and then a normal date format that is displayed on the Homepage with 2. März 2019 without time.
      Can anybody help me?
      Thanks in advance.
    • By louisstephens
      From my last post, I was given a good idea on how to count the repeater items, and it worked wonderfully. I got my code working well and the columns (based on the count) all work well as well. Now, I have a head scratcher on my hands. 
      <?php $buttonsIncluded = $page->special_custom_buttons->find('special_custom_buttons_include=1'); $buttonsIncludedCount = count($buttonsIncluded); $buttonsIncludedCountAdditional = $buttonsIncludedCount +1; echo $buttonsIncludedCount; ?> <div class="row"> <?php foreach($buttonsIncluded as $button): ?> <?php if($button->custom_buttons_include): ?> <?php if($buttonsIncludedCountAdditional == 2): ?> <div class="col-6"> <a href=""><?php echo $button->custom_buttons_text; ?></a> </div> <?php elseif($buttonsIncludedCountAdditional == 3): ?> <div class="col-4"> <a href=""><?php echo $button->custom_buttons_text; ?></a> </div> <?php elseif($buttonsIncludedCountAdditional == 4): ?> <div class="col-3"> <a href=""><?php echo $button->custom_buttons_text; ?></a> </div> <?php endif; ?> <?php endif; ?> <?php endforeach; ?> </div> All of this is included in a larger foreach statement that is pulling in other data (like body copy etc etc) from a Page Table field. As you can see in my code above, I am adding "1" to the count, so I can have space in the grid layout for a new button.
      So, right now: it looks something like: 
      [repeater button] [repeater button] [repeater button] [space for new button] What I really need to do is to pull in the button from the Page Table and add it into the new space so it looks like:
      [repeater button] [repeater button] [repeater button] [button from Page Table] Is this even possible todo, or is there a better way to go about this? 
       
      *Edit*
      So, I really just overlooked something quite easy here. Since the grid is based on 12 columns, I could just take 12 and divide by $buttonsIncludedCountAdditional which would give me the remaining col width to use outside the foreach loop. I was trying to make this too complicated.
    • By rolisx
      Hi all
      I have a problem here. I created a gallery with 240 pictures. Created an images field with no maximum amount (0). Unfortunately, only 98 of the 240 images show on the website. Any idea what I possibly could have done wrong? Thanks for your help!
      <?php foreach ($page->images as $image) { $options = array( 'quality' => 90, 'upscaling' => false ); $thumb = $image->size(250, 250, $options); ?> <div class="col-xl-2 col-lg-3 col-md-4 col-sm-6 col-6 foto"> <a href="<?= $image->url ?>" data-lightbox="lightbox" > <img src="<?= $thumb->url ?>" alt="" > </a> </div> <?php } ?>  
    • By celfred
      Hello !
      I have somehting I don't understand here... Here's my code :
      $allPlayers = $pages->find("parent.name=players, team=$selectedTeam"); $allTrains = $allPlayers->find("template=event, task.name~=ut-action, refPage!='', date>=$startDate, date<=$endDate, sort=refPage, sort=date"); bd('$allTrains:'.$allTrains->count()); // DISPLAYS 0 ???? foreach($allPlayers as $p) { $allTrainings = $p->find("template=event, task.name~=ut-action, refPage!='', date>=$startDate, date<=$endDate, sort=refPage, sort=date"); $test += $allTrainings->count(); } bd('$test:'.$test); // DISPLAYS 883 pages (normal) As you can read from my comments, I have no idea why my first $allTrains stays at 0 while the second request actually finds the corresponding pages. If someone could explain I'd appreciate a lot. I have been struggling with this for hours now... For your information, my pages having template 'event' are in a subtree like so :
      - player 01
        - history-1
          - event 01
         - event 02
         - event ...
        - history-2
          - event 01
          - event ...
      - player 02
        - history-1
          - event 01
         - event 02
         - event ...
        - history-2
          - event 01
          - event ...
      - player ...
        - history-1
          - event 01
         - event 02
         - event ...
        - history-2
          - event 01
          - event ...
       
      Thanks in advance. (sorry for my preceding 'tree' which doesn't look like much. I need to find a way to output this better 😉 )
×
×
  • Create New...