Filtering out items using SimpleXML - php

Been looking around and am stumped. Basically I'm trying to filter out a result from an xml feed and hide it from displaying in the html output. I'm trying to find out the venue "Hornblower Cruises and Events" and if it exists, hide the whole , which is the parent of all the nodes.
Here's the URL: http://www.sandiegomagazine.com/goldstartest/rss3-exclude.php
Here's my code:
<?php
$myfeed = simplexml_load_file('https://www.goldstar.com/api/listings.xml?api_key=6d0d598c69dfecfcf028b0d2b3c9b693b606ad8c&postal_code=92101');
$i = 0;
foreach ($myfeed as $goldstar):
$title=$goldstar->headline_as_html;
$summary=$goldstar->summary_as_html;
$dates=$goldstar->upcoming_dates->event_date->date;
$ourprice=$goldstar->our_price_range;
$fullprice=$goldstar->full_price_range;
$img=$goldstar->image;
$link=$goldstar->link;
$venue_name=$goldstar->venue->name;
$venue_street=$goldstar->venue->address->street_address;
$venue_locality=$goldstar->venue->address->locality;
$venue_region=$goldstar->venue->address->region;
$venue_zip=$goldstar->venue->address->postal_code;
$venue_phone=$goldstar->venue->phone;
$category=$goldstar->category_list->category->name;
// if ($venue_name == 'Hornblower Cruises and Events'){
// unset($myfeed->event);
//echo $myfeed->asxml();
//}
if (++$i > 20) {
// stop after 10 loops
break;
}
?>
<html>
<head></head>
<body>
<div class="gs-item">
<div class="gs-itemcontent">
<h3 class="gs-cat"><?php echo $category; ?></h3>
<h2><?php echo $title; ?></h2>
<h4 class="gs-date">Date: <?php echo $dates; ?> <br/>For more show dates, click here</h4>
<img src="<?php echo $img; ?>" />
<p><?php echo $summary; ?></p>
<div id="gs-callout">
<span class="fullprice">Full Price: <?php echo $fullprice; ?></span>
<br/>
<span class="ourprice">Our Price: <span class="gs-hilite"><?php echo $ourprice; ?></span></span>
<p><a class="gs-button" href="<?php echo $link; ?>" target="_blank">Buy Tickets ยป</a></p>
</div>
<ul class="gs-venue">
<li><strong><?php echo $venue_name; ?></strong> | </li>
<li><?php echo $venue_street; ?></li>
<li><?php echo $venue_locality; ?>, <?php echo $venue_region; ?> <?php echo $venue_zip; ?></li>
<li><?php echo $venue_phone; ?></li>
</ul>
</div>
<div class="gs-clear"></div>
</div>
<? endforeach; ?>
</body>
Help?

Use a keyed foreach
foreach ($myfeed as $key => $goldstar):
And then unset the entire current xml using the key
unset($myfeed->$key);
Or unset just the venue with unset($myfeed->$key->venue);
Alternately, you could just build a new obj instead of trying to edit the existing one. Instantiate a new object before your loop and then only add the pieces to it that you want to keep.
Or, you can just continue the foreach if you find the unwanted venue. The only downside is that you won't have a copy of your ok'd list in $myfeed. So...
if ($venue_name == 'Hornblower Cruises and Events') { continue; }

Firstly you should cast every object that you are getting from your SimpleXML object to the relevant type. For example you should cast string attributes or nodes with putting (string) before reading the field:
$venue_name = (string)$goldstar->venue->name
For your question about filtering, I'd suggest your own way to keep looking for the match string and then decide to add or not.
EDIT
You're trying to see if the venue name is 'Hornblower Cruises and Events' then unset the current event field and echo it as XML? Firstly you should write unset($myfeed) because it's the event field itself. Next asxml would return nothing if you unset $myfeed. And you have HTML mistake in your code. In every loop of your for, you're writing:
<html>
<head></head>
<body>
You should place them before the for. And there is no closing tag for them. Put the closing tags after for. If you want to just get the fields with not venue name 'Hornblower Cruises and Events', put the <?php if($venue_name != 'Hornblower Cruises and Events') : ?> before <div class="gs-item"> and put <?php endif; ?> after </ul>.

