Merge two arrays and selected checkbox in PHP - php

First Array Output:
print_r($categories);
Array
(
[1] => Accounting & Financial
[2] => Advertising Services
[3] => Awards & Incentives
[4] => Business Consultants
[5] => Career Services
[6] => Creative Services
[7] => Data Management
[8] => Distributors & Agents
)
Second array Output:
print_r($Service_Provider_Id['Category']);
Array
(
[0] => Array
(
[id] => 1
[category] => Accounting & Financial
)
[1] => Array
(
[id] => 2
[category] => Advertising Services
)
)
My Below code showing all checkbox base on first array
<?phpforeach ($categories as $key => $value) { ?>
<div class="checkboxes-div">
<input type="checkbox" id="CategoryCategory<?php echo $key; ?>" value="<?php echo $key?>" name="data[Category][Category][]">
<label class="selected" for="CategoryCategory<?php echo $key; ?>">
<?php echo $value; ?>
</label>
</div>
<?php } ?>
if second array category's key value match with first array value so i want to selected checkbox

since in_array() will not work in multidimensional array you have to use two foreach loop. so try this
<?php
$categories=Array
(
"1" => "Accounting & Financial",
"2" => "Advertising Services",
"3" => "Awards & Incentives",
"4" => "Business Consultants",
"5" => "Career Services",
"6" => "Creative Services",
"7" => "Data Management",
"8" => "Distributors & Agents"
) ;
$Service_Provider_Id['Category'] = Array
(
"0" => Array
(
"id" => "1" ,
"category" => "Accounting & Financial"
),
"1" => Array
(
"id" => "2",
"category" => "Advertising Services"
)
);
?>
<?php foreach ($categories as $key => $value) { ?>
<div class="checkboxes-div">
<input type="checkbox" id="CategoryCategory<?php echo $key; ?>" value="<?php echo $key?>" name="data[Category][Category][]"
<?php foreach ($Service_Provider_Id['Category'] as $keys => $values) { foreach ($values as $keys2 => $values2) { if(in_array($value,$Service_Provider_Id['Category'][$keys])) { ?> checked <?php } } } ?> >
<label class="selected" for="CategoryCategory<?php echo $value; ?>">
<?php echo $value; ?>
</label>
</div>
<?php } ?>

thing is you want to search an element in a multi dimensional array, so you must use a function for this. Try the code below
function ArraySearchRecursive($Needle, $Haystack, $NeedleKey = "", $Strict = false, $Path = array()) {
if (!is_array($Haystack))
return false;
foreach ($Haystack as $Key => $Val) {
if (is_array($Val) &&
$SubPath = ArraySearchRecursive($Needle, $Val, $NeedleKey, $Strict, $Path)) {
$Path = array_merge($Path, Array($Key), $SubPath);
return $Path;
} elseif ((!$Strict && $Val == $Needle &&
$Key == (strlen($NeedleKey) > 0 ? $NeedleKey : $Key)) ||
($Strict && $Val === $Needle &&
$Key == (strlen($NeedleKey) > 0 ? $NeedleKey : $Key))) {
$Path[] = $Key;
return $Path;
}
}
return false;
}
and then
<?php foreach ($categories as $key => $value) { ?>
<div class="checkboxes-div">
<input type="checkbox" id="CategoryCategory<?php echo $key; ?>" value="<?php echo $key; ?>" <?php if (ArraySearchRecursive($value, $Service_Provider_Id['Category'])) { ?> checked <?php } ?> name="data[Category][Category][]">
<label class="selected" for="CategoryCategory<?php echo $key; ?>">
<?php echo $value; ?>
</label>
</div>
<?php } ?>
This works. I personally tried it.

Related

Parsing multidimensional php array recursively, make a change and return a result

