How to merge 3 arrays keeping their meta key? - php

I'm Getting some arrays from some wordpress custom fields:
$content = array(get_post_meta($postId, 'content'));
$media = array(get_post_meta($postId, 'media'));
$yt = array(get_post_meta($postId, 'youtube'));
I then need to have it printing in sequence, like:
media
content
LInk
Embed
And repeat the sequence for each value
media
content
LInk
Embed
For the sequence I'd use this:
echo '<ul>';
for ($i = 0; $i < count($all_array['media']); $i++) {
for ($j = 0; $j < count($all_array['content']); $j++) {
for ($k = 0; $k < count($all_array['youtube']); $k++) {
echo '<li>media->' . $all_array['media'][$i] . '</li>';
echo '<li>content->' . $all_array['content'][$j] . '</li>';
echo '<li>link->' . $all_array['link'][$k] . '</li>';
}
}
}
echo '</ul>';
But I'm doing something wrong with the merging of the 3 fields as if I do a var_dump before to run the for bit, like
echo '<pre>' . var_export($all_array, true) . '</pre>';
Then this is what I get and I cannot iterate as I wish:
array (
0 =>
array (
0 =>
array (
0 => '
brother
',
1 => '
Lorem
',
2 => '
End it
',
),
1 =>
array (
0 => '337',
1 => '339',
),
2 =>
array (
0 => 'https://www.youtube.com/watch?v=94q6fzbJUfg',
),
),
)
Literally the layout in html that I'm looking for is:
image
content
link
image
content
link
...
UPDATE
This how I am merging the arrays:
foreach ( $content as $idx => $val ) {
$all_array[] = [ $val, $media[$idx], $yt[$idx] ];
}
This is the associative array how it looks like:
Content:
array (
0 =>
array (
0 => '
brother
',
1 => '
Lorem
',
2 => '
End it
',
),
)
Media
array (
0 =>
array (
0 => '337',
1 => '339',
),
)
Youtube
array (
0 =>
array (
0 => 'https://www.youtube.com/watch?v=94q6fzbJUfg',
),
)

