PHP foreach create menu from array - php

I am currently creating a joomla component, and i am currently stuck with the menu part.
this is in my model file:
public function getMenu(){
$menu_id = JRequest::getInt('id');
$db = $this->getDbo();
$query = $db->getQuery(true);
$query->select('t.country_name,t.country_code, a.continent_name');
$query->from('#__vectormap_countries AS t')
->join('LEFT', '#__vectormap_continents AS a USING(continent_id)')
->where('t.published = 1');
$db->setQuery($query);
$menu_items = $db->loadObjectList();
return $menu_items;
}
and on the front end i have:
<?php $menus = $this->menu ?>
<?php foreach($menus as $menu): ?>
<div><?php echo $menu->continent_name ?></div>
<li id="<?php echo $menu->country_code ?>"><?php echo $menu->country_name ?></li>
<br />
<?php endforeach; ?>
and that returns:
Africa
South Africa
Africa
Mozambique
or if i print out the array this:
Array ( [0] => stdClass Object ( [country_name] => South Africa [country_code] => ZA [continent_name] => Africa ) [1] => stdClass Object ( [country_name] => Mozambique [country_code] => MZ [continent_name] => Africa ) ) 1
Now Finally the question, how would i sort it so that Africa (continent_name) not be repeated but rather have all the countries that have the continent_name of Africa list underneath it?
Keep in mind North America and such will also come in to play..
Summarized question -> How would I sort countries underneath there associated continents fond in the array.
Any Help Greatly Appreciated thanks.
how would i sort it that everything

The easy fix is by ORDERing your query results and then add some logic in your foreach loop
$query->order('a.continent_name ASC, t.country_name ASC');
In your foreach loop remember what the previous continent was
<?php
$lastcontinent = "";
foreach($menus as $k => $menu):
if($lastcontinent != $menu->continent_name){
if($k > 0){ // if this isn't the first continent
// closing tags for the previous continent
echo '</ul></div>';
}
echo '<div>'.$menu->continent_name.'</div><ul>';
}
$lastcontinent = $menu->continent_name;
echo '<li id="'.$menu->country_code.'">'.$menu->country_name.'</li>';
endforeach;
?>
</ul></div> <!-- closing tags for the last continent which hasn't been closed yet -->

Use a foreach loop and make a new array and create continent_name as a key. Then you won't have a repetitive names.

Related

Foreach is showing only one result instead of all

I'm trying to select elements from only one category and show them on page.
Currently I have 5 posts in this category but on page I see only one.
Why is that?
Here is how I try
<?php
$args = array(
'showposts'=>-1,
'category_name' => 'custom-page',
);
$query = new WP_Query( $args );
$aSolutionsePost = array();
if ( $query->have_posts() ) {
while ( $query->have_posts() ) {
$aSolutionsePost = array();
$query->the_post();
$aSolutionsePost['title'] = $query->post->post_title;
$aSolutionsePost['content'] = $query->post->post_content;
}
}
?>
<div class="col-4 ">
<ul class="price">
<?php if(!empty($aSolutionsePost)){?>
<?php foreach($aSolutionsePost as $item){ ?>
<li class="header"><?php echo $item->title; ?></li>
<li class="grey"><?php echo apply_filters('the_content',$item->content);?></li>
<?php }?>
<?php }?>
</ul>
</div>
When I print_r($aSolutionsePost); I see only one result. This:
Array (
[title] => Price test title
[content] => Price test content
[0] => Array (
[title] => Price test title
[content] => Price test content
)
)
This line of code inside your while ( $query->have_posts() ) loop:
$aSolutionsePost = array();
is overwriting the value of $aSolutionsePost each pass through the loop. You probably want something like this instead:
while ( $query->have_posts() ) {
$query->the_post();
$aSolutionsePost[] = array('title' => $query->post->post_title,
'content' => $query->post->post_content);
}
Note that in your code to echo the results, you are treating the array elements as objects, not associative arrays. It's simplest to just change those lines to this:
<li class="header"><?php echo $item['title']; ?></li>
<li class="grey"><?php echo apply_filters('the_content',$item['content']);?></li>
but if you want to keep that code the same you can change the assignment line to this:
$aSolutionsePost[] = (object)array('title' => $query->post->post_title,
'content' => $query->post->post_content);
Check array set inside while,
You re-create $aSolutionsePost every time, so it will be reseted.
Solution is to create new array and append it to $aSolutionsePost, check below snippet.
while ( $query->have_posts() ) {
$tmpSolutionsePost = array();
$query->the_post();
$tmpSolutionsePost['title'] = $query->post->post_title;
$tmpSolutionsePost['content'] = $query->post->post_content;
$aSolutionsePost[] = $tmpSolutionsePost;
}
You are actually updating the same array with new values in the loop.
$finalData =array();
while ( $query->have_posts() ) {
$aSolutionsePost = array();
$query->the_post();
$aSolutionsePost['title'] = $query->post->post_title;
$aSolutionsePost['content'] = $query->post->post_content;
$finalData[] = $aSolutionsePost;
}
Now iterate over $finalData.
This is because you are adding the element to same key of array again and again and that is why there is only 1 element in the array, hence foreach is showing only 1 element.
You should possibly take 2d array to solve this purpose.