Related

Combining php loop and count - Wordpress ACF

I wondered if anyone could help me combine two blocks of code I have. I have one block looping though items and the start of another block showing a count and hopefully enabling me to display the items looping through in rows by adding a div around them every two items... Heres the first bit of code, the loop:
<?php if(get_field('areas')): ?>
<?php while(has_sub_field('areas')): ?>
<div class="single-area-item six columns">
<p> <img src="<?php the_sub_field('area_icon'); ?>" style="width:100%;"> <p>
<h4> <?php the_sub_field('area_title'); ?> </h4>
<p> <?php the_sub_field('area_info'); ?> <p>
</div>
<?php endwhile; ?>
<?php endif; ?>
I'm using Advance Custom Fields for Wordpress and this is pulling through repeater fields... this displays them just one after the other.
Here's the code I have found to hopefully display them in rows.
<?php
$num = 1;
foreach ( $terms as $term ) {
if($num%2) {
echo '<div class="area-row">';
}
// Other Code
if($num %2) {
echo '</div>';
}
$num++
}
?>
I would like to display them in rows of two...
ONE TWO
THREE FOUR
FIVE SIX
Etc...
So, Im guessing I need to combine the code somehow... I currently have this: but it doesn't seem to work:
<?php
$num = 1;
foreach ( $terms as $term ) {
if($num%2) {
echo '<div class="area-row">';
}
if(get_field('areas')): ?>
<?php while(has_sub_field('areas')): ?>
<div class="single-area-item six columns">
<p> <img src="<?php the_sub_field('area_icon'); ?>" style="width:100%;"> <p>
<h4> <?php the_sub_field('area_title'); ?> </h4>
<p> <?php the_sub_field('area_info'); ?> <p>
</div>
<?php endwhile; ?>
<?php endif; ?>
if($num %2) {
echo '</div>';
}
$num++
}
?>
Okay so it looks like there was a couple of simple issues with this, you had closed the php tag after your if statment and then continued to write php without reopening the php tags. Also there is a slight logic error with the if($num%2) statements as one of these needs to be if, the other needs to be if not, so that the alternate.
Give this code a try and let me know how you get on:
<?php
if(get_field('areas')):
$num = 1;
?>
<?php while(has_sub_field('areas')):
if($num%2) {
echo '<div class="area-row">';
} ?>
<div class="single-area-item six columns">
<p> <img src="<?php the_sub_field('area_icon'); ?>" style="width:100%;"> <p>
<h4> <?php the_sub_field('area_title'); ?> </h4>
<p> <?php the_sub_field('area_info'); ?> <p>
</div>
<?php
if(!$num%2) {
echo '</div>';
}
$num++
endwhile; ?>
<?php endif; ?>
The main reason behind this question was for me to be able to target the third item of the looped through items, as it had padding on it that was breaking the rows that I needed to remove.
I have since found another solution that seems to be working.
By using the nth-child element, I have been able to target and remove the padding on every third item that's looped through - fixing the issue.
.single-area-item:nth-child(3n+3) {
margin-left: 0;
}
This is for rows or 2 items, if it were rows of 3 or 4 then it would need to target every 4th or 5th item respectively.

Yii2: how to display images from backend/web to frontend in advanced app