The way I've resolved it is first I calculate the tot. items within each array, then I get the array with max items and loop and add the items in sequence:
//GET CUSTOM FIELDS
$content = get_post_meta($post_to_edit->ID, 'content', false);
$media = get_post_meta($post_to_edit->ID, 'media', false);
$yt = get_post_meta($post_to_edit->ID, 'youtube', false);
$max = max(count($content), count($media), count($yt));
$combined = [];
//
// CREATE CUSTOM FIELDS UNIQUE ARRAY
for($i = 0; $i <= $max; $i++) {
if(isset($media[$i])) {
$combined[] = ["type" => "media", "value" => $media[$i]];
}
if(isset($content[$i])) {
$combined[] = ["type" => "content", "value" => $content[$i]];
}
if(isset($yt[$i])) {
$combined[] = ["type" => "youtube", "value" => $yt[$i]];
}
}
Finally I can loop:
foreach ($combined as $key => $val) {
if($val['type'] === "media") {
...
}
if($val['type'] === "content") {
...

You don't need to merge the arrays together. It will work fine in separate arrays. However, your for loops don't have the right logic. Try:
for ($i = 0; $i < count($media); $i++) {
for ($j = 0; $j < count($media[$i]); $j++) {
echo '<li>media->' . $media[$i][$j] . '</li>';
}
for ($j = 0; $j < count($content[$i]); $j++) {
echo '<li>content->' . $content[$i][$j] . '</li>';
}
for ($j = 0; $j < count($youtube[$i]); $j++) {
echo '<li>link->' . $youtube[$i][$j] . '</li>';
}
}

Related

How to count the number of item in foreach loop based by it's parent?

I have a simple loop to display a list. But I do not know how to count it's parent item. This is my current attempt:
$no = 0;
$ct = 0;
$type = "";
foreach($item as $row_item){
$no = $no + 1;
if($type != $row_item['type']){
$ct = $ct + 1;
}
echo $no." ".$row_item['type']." ".$row_item['item'];
$type = $row_item['type'];
}
My desired output :
1 TYPE_A 3 A1
2 TYPE_A 3 A2
3 TYPE_A 3 A3
4 TYPE_B 2 B1
5 TYPE_B 2 B2
In order to count the total number of each type you'll need to iterate over the entire collection twice. Once to count the totals, and once to display the results for each row. The code below actually does 3 loops, the array_filter method iterates over the entire array, but I like the clean code. :)
http://sandbox.onlinephpfunctions.com/code/962f418715d1518c818732f6e59ba4f28d5a19f3
<?php
$items = array(
array( 'name' => 'A1', 'type' => 'TYPE_A' ),
array( 'name' => 'A2', 'type' => 'TYPE_A' ),
array( 'name' => 'A3', 'type' => 'TYPE_A' ),
array( 'name' => 'B1', 'type' => 'TYPE_B' ),
array( 'name' => 'B2', 'type' => 'TYPE_B' )
);
function is_TYPE_A( $item ) {
return $item['type'] == 'TYPE_A';
}
function is_TYPE_B( $item ) {
return $item['type'] == 'TYPE_B';
}
$TYPE_A_COUNT = count( array_filter( $items, 'is_TYPE_A' ) );
$TYPE_B_COUNT = count( array_filter( $items, 'is_TYPE_B' ) );
function getTypeTotalByItem( $item ) {
global $TYPE_A_COUNT, $TYPE_B_COUNT;
if ( $item['type'] == 'TYPE_A' ) {
return $TYPE_A_COUNT;
}
if ( $item['type'] == 'TYPE_B' ) {
return $TYPE_B_COUNT;
}
}
for ( $i = 0; $i < count( $items ); $i++ ) {
echo ( $i + 1 )." ".$items[$i]['type']." ".getTypeTotalByItem($items[$i])." ".$items[$i]['name']."\n";
}
You can use array_map() and a couple foreach() loops for this if you were so inclined. It should interpret fairly quickly:
# Create a storage array
$counter = [];
# Sort the main array into type
array_map(function($v) use (&$counter){
# Store the subs under the type
$counter[$v['type']][] = $v['item'];
},$items);
# Start counter
$i = 1;
# Loop through each type
foreach($counter as $title => $row){
# Count how many are under this type
$count = count($row);
# Loop the rows in the types arrays
foreach($row as $item) {
# Write increment, type, total count, item
echo $i." ".$title." ".$count." ".$item.'<br />';
$i++;
}
}

How to show these massives by two pair?

I need to sort these massives:
$arr1 = array(
'audio',
'audio',
'audio',
'audio',
'audio',
);
$arr2 = array(
'video',
'video',
'video'
);
Using a for loop:
$result = array_merge($arr1, $arr2);
for($i = 0; $i < count($result); $i++){
$finally_arr[] = $arr1[$i];
$finally_arr[] = $arr2[$i];
}
Finally I want to get like this:
$finally_arr = array(
[0] => audio
[1] => video
[2] => video
[3] => audio
[4] => audio
[5] => video
[6] => audio
[7] => audio
);
The first item is single, others come in pairs, like chess:
audio video
video audio
audio video
audio audio
Providing that items in array which is more, go down together.
How to write this loop?
$lenght = max(count($arr1), count($arr2));
$i = 0;
while ($i < $lenght){
// One order
if(array_key_exists($i, $arr1))
$finally_arr[] = $arr1[$i] . '<br>';
if(array_key_exists($i, $arr2))
$finally_arr[] = $arr2[$i] . '<br>';
if(++$i >= $lenght) break;
// Revert order
if(array_key_exists($i, $arr2))
$finally_arr[] = $arr2[$i] . '<br>';
if(array_key_exists($i, $arr1))
$finally_arr[] = $arr1[$i] . '<br>';
$i++;
}

PHP dynamic lists of arrays

Please can somebody help me with a solution to make a a string list of array like:
$string=array1, array2, .........., arrayn.
I need to generate this list dynamically.
Now I send it each array in list but I want to increase the numbers and I wonder how to put arrays dynamically inside the list.
In my code I have something like this:
$array[$j]
I need to create a list like this:
$string=$string.','.$array[$j]
...but it doesn't work. I can't send it as a multidimensional array.
Does anyone have any ideas?
if you are talking about a multidimensional array:
$container[0] = $string;
$container[1] = $array;
$container[2] = $my_other_array;
// ...
then for example $container[1] will contain your $array and with $container[1][$j] you can access the key $j in your original array.
My code is
$Copii = [];
$Config_Camere = [];
$nrCamere = $array['Camere'];
for ($i = 1; $i <= $nrCamere; $i++) {
if ($array['Copii_Cam' . $i] >= 1) {
for ($j = 1; $j <= $array['Copii_Cam' . $i]; $j++) {
$Copii[$j] = array_combine(['AgeQualifyingCode', 'Count', 'Age'], ['c', '1', $array['varstaCopil' . $j . '_Cam' . $i]]);
}
if ($array['Copii_Cam' . $i] == 2) {
$Config_Camere['RoomRequest'] = ['IndexNumber' => $i, 'GuestsCount' => ['GuestCount' => [['AgeQualifyingCode' => 'a', 'Count' => $array['Adulti_Cam' . $i]], $Copii[1], $Copii[2]]]];
} else if ($array['Copii_Cam' . $i] == 1) {
$Config_Camere['RoomRequest'] = ['IndexNumber' => $i, 'GuestsCount' => ['GuestCount' => [['AgeQualifyingCode' => 'a', 'Count' => $array['Adulti_Cam' . $i]], $Copii[1]]]];
}
} else {
$Config_Camere['RoomRequest'] = ['IndexNumber' => $i, 'GuestsCount' => ['GuestCount' => ['AgeQualifyingCode' => 'a', 'Count' => $array['Adulti_Cam' . $i]]]];
}
}
And if you see i want to generate dinamicaly the array $Copii
Thanks a lot

JSON encoding from wordpress database values

I need a proper JSON file with "geo_langitude", "geo_latitude", "adress" & "url" values
I have wp database with post_meta "property" - "geo_langitude" "geo_latitude" & "address" in there.
my file is smth like that
<?php
function return_markers($count) {
$query = new WP_Query('post_type=property&posts_per_page=-1&orderby=menu_order&order=DESC&post_status=publish');
$array = array();
$i = 0;
for ($i = 0; $i< $count; $i++) {
$elem = array(
't' => 'string '.$i,
'x' => get_post_meta($post->ID,'geo_latitude',true),
'y' => get_post_meta($post->ID,'geo_longitude',true),
'z' => $i
);
$array[] = $elem;
}
echo json_encode($elem);
};
return_markers($i);
?>
It's my first time using JSON so I have troubles and I don't know where. =(
with random markers work perfectly:
<?php
function return_markers($count) {
$array = array ();
for ($i = 0; $i< $count; $i++) {
$elem = array(
't' => 'string '.$i,
'x' => 23 + (rand ( 0 , 10000 ) / 10000) * 5,
'y' => 56.2 + (rand ( 0 , 10000 ) / 10000) * 0.8,
'url' => '#map_redirect_'.$i,
'z' => $i
);
$array[] = $elem;
}
echo json_encode($array);
};
return_markers(23);
?>

Creating php arrays from sql queries

I'm trying to create an array of arrays so I can build a dynamic menu, but I'm getting lost amongst the code. My output looks like this:
$menu = Array (
[0] => Array (
[text] => Home
[class] => 875
[link] => //Home
[show_condition] => TRUE
[parent] => 0
)
[1] => Array (
[text] => About
[class] => 326
[link] => //About
[show_condition] => TRUE
[parent] => 0
)
etc
etc
etc
[339] => Array (
[text] => Planner
[class] => 921
[link] => //Planner
[show_condition] => TRUE
[parent] => 45
)
)
And the two functions which should build the menu are:
function build_menu ( $menu ) {
$out = '<div class="container4">' . "\n";
$out .= ' <div class="menu4">' . "\n";
$out .= "\n".'<ul>' . "\n";
for ( $i = 1; $i <= count ( $menu )-1; $i++ )
{
if ( is_array ( $menu [ $i ] ) ) {//must be by construction but let's keep the errors home
if ( $menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == 0 ) {//are we allowed to see this menu?
$out .= '<li class="' . $menu [ $i ] [ 'class' ] . '"><a href="' . $menu [ $i ] [ 'link' ] . '">';
$out .= $menu [ $i ] [ 'text' ];
$out .= '</a>';
$out .= get_childs ( $menu, $i );
$out .= '</li>' . "\n";
}
}
else {
die ( sprintf ( 'menu nr %s must be an array', $i ) );
}
}
$out .= '</ul>'."\n";
$out .= "\n\t" . '</div>';
return $out . "\n\t" . '</div>';
}
function get_childs ( $menu, $el_id ) {
$has_subcats = FALSE;
$out = '';
$out .= "\n".' <ul>' . "\n";
for ( $i = 1; $i <= count ( $menu )-1; $i++ )
{
if ( $menu [ $i ] [ 'show_condition' ] && $menu [ $i ] [ 'parent' ] == $el_id ) {//are we allowed to see this menu?
$has_subcats = TRUE;
$add_class = ( get_childs ( $menu, $i ) != FALSE ) ? ' subsubl' : '';
$out .= ' <li class="' . $menu [ $i ] [ 'class' ] . $add_class . '"><a href="' . $menu [ $i ] [ 'link' ] . '">';
$out .= $menu [ $i ] [ 'text' ];
$out .= '</a>';
$out .= get_childs ( $menu, $i );
$out .= '</li>' . "\n";
}
}
$out .= ' </ul>'."\n";
return ( $has_subcats ) ? $out : FALSE;
}
But the menu is refusing to show any submenu levels - it only displays top level. Any ideas?
Thanks!
Your code is almost there - you may want to change mysql_fetch_array to mysql_fetch_assoc, and you can convert values as returned into the appropriate types using functions like intval:
$menu = array();
$sql = "SELECT TabName as text, TabID as class, TabPath as link, IsVisible as show_condition, ParentId as parent FROM dnn_SMA_Tabs WHERE PortalID = 3 AND IsVisible = 'True' ORDER BY TabOrder ASC";
$result = mysql_query($sql);
$index = 1;
while($row = mysql_fetch_assoc($result)) {
$row['parent'] = intval($row['parent']);
$menu[$index] = $row;
$index++;
}
You'll need to convert show_condition to the appropriate type - how to do that probably depends on what column type IsVisible is.
i see your array has indexes from [0] to [399]
Array (
[0] => Array (
[text] => Home
[class] => 875
[link] => //Home
[show_condition] => TRUE
[parent] => 0
)
[1] => Array (
[text] => About
[class] => 326
[link] => //About
[show_condition] => TRUE
[parent] => 0
)
etc
etc
etc
[339] => Array (
[text] => Planner
[class] => 921
[link] => //Planner
[show_condition] => TRUE
[parent] => 45
) )
but you try to show items from [1] to [340]
for ( $i = 1; $i <= count ( $menu ); $i++ )
count($menu) returns 340 ([0]->[399])
Solution: for ( $i = 0; $i < count ( $menu ); $i++ )
start from 0 and go until 399 (strictly < 340)
I would do it in an other way: object oriented.
class Menu {
private $children = array();
private $name = '';
private $link = '';
private $class = '';
private $show = TRUE;
function __construct($name, $class, $link, $show = TRUE, $parent = null) {
$this->name = $name;
$this->link = $link;
$this->class = $class;
$this->show = $show;
if(!is_null($parent)) {
$parent->addChild($this);
}
}
function addChild(Menu $child) {
$this->children[] = $child;
}
// ... remaining getters (and probably setters)
}
Then you can build the menu like this:
$home = new Menu('Home', '875', '//Home');
$about = new Menu('About', '326', '//About');
//...
$planner = new Menu('Planner', '921', '//Planner', true, $home);
$menu = array($home, $about,...);
This is just one example. I am aware that this would mean you create 340 variables to hold your menu. With other setter and getter methods you can do it better, this is just a fast 'sketch'.
You can build the menu like this:
function build_menu ( $menu, $showContainer = false) {
$out = '';
if($showContainer) {
$out = '<div class="container4">' . "\n";
$out .= ' <div class="menu4">' . "\n";
}
if(!empty($menu)) {
$out .= '<ul>' . "\n";
for ($entry in $menu) {
if($entry->getShow()) {//are we allowed to see this menu?
$out .= '<li class="' . $entry->getClass() . '"><a href="' . $entry->getLink() . '">';
$out .= $entry->getText();
$out .= '</a>';
$out .= "\n" . build_menu($entry->getChildren());
$out .= '</li>' . "\n";
}
}
$out .= '</ul>'."\n";
}
if($showContainer) {
$out .= "\n\t" . '</div>';
$out .= "\n\t" . '</div>';
}
return $out;
}
I didn't test the code, but this is the idea behind it. If you have no experience with OOP and php have a look at the official documentation.
And also note that this requires PHP5.

Categories