Add class to ACF multi select

I have been struggling for two hours with the following situation and I still didn't find the solution. Hopefully you guys can help me out. It's about the following:
I use ACF to make a selection from a multi select menu. I want to show all of the choices and I want to add a class to the selected values.
Below you will find my code so far. This outputs all of the choices. But I don't know how to check whether the choice has been selected or not.
$features = get_field_object('features');
$choices = $features['choices'];
$values = $features['value'];
if ( $features ):
echo '<ul class="checks">';
foreach ( $choices as $choice) {
echo '<li>'. $choice .'</li>';
}
echo '</ul>';
endif;
Thanks a lot for helping!
You can check if the key of the current $choice is as a value in the $values array.
if you var_dump the $features array you will see that $values array contains the keys of the values and the $choices array contains both of them.
var_dump example:
$features['value'] => Array
(
[0] => color1
)
$features['choices'] => Array
(
[color1] => red
[color2] => yellow
[color3] => green
)
Code:
$features = get_field_object('features');
$choices = $features['choices'];
$values = $features['value'];
if ( $features ):
echo '<ul class="checks">';
foreach ( $choices as $key => $choice) {
$class = in_array($key, $values) ? 'class="selected"' : '';
echo '<li ' . $class . '>'. $choice .'</li>';
}
echo '</ul>';
endif;

Recursive sitemap array function php