I would like to parse an array, get some informations and return a new array but recursively I don't know how do this.
Here an example of array:
$arr= array (
0 => array (
'id'=> 0,
'dir_name' => '',
'children' => array (
36 => array (
'id'=>36,
'dir_name' => 'dir 36',
'children' => array (
92 => array (
'id'=>92,
'dir_name' => 'dir 92',
'children' => array (
93 => array (
'id'=>93,
'dir_name' => 'dir 93', ), ), ),
94 => array (
'id'=>94,
'dir_name' => 'dir 94',
'children' => array (
95 => array (
'id'=>95,
'dir_name' => 'dir 95', ), ), ), ), ), ), ), );
Here my function:
function all_dir($array,$id_selected=0,$pos=0,$tab_pos=[])
{
$flat= [];
foreach($array as $k=>$value)
{
if (is_array($value))
$flat = array_merge($flat, all_dir($value, $id_selected,$pos,$tab_pos));
else
{
if($k=="id")
{
$option='<option value="'.$value.'"';
if($value==$id_selected)
$option .=" selected ";
}
if($k=="dir_name")
{
$flat[] = $value;
$tab_pos[$pos]=$value;
$val='';
for($i=0; $i<=$pos; $i++)
{
$val .= $tab_pos[$i].'/';
}
$option .='>'.$val.'</option>';
echo $option;
$pos++;
}
}
}
return $flat;
}
A sample html code:
<html>
<body>
<select name="" id="">
<?php
all_dir($arr, 93);
?>
</select>
</body>
</html>
What I get:
<select id="" name="">
<option value="0">/</option>
<option value="36">/dir 36/</option>
<option value="92">/dir 36/dir 92/</option>
<option selected="" value="93">/dir 36/dir 92/dir 93/</option>
<option value="94">/dir 36/dir 94/</option>
<option value="95">/dir 36/dir 94/dir 95/</option>
</select>
What I want:
all_dir() returns an array like (and don't display some options html code):
[
"0" =>"/",
"36" =>"/dir 36/",
"92" =>"/dir 36/dir 92/",
"93" =>"/dir 36/dir 92/dir 93/",
"94" =>"/dir 36/dir 94/",
"95" =>"/dir 36/dir 94/dir 95/",
]
You want to transform one array structure to another. It can be done i many ways.
I decided to split your function in two, first one get_dir recursively travels through array and grabs important data (id and dir_name), and second get_dir_root that transforms that immediate format to format you expect.
Also i removed $id_selected, $pos, $tab_pos arguments, since you don't use it in new version.
function get_dir($array, $names = [])
{
$ret = [];
foreach ($array as $k => $v)
{
$id = $v['id'];
$name = $v['dir_name'];
$ret[$id] = $names;
$ret[$id][] = $name;
if (!empty($v['children']))
{
$xret = get_dir($v['children'], $ret[$id]);
foreach ($xret as $kk => $vv)
{
$ret[$kk] = $vv;
}
}
}
return $ret;
}
function get_dir_root($array)
{
$ret = [];
foreach (get_dir($array) as $k => $v)
{
$ret[$k] = implode ('/', $v);
if ($ret[$k] == '')
$ret[$k] = '/';
else
$ret[$k] .= '/';
}
return $ret;
}
Working example

How To Get Data from JSON Into Unordered List?

I have a JSON file that contain this:
"Menus": [{
"MenuId": "1",
"MenuName": "Perencanaan dan Pengadaan",
"MenuParent": "",
"MenuLink": ""
}, {
"MenuId": "1-1",
"MenuName": "RKA / DPA",
"MenuParent": "1",
"MenuLink": ""
}, {
"MenuId": "1-1-1",
"MenuName": "Daftar RKA / DPA",
"MenuParent": "1-1",
"MenuLink": "rkbu"
},
I want to put that data into unordered list dynamically. So the output I want is like this (with 3 level list):
Perencanaan dan Pengadaan
RKA / DPA
Daftar RKA / DPA
I have tried this code:
echo "<ul>";
foreach($get_data['Menus'] as $node){
if(strlen($node['MenuId']) == 1){
echo "<li>" . $node['MenuName'];
echo "</li>";
}
echo "<ul>";
if(strlen($node['MenuId']) == 3){
echo "<li>".$node['MenuName']."</li>";
}
if(strlen($node['MenuId']) == 5){
echo "<ul>";
echo "<li>".$node['MenuName']."</li>";
echo "</ul>";
}
echo "</ul>";
}
echo "</ul>";
But I find that it is not dynamic because it depends on string length. I've read that the best method is using recursive method. But I cannot find the recursive pattern of my JSON file. Can anybody help me find the solution? Thanks
I don't think it is possible to make recursive calls directly on your flat JSON data.
I suggest you first convert your flat data to a multidimensional array and afterwards recursively generate your menu.
I took parts of the code from here: Dynamically creating/inserting into an associative array in PHP
$get_data = array(
array(
"MenuId" => "1",
"MenuName" => "Perencanaan dan Pengadaan",
"MenuParent" => "",
"MenuLink" => ""
),
array(
"MenuId" => "1-1",
"MenuName" => "RKA / DPA",
"MenuParent" => "1",
"MenuLink" => ""
),
array(
"MenuId" => "1-1-1",
"MenuName" => "Daftar RKA / DPA",
"MenuParent" => "1-1",
"MenuLink" => "rkbu"
)
);
function insert_into(&$array, array $keys, $value) {
$last = array_pop($keys);
foreach($keys as $key) {
if(!array_key_exists($key, $array) ||
array_key_exists($key, $array) && !is_array($array[$key])) {
$array[$key]['items'] = array();
}
$array = &$array[$key]['items'];
}
$array[$last]['value'] = $value;
}
function create_menu($menuItems) {
$content = '<ul>';
foreach($menuItems as $item) {
$content .= '<li>' . $item['value'];
if(isset($item['items']) && count($item['items'])) {
$content .= create_menu($item['items']);
}
$content .= '</li>';
}
$content .= '</ul>';
return $content;
}
$menuItems = array();
foreach($get_data as $item) {
$levels = explode('-', $item['MenuId']);
insert_into($menuItems, $levels, $item['MenuName']);
}
print_r($menuItems);
print create_menu($menuItems);
DEMO: http://3v4l.org/dRK4f
Output:
Array (
[1] => Array (
[value] => Perencanaan dan Pengadaan
[items] => Array (
[1] => Array (
[value] => RKA / DPA
[items] => Array (
[1] => Array (
[value] => Daftar RKA / DPA
)
)
)
)
)
)
<ul>
<li>Perencanaan dan Pengadaan
<ul>
<li>RKA / DPA
<ul>
<li>Daftar RKA / DPA</li>
</ul>
</li>
</ul>
</li>
</ul>

How can I show array in PHP?

I have this source to show array
foreach ($menu_items as $item=>$value) {
if($item != 'about-me'){
echo ''.$item.'';
}else if($item == 'about-me'){
echo 'about';
}
And this is my array:
$menu_items = array(
"disabled" => array (
"contact" => "Contact",
),
"enabled" => array (
"services" => "Services",
"process" => "Process",
"portfolio" => "My Portfolio",
"about-me" => "Abouuuuut",
"contact" => "Contact",
),
);
Now it shows me (when it is enabled):
services
process
portfolio
about
contact
I want to show:
Services
Process
My Portfolio
about
Contact
You need to do this:
foreach ($menu_items as $item=>$value) {
if($item != 'about-me'){
echo ''.$value.''; //change here
}else if($item == 'about-me'){
echo 'about';
}
}
You are using $item, use the $value instead of $item.

PHP - How to format this output using given array?

So right now i have an array named $socialMeta, containing:
Array (
[0] => Array (
[socialFacebook] => Array (
[0] => http://www.facebook.com/someUsername
)
)
[1] => Array (
[socialYoutube] => Array (
[0] => http://www.youtube.com/user/someUsername
)
)
[2] => Array (
[socialSoundcloud] => Array (
[0] => http://www.soundcloud.com/someUsername
)
)
)
From this array I need to create the following output:
<div class="social">
Add us on <span>Facebook</span>
Visit us on <span>Youtube</span>
Visit us on <span>Souncloud</span>
</div>
Please not that there are different anchor text for the first link.
For anchor classes i can use $socialMeta key to make whole process a bit easier.
<?php if (!empty($socialMeta)) { ?>
<div class="social">
<?php foreach ($socialMeta as $rows) {?>
<?php foreach ($rows as $key => $val) {?>
<?php
switch ($key) {
case "socialFacebook":
$title = "Facebook";
$class = "fb";
break;
case "socialYoutube":
$title = "Youtube";
$class = "yt";
break;
case "socialSoundcloud":
$title = "Souncloud";
$class = "sc";
break;
}
?>
Add us on <span><?php echo $title; ?></span>
<?php }?>
<?php }?>
</div>
<?php }?>
Start by identifying the network for each element in the array (I assume the name is $array in the following examples):
function add_network($array) {
static $networks = array('Facebook', 'Youtube', 'Soundcloud');
foreach($networks as $network)
if (isset($array['social' . $network])) {
$array['network'] = $network;
return $array;
}
//None found
$array['network'] = false;
return $array;
}
$array = array_map('add_network', $array);
Then transform the array (you should find a better name for this function):
function transform_array($a) {
static $classes = array('Youtube' => 'yt', 'Facebook' => 'fb', 'Soundcloud' => 'sc');
$network = $a['network'];
$class = $classes[$network];
$url = $a['social' . $network][0]
return array('network' => $network,
'url' => $url,
'class' => $class);
}
$array = array_map('transform_array', $array);
And now just loop over the elements of $array:
foreach($array as $row) {
$network = $row['network'];
$url = $row['url'];
$class = $row['class'];
if ($network === 'Facebook')
$link_text = 'Add us on <span>%s</span>';
else
$link_text = 'Visit us on <span>%s</span>'
$link_text = sprintf($link_text, $network);
printf('%s',
$url, $class, $link_text);
}
<?php
function flattenArray(array $input){
$nu = array();
foreach($input as $k => $v){
if(is_array($v) && count($v) == 1){
$nu[key($v)] = current($v);
if(is_array($nu[key($v)]) && count($v) == 1)
$nu[key($v)] = current($nu[key($v)]);
}
else
$nu[$k] = $v;
}
return $nu;
}
// here you can maintain the sortorder of the output and add more social networks with the corresponding URL-text...
$urlData = array(
'socialFacebook' => 'Add us on <span>Facebook></span>',
'socialYoutube' => 'Visit us on <span>Youtube</span>',
'socialSoundcloud' => 'Visit us on <span>Souncloud</span>',
);
$testArray = array(
array('socialFacebook' => array('http.asdfsadf')),
array('socialYoutube' => array('http.asdfsadf')),
array('socialSoundcloud' => array('http.asdfsadf'))
);
$output = flattenArray($testArray);
HERE WE GO
echo '<div class="social">';
foreach($urlData as $network => $linkText){
if(!empty($output[$network]))
echo sprintf('%s</span>', $output[$network], $linkText);
}
echo '</div>';

How do I merge same array without show it duplicate

I want to merge array which have same key to be one. Example
$options = array(
array("group" => "header","title" => "Content 1"),
array("group" => "header","title" => "Content 2"),
array("group" => "menu","title" => "Content 3"),
array("group" => "content","title" => "Content 4"),
array("group" => "content","title" => "Content 5"),
array("group" => "content","title" => "Content 6"),
array("group" => "footer","title" => "Content 7")
);
foreach ($options as $value) {
if ($value['group']) {
echo "<div class='{$value['group']}'>";
echo $value['title'];
echo "</div>";
}
}
Current output is
<div class='header'>Content 1</div><div class='header'>Content 2</div><div class='menu'>Content 3</div><div class='content'>Content 4</div><div class='content'>Content 5</div><div class='content'>Content 6</div><div class='footer'>Content 7</div>
What I want here is to be
<div class='header'>
Content 1
Content 2
</div>
<div class='menu'>
Content 3
</div>
<div class='content'>
Content 4
Content 5
Content 6
</div>
<div class='footer'>
Content 7
</div>
Let me know
$grouped = array();
foreach($options as $option) {
list($group, $title) = array_values($option);
if (!isset($grouped[$group])) {
$grouped[$group] = array();
}
$grouped[$group][] = $title;
}
foreach ($grouped as $group => $titles) {
echo sprintf('<div class="%s">%s</div>', $group, implode('', $titles));
}
$groups = array ();
foreach ( $options as $value ) {
if ( !isset ( $groups[$value['group']] ) ) {
$groups[]['group'] = $value['group']
}
$groups[$value['group']]['title'][] = $value['title'];
}
foreach ( $groups as $group ) {
echo "<div class="{$group['group']}">";
echo implode ( "\n", $group['title'] );
echo "</div>";
}
This should work, but if it doesn't matter to you, you could also just change the structure of your hardcoded-array, then you wouldn't need my first foreach.

Categories