I need to display 1 (first) image which path is saved in database like Img1.jpg;img2.jpg;, I tried to seperate each path by using explode, getting all the images as array but not able to pick single path-
<div class="col-sm-6 masonry-item">
<a href="<?php echo Url::to(['site/roompage']); ?>" class="product_item text-center">
<span class="product_photo bordered_wht_border">
<?php
foreach (explode(';',rtrim($row['images'],';'),1) as $key_img => $value_img)
{
?>
<?php echo Html::img('#backend/web'.'/'.$value_img);?>
<?php
}
?>
</span>
<span class="product_title"><?php echo $row['room_type']; ?></span>
<span class="product_price">Rs.<?php echo $row['rate']; ?></span>
</a>
</div>
<?php endforeach; ?>
<?php
// if you want only the first image is better
$my_image = explode(';',rtrim($row['images'],';'),1);
echo Html::img('#backend/web'.'/'.$my_image[0]);
}
?>
otherwise
<?php
// if you want all the image
foreach (explode(';',rtrim($row['images'],';')) as $key_img => $value_img)
{
echo Html::img('#backend/web'.'/'.$value_img);
}
?>
this because (explode(';',rtrim($row['images'],';'),1) return an array of two element (the first and the rest)
The src parameter, containing the backend alias, will be processed by Url::to()
Check the docs for details on Html::img()

Wrap output with link from field in drupal views

I have a view that is outputting a list of nodes that contain a link, image and text.
I want to use the link field to wrap the output (rather than link to the node), but I can't figure out how to get the raw url/title etc to create create that link in the template.
The field is configured to output the url as plain text, but is wrapped in div/spans regardless of the style settings for the view field.
views-view-fields--my-view.php:
<a href="<?php echo $fields['field_link']->content ?>">
<?php foreach ($fields as $id => $field):
if ($id == 'field_link') continue;
?>
<?php if (!empty($field->separator)): ?>
<?php print $field->separator; ?>
<?php endif; ?>
<?php print $field->wrapper_prefix; ?>
<?php print $field->label_html; ?>
<?php print $field->content; ?>
<?php print $field->wrapper_suffix; ?>
<?php endforeach; ?>
</a>
This produces:
<a href="<div class=" data-thmr="thmr_72"><div class="field-items"><div class="field-item even"><span data-thmr='thmr_24' class='devel-themer-wrapper'>/drupal/%237digital-buy</span></div></div></div>">
[...]
</a>
Which is obviously not what I need.
Found the solution. You need to rewrite the output. See below.

Offset PHP array results

I am looking to offset a group of PHP array results to create multiple rows of data.
For example, the first row will contain the first four array results, with the second row displaying results 5-8 and the third row containing results 9-12.
Currently, I am printing out all 12 in one list, however I'd like a bit more display control (i.e. ordering the results into columns which I can style independent of each), hence why I'd like to offset the results.
My current PHP is below:
<?php
if (empty($tmdb_cast['cast'])) {
} else {?>
<section class="cast">
<p class="title">Cast</p>
<ul class="section_body"><?php
foreach($tmdb_cast['cast'] as $key => $castMember){
if ($key < 12) {?>
<li class="actor_instance clearfix"><?php
if ($castMember['profile_path'] != '') {?>
<img src="http://cf2.imgobject.com/t/p/w45<?php echo $castMember['profile_path']; ?>" class="actor_image pull-left" alt="<?php echo $castMember['name']; ?>" title="<?php echo $castMember['name']; ?>" /><?php
} else {?>
<img src="assets/images/castpic_unavailable.png" class="actor_image pull-left" alt="No image available" title="No image available" /><?php
}?>
<p class="actor"><?php echo $castMember['character']; ?> - <?php echo $castMember['name']; ?></p>
</li><?php
}
}?>
<div class="morecast pull-right">[...view all cast]</div>
</ul>
</section><?php
}?>
P.S. Apologies for how I've formatted the code in the above block - I'm still not 100% sure how to make it look "nice" on StackOverflow.
Use array_chunk to break a single dimension array into a 2D array. Then you can loop through each chunk, and then each result, to get that "offset" effect between them.
$chunks = array_chunk($tmdb_cast['cast'], 4); // 4 here, is the number you want each group to have
foreach($chunks as $key => $chunk)
{
foreach($chunk as $castMember)
{
//display castMember here
}
// add code between groups of 4 cast members here
}
First: mixing php and html this way is a very bad habbit... one day you will have to maintain your code and that day you will vomit all over your desk because you mixed different languages in one file...
That being said..
and without creating a new array:
foreach($tmdb_cast['cast'] as $key => $castMember)
{
if ($key < 12)
{
// your code goes here
// if key is 3, or 7 the code below will close the listcontainer and open a new one...
if( ($key+1)%4 == 0 AND $key <11)
echo '</ul> <ul class="section_body">';
}
}
Also replace this:
if (empty($tmdb_cast['cast']))
{
}
else {
with this:
if (!empty($tmdb_cast['cast']))
{
I'm not entirely sure what you're looking for but here's how I would format your code. Alternative syntax for 'if' is a little more readable, and the use of for loops instead of a foreach will give you the control over row numbers you say you're looking for.
<?php if( ! empty($tmdb_cast['cast'])): ?>
<section class="cast">
<p class="title">Cast</p>
<ul class="section_body">
<?php
for($i = 0; $i < 12; $i++):
$castMember = $tmdb_cast['cast'][$i];
?>
<li class="actor_instance clearfix">
<?php if($castMember['profile_path'] != ''): ?>
<img src="http://cf2.imgobject.com/t/p/w45<?php echo $castMember['profile_path']; ?>" class="actor_image pull-left" alt="<?php echo $castMember['name']; ?>" title="<?php echo $castMember['name']; ?>" />
<?php else: ?>
<img src="assets/images/castpic_unavailable.png" class="actor_image pull-left" alt="No image available" title="No image available" />
<?php endif; ?>
<p class="actor"><?php echo $castMember['character']; ?> - <?php echo $castMember['name']; ?></p>
</li>
<?php endfor; ?>
<div class="morecast pull-right">[...view all cast]</div>
</ul>
</section>
<?php endif; ?>

Help with a foreach loop

In my website I am trying to display all the applicants to jobs that a user has posted, basically I want the out put to simimlar too,
Job Title 1
Aplicant Name 1
Aplicant Name 2
Applicant Name 3
Job Title 2
Applicant Name 4
Application Name 5
Basically I want the applications to be gathered under the jobs they applied for, however the out put I am current getting is,
Job Title 1
Application Name 1
Job Title 1
Applicant Name 2
The code I am using to do this foreach loop is as follows
<?php foreach($applications as $a) : ?>
<h3><?php echo $a['jobtitle']; ?></h3>
<li>
<img src="/media/uploads/candidates/<?php echo preg_replace('/(.gif|.jpg|.png)/', '_thumb$1', $a['profile_image']);?>" width="90" height="60"/>
<p><?php echo $a['name']; ?></p>
</li>
<?php endforeach; ?>
We need the data structure to properly answer, but I'm assuming you need a nested foreach...
<? foreach($jobs as $j): ?>
# list jobs
<? foreach($applicants as $a): ?>
<? if ($j['jobtitle'] == $a['jobtitle']): ?>
# list applicants
<? endif; ?>
<? endforeach; ?>
<? endforeach; ?>
Well you are getting that because you are only outputting
$a['jobtitle']
and
$a['name']
Where are the other names stored? Something like this is probably what you want, although that won't work if you copy/paste it as it seems that $applications[x]['name'] is not an array:
<?php foreach($applications as $a) : ?>
<h3><?php echo $a['jobtitle']; ?></h3>
<li>
<img src="/media/uploads/candidates/<?php echo preg_replace('/(.gif|.jpg|.png)/', '_thumb$1', $a['profile_image']);?>" width="90" height="60"/>
<?php foreach($a['name'] as $name)?>
<p><?php echo $name; ?></p>
<?php endforeach; ?>
</li>
<?php endforeach; ?>
I recommend pulling jobtitle and applicants from the database and storing them in a multidimensional array.
$jobs[$jobtitle][] = $applicant_name;
Then looping through this array in your view. I've omitted your image code for clarity.
foreach($jobs as $title=>applicants){
echo $title;
foreach($applicants as $name){
echo $name;
}
}

Categories