I having some problems generating a full tree of my db(sitemap). I reached a level that i want to write better code. Thats why i choose a recursive function for this puzzle.
I want to generate a endless unordered list.
Like so:
<ul>
<li><a></a>
<ul>
<li><a></a>(subs)
etc etc etc.....
</ul>
</li>
</ul>
Like i already said i tried the following:
<?php
function traverseArray($array, $sub=false)
{
foreach($array as $cat)
{
if(isset($cat['childeren']) && is_array($cat['childeren']))
{
//a category with subs
echo('<ul id="'.$cat['parent_cat_id'].'" class="lv0">');
echo('<li id="'.$cat['parent_cat_id'].'"><a href=#>'.$cat['name'].'</a>'."\n");
traverseArray($cat['childeren'], true);
}else{
if($sub){
//a sub category of category
echo('</ul></li>');
echo('<li id="'.$cat['parent_cat_id'].'"><a href=#>'.$cat['name'].'</a></li>'."\n");
}else{
//category with no subs
echo('<ul id="'.$cat['parent_cat_id'].'" class="lv0">');
echo('<li id="'.$cat['parent_cat_id'].'"><a href=#>'.$cat['name'].'</a></li>'."\n");
echo('</ul>');
}
}
}
}
traverseArray($sitemap);
?>
but this is a puzzle i cant figure out properly,
this the result so far(messy):
<ul id="0" class="lv0">
<li id="0"><a href=#>Headsets</a>
</ul></li>
<li id="1"><a href=#>(USB) headsets ....</a></li>
</ul></li>
<li id="1"><a href=#>... headsets</a></li>
</ul></li>
<li id="1"><a href=#>.. USB headsets</a></li>
</ul></li>
<li id="1"><a href=#>Bluetooth headsets</a></li>
<ul id="0" class="lv0">
<li id="0"><a href=#>Unified Communications</a></li>
A big mess!
The $sitemap array looks like this:
Array
(
[0] => Array
(
[category_id] => 1
[parent_cat_id] => 0
..........etc
........etc
[type] => cat
[childeren] => Array
(
[0] => Array
(
[category_id] => 2
[parent_cat_id] => 1
.......etc
[type] => cat
[childeren] => Array
(
[0] => Array
(
[category_id] => 32
[parent_cat_id] => 16
.......etc
[type] => series
)
)
So childeren in childeren in childeren,
Is this the best way to do this/ on the right track?
Or are there beter ways out there?
Like sql tree's or something? or just again the old foreach in foreach ..(which i am trying to avoid this time).
Any help would be much appreciated!!!
Thanks in advance,
Jacob
"What is wrong with my code?" is not a question for stackoverflow.
Think about what 'traverseArray' function should do.
Your code is a mess.
Here is a cleaned example of array traversing.
Please fit it to your needs:
function traverseArray($array)
{
echo '<ul>';
foreach($array as $cat)
{
echo '<li>';
if(isset($cat['childeren']) && is_array($cat['childeren']))
{
echo '' . $cat['name'] . '';
traverseArray($cat['childeren']);
}
else
{
echo '' . $cat['name'] . '';
}
echo '</li>';
}
echo '</ul>';
}
traverseArray($sitemap);

Creating a bullet list using mysql table data

I have a table similar to the following:
subcategory category
------------------------
apples fruits
oranges fruits
pears fruits
honda cars
volvo cars
audi cars
What would be an easy way to print out something like the example below, using php and mySQL?
Example:
Fruits:
Apples
Oranges
Pears
Cars:
Honda
Volvo
Audi
I have been trying to figure this out for hours now, I appreciate any advice.
Get a list of categories, and then subcategories in each categories.
<?php
$categories = array();
foreach ($results as $result) {
$category = $result['category'];
$categories[$category][] = $result['subcategory'];
}
This will then give you a multidimensional array, with categories and the keys, and the sub-categories as the values. You can loop over them as thus:
<ul>
<?php foreach ($categories as $category => $subcategories): ?>
<li>
<?php echo $category; ?>
<ul>
<?php foreach ($subcategories as $subcategory): ?>
<li><?php echo $subcategory; ?></li>
<?php endforeach; ?>
</ul>
</li>
<?php endforeach; ?>
</ul>
$data = getData();
$dataByCat = array();
foreach($data as $row) {
$dataByCat[$row['category']][] = $row;
}
$dataByCat will be an array in the "shape" of your bullet points.

Looping through multiple arrays and display select options

I have a multi-select box for country selection. I want to select any countries which are associated, meaning an array I get from the database.
Here's the code I have:
<?php
foreach($countries as $country){
if(!empty($offer_countries)){
foreach($offer_countries as $key => $offer_country){
if(isset($offer_country['country_id']) && ($offer_country['country_id'] == $country['id'])){
echo '<option value="'.$country['id'].'" selected>'.$country['name'].'</option>';
}else{
echo '<option value="'.$country['id'].'">'.$country['name'].'</option>';
}
}
}else{
echo '<option value="'.$country['id'].'">'.$country['name'].'</option>';
}
}
?>
The $offer_countries array, looks like this:
Array
(
[0] => Array
(
[country_id] => 1
)
[1] => Array
(
[country_id] => 2
)
[2] => Array
(
[country_id] => 3
)
)
I'm looping all countries to display them, then I have a nested foreach to see if the country is already set, if so, make the option box selected.
The problem with this is that let's say I have 3 items selected, it'll display 3 of the same country, based on the number of items in the array. So if United States should be checked, it'll show it three times, with the last one checked.
Ok, sorry for the looong explanation, it's probably fairly self explanatory, but any help would be awesome!
This solved it:
<?php
foreach($countries as $country){
$i = 0;
if(!empty($offer_countries)){
foreach($offer_countries as $key => $offer_country){
if($offer_country['country_id'] == $country['id']){
echo '<option value="'.$country['id'].'" selected>'.$country['name'].'</option>';
$i = 1;
break;
}
}
if($i == 0){
echo '<option value="'.$country['id'].'">'.$country['name'].'</option>';
}
}else{
echo '<option value="'.$country['id'].'">'.$country['name'].'</option>';
}
}
?>
Your inner 'foreach' statement is going to output 'something' whether or not the value is set, and it does so based on the $country variable set up in the outer foreach loop.
So what happens is that you output on the outer 'foreach' loop once for each time it runs on the inner foreach loop.

Categories