How to Create Menu From Array - php

i have an array from database like this. I want to put the array into a menu like this.
Setting
Menu Category
Menu Category View
Group
Group View
Deposits
Group Menu
Group Menu View
Menu
Menu View
ETC
I've been trying But so far every attempt failed
array(
(int) 0 => array(
'MenuCategory' => array(
'name' => 'Setting'
),
'Menu' => array(
'name' => 'Menu Category',
'url' => '/menu_categories/adding',
'parent_id' => null
),
'Site' => array(
'id' => (int) 1
),
'Sub' => array(
'name' => 'Menu Category View',
'url' => '/menu_categories/view'
)
),
(int) 1 => array(
'MenuCategory' => array(
'name' => 'Setting'
),
'Menu' => array(
'name' => 'Group',
'url' => '/groups/adding',
'parent_id' => null
),
'Site' => array(
'id' => (int) 1
),
'Sub' => array(
'name' => 'Group View',
'url' => '/groups/view'
)
),
(int) 2 => array(
'MenuCategory' => array(
'name' => 'Setting'
),
'Menu' => array(
'name' => 'Deposits',
'url' => '/Deposits/requestTiket',
'parent_id' => null
),
'Site' => array(
'id' => (int) 1
),
'Sub' => array(
'name' => null,
'url' => null
)
),
(int) 3 => array(
'MenuCategory' => array(
'name' => 'Setting'
),
'Menu' => array(
'name' => 'Group Menus',
'url' => '/group_menus/adding',
'parent_id' => null
),
'Site' => array(
'id' => (int) 1
),
'Sub' => array(
'name' => 'Group View',
'url' => '/group_menus/view'
)
),
(int) 4 => array(
'MenuCategory' => array(
'name' => 'Setting'
),
'Menu' => array(
'name' => 'Menu',
'url' => '/menus/adding',
'parent_id' => null
),
'Site' => array(
'id' => (int) 1
),
'Sub' => array(
'name' => 'Menu View',
'url' => '/menus/view'
)
)
);
can anyone help me ? ?

You can simply loop through it with three nested foreach() loops, like so:
$arr = // your array;
echo "<ul>";
foreach($arr as $setting => $nested) {
echo "<li>$setting<ul>";
foreach($nested as $category => $nested2) {
echo "<li>$category</li><ul>";
foreach($nested2 as $view) {
echo "<li>$view</li>";
}
echo "</ul></li>";
}
echo "</ul></li>";
}
echo "</ul>";
The only problem with this is that it might print out unnecessary (empty) <ul>s, and that the <ul>s default to different bullet types (easy to fix with CSS though).
Test it out at PHP Sandbox or at Ideone. Here is the output provided:
<ul><li>setting<ul><li>menu category</li><ul><li>menu category view</li></ul></li><li>group</li><ul><li>group view</li></ul></li><li>deposits</li><ul></ul></li><li>group menu</li><ul><li>group menu array</li></ul></li><li>menu</li><ul><li>menu view</li></ul></li></ul></li></ul>

import java.util.Scanner;
public class ARRAY123 {
static int Yaki2=0;
static String ff, ll;
static Scanner Yaki = new Scanner (System.in);
public static void main (String[]a){
//String [] Names = new Array (5);
char menuInput;
char retry;
String [] names;
names = new String [5];
names [0] = "";
names [1] = "";
names [2] = "";
names [3] = "";
names [4] = "";
do {
System.out.println("Names in the Array");
System.out.println("Choose what you want to do with the Array:");
System.out.println("[A]ADD");
System.out.println("[B]EDIT");
System.out.println("[C]DELETE");
System.out.println("[D]SORT");
System.out.println("[E]SEARCH");
menuInput = Yaki.next().charAt(0);
switch (menuInput) {
case 'a':
case 'A':
System.out.println("Add Elements to the Array");
System.out.print("Input whatever element you want to add:");
add(names);
break;
case 'b':
case 'B':
System.out.println("Edit an Element in the Array");
ll = Yaki.next();
System.out.println("Palitan mo na");
ff = Yaki.next();
wait
(ll,ff);
break;
}
System.out.println("Would you like to do more?");
retry = Yaki.next().charAt(0);
}while (retry == 'Y'|| retry == 'y');
System.out.println(names[0]);
System.out.println(names[1]);
System.out.println(names[2]);
System.out.println(names[3]);
System.out.println(names[4]);
}
private static void wait(String ll2, String ff2) {
// TODO Auto-generated method stub
}
static void add (String a[]) {
if (Yaki2 < a.length) {
a[Yaki2] = Yaki.next();
Yaki2++;}
else
System.out.println("The Elements in the Array are complete, you can no longer add more");
}
}

Related

Replace key in array, with keeping order intact

I would like to replace keys in arrays, because I will move them on two indexes up.
Problem that I am facing is that those are containing same names which will not be ok, if i want to move them up.
This is how array looks like.
$list = array(
'ind' => array(
'messagetype' => 'Alert',
'visibility' => 'Public',
'info' => array(
0 => array(
'urgency' => 'Urgent',
'params' => array(
0 => array(
'Name' => 'display',
'value' => '3; top',
),
1 => array(
'Name' => 'level',
'value' => '1; blue',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GSSD154',
),
),
),
),
1 => array(
'messagetype' => 'Information',
'visibility' => 'Private',
'info' => array(
0 => array(
'urgency' => 'Minor',
'params' => array(
0 => array(
'Name' => 'display',
'value' => '1; left',
),
1 => array(
'Name' => 'level',
'value' => '1; red',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GBECS23',
),
),
),
),
),
),
),
),
);
and this is how I would like the output to be with changing keys in Name0, Name1, which are inside params.
$list = array(
'ind' => array(
'messagetype' => 'Alert',
'visibility' => 'Public',
'info' => array(
0 => array(
'urgency' => 'Urgent',
'params' => array(
0 => array(
'Name0' => 'display',
'value0' => '3; top',
),
1 => array(
'Name1' => 'level',
'value1' => '1; blue',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GSSD154',
),
),
),
),
1 => array(
'messagetype' => 'Information',
'visibility' => 'Private',
'info' => array(
0 => array(
'urgency' => 'Minor',
'params' => array(
0 => array(
'Name0' => 'display',
'value0' => '1; left',
),
1 => array(
'Name1' => 'level',
'value1' => '1; red',
),
),
'area' => array(
'ard' => 'Bob',
'code' => array(
0 => array(
'Name' => 'Badge',
'value' => 'GBECS23',
),
),
),
),
),
),
),
),
);
I have tried with a lots of examples over this website, but could not find one to achieve this.
Code that I used from
How to replace key in multidimensional array and maintain order
function replaceKey($subject, $newKey, $oldKey) {
// if the value is not an array, then you have reached the deepest
// point of the branch, so return the value
if (!is_array($subject)) {
return $subject;
}
$newArray = array(); // empty array to hold copy of subject
foreach ($subject as $key => $value) {
// replace the key with the new key only if it is the old key
$key = ($key === $oldKey) ? $newKey : $key;
// add the value with the recursive call
$newArray[$key] = replaceKey($value, $newKey, $oldKey);
}
return $newArray;
}
$s = replaceKey($list, 'Name0', 'Name');
print "<PRE>";
print_r($s);
at the moment I get this output:
[0] => Array
(
[Name0] => display
[value] => 1; left
)
[1] => Array
(
[Name0] => level
[value] => 1; red
)
any help would be appreciated. regards
A very strange question, but why not?
The following function returns nothing (a procedure) and changes the array in-place using references but feel free to rewrite it as a "real" function (without references and with a return statement somewhere).
The idea consists to search for arrays, with numeric keys and at least 2 items, in which each item has the Name and value keys. In other words, this approach doesn't care about paths where the targets are supposed to be:
function replaceKeys(&$arr) {
foreach ($arr as &$v) {
if ( !is_array($v) )
continue;
$keys = array_keys($v);
if ( count($keys) < 2 ||
$keys !== array_flip($keys) ||
array_keys(array_merge(...$v)) !== ['Name', 'value'] ) {
replaceKeys($v);
continue;
}
foreach ($v as $k => &$item) {
$item = array_combine(["Name$k", "value$k"], $item);
}
}
}
replaceKeys($list);
print_r($list);
demo

PHP if statement inside an array

I'm trying to write the below array if a value is set. How can I do this inside of an array? I know I could use a ternary operator but i'm not sure how.
array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
if($Value === 1){
//Need to write the below when value is true
array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
),
),
}
),
You cannot intersect a definition of an array with a conditional statement. What you need to do instead is to define your array first and then do an if statement which will add to the array. It's not entirely clear at what level of your array you want to add the conditional content, so I'll show it on a simplified example:
$value = 1;
$myArray = array(
'name' => 'Joe',
'kids' => array(
'name' => 'Mary',
),
);
if ($value === 1) {
$myArray['kids']['hobbies'] = 'kite flying';
}
After this, the variable $myArray will have the following content:
array(
'name' => 'Joe',
'kids' => array(
'name' => 'Mary',
'hobbies' => 'kite flying',
),
)
Where exactly you need to put your conditional data depends on the full structure of your array, but the idea is you access the parts you want through indices.
Edit: in case you can just add the needed subarray at the end of your array, you can utilize array_push.
There is 3 variants to do this:
// Variant 1
// Anonymous function, variables from the parent scope
$Value = 1;
$arr = array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
'ifArray' => function() use ($Value) {
if ($Value == 1)
return array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
),
);
}
);
print_r($arr['ifArray']());
// Variant 2
// Anonymous function, variable assignment
$arr = array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
'ifArray' => function($Value) {
if ($Value == 1)
return array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
),
);
}
);
$Value = 1;
print_r($arr['ifArray']($Value));
// Variant 3
// Ternar operator
$Value = 1;
$arr = array(
'name' => 'extraFields',
'attributes' => array(
'name' => 'portal',
),
'ifArray' => $Value != 1 ? null : array(
'name' => 'portal',
'value'=> '',
'attributes' => array(
'id' => '1',
'value'=> 'testportal',
)
)
);
print_r($arr['ifArray']);
However, the variant that El_Vanja suggested, might be more clear than those three.

Prestashop HelpForm type switch in module

I want create a input type switch in my backend module in prestashop 1.6.
I write this and work
array(
'type' => 'switch',
'label' => $this->l('Label'),
'name' => 'PRESTASHOP_INPUT_SWITCH',
'is_bool' => true,
'desc' => $this->l('Description'),
'values' => array(
array(
'id' => 'active_on',
'value' => true,
'label' => $this->l('Enabled')
),
array(
'id' => 'active_off',
'value' => false,
'label' => $this->l('Disabled')
)
),
)
But if i try with custom value e not boolean it not work
array(
'type' => 'switch',
'label' => $this->l('Label'),
'name' => 'PRESTASHOP_INPUT_SWITCH',
'is_bool' => false,
'desc' => $this->l('Description'),
'values' => array(
array(
'id' => 'value1',
'value' => 'value1',
'label' => $this->l('value1')
),
array(
'id' => 'value2',
'value' => 'value2',
'label' => $this->l('value2')
)
),
)
In backend appear two boxes with labels value 'no'.
In HelperForm classes of prestashop there is no trace of input type switch.
The same code with type radio work, but i want a switch type.
Unfortunately, as you can see here:
PrestaShop doesn't have possibility to use custom value in "switch" field.
You don't need to change default switch values.
This is how you handle submit form:
public function getContent()
{
if (Tools::isSubmit('submitForm'))
{
$my_value = ( (int)Tools::getValue('PRESTASHOP_INPUT_SWITCH') == 1 ) ? 'value1' : 'value2';
if (Configuration::updateValue('PRESTASHOP_INPUT_SWITCH', $my_value))
$echo .= $this->displayConfirmation($this->l('Value updated.'));
}
$echo .= $this->renderForm();
return $echo;
}
You probably already have something like this:
public function renderForm()
{
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Settings'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'switch',
'label' => $this->l('Label'),
'name' => 'PRESTASHOP_INPUT_SWITCH',
'is_bool' => true,
'desc' => $this->l('Description'),
'values' => array(
array(
'id' => 'active_on',
'value' => 1,
'label' => $this->l('Value1')
),
array(
'id' => 'active_off',
'value' => 0,
'label' => $this->l('Value2')
)
),
)
),
'submit' => array(
'title' => $this->l('Save'),
)
),
);
$helper = new HelperForm();
$helper->module = $this;
$helper->show_toolbar = false;
$helper->table = $this->table;
$lang = new Language((int)Configuration::get('PS_LANG_DEFAULT'));
$helper->default_form_language = $lang->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') ? Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG') : 0;
$this->fields_form = array();
$helper->identifier = $this->identifier;
$helper->submit_action = 'submitForm';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false).'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => $this->getConfigFieldsValues(),
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id
);
return $helper->generateForm(array($fields_form));
}
and loading the values:
public function getConfigFieldsValues()
{
return array(
'PRESTASHOP_INPUT_SWITCH' => Tools::getValue('PRESTASHOP_INPUT_SWITCH', Configuration::get('PRESTASHOP_INPUT_SWITCH') == 'value1' : 1 : 0),
);
}
Unfortunately prestashop doesn't support the custom value of switch but you can handle this like:
$config = Configuration::get('oneclickcheckout');
$this->settings = Tools::unSerialize($config);
$settings = $this->settings;
if (isset($settings['Description']) && $settings['Description'] == 1) {
}

CakePHP return find('all') using 'id' as array Index

So I'm trying to return a find 'all' array using the id of a 'Product' as the index key for each Product.
Typically it returns:
array(
(int) 0 => array(
'Product' => array(
'id' => '1232',
'category_id' => '330',
'name' => 'Product #1',
)
),
(int) 1 => array(
'Product' => array(
'id' => '1245',
'category_id' => '310',
'name' => 'Product #2',
)
),
(int) 2 => array(
'Product' => array(
'id' => '1248',
'category_id' => '312',
'name' => 'Product #3',
)
)
)
Whereas ideally I'd like it to return:
array(
(int) 1232 => array(
'Product' => array(
'id' => '1232',
'category_id' => '330',
'name' => 'Product #1',
)
),
(int) 1245 => array(
'Product' => array(
'id' => '1245',
'category_id' => '310',
'name' => 'Product #2',
)
),
(int) 1248 => array(
'Product' => array(
'id' => '1248',
'category_id' => '312',
'name' => 'Product #3',
)
)
)
Is this possible? And how do I go about doing it?
I have an excel spreadsheet of records that I need to match ID's to, so currently I have it iterating each spreadsheet row and performing a 'first' find to get any results, then act upon them if they do.
It works, but the recordset has grown to over 28000 and so performing one find for each has noticeable overhead.
If I can do this simply in the 'find' operation it would be great, if not, any noticeable increase in performance would be appreciated.
You can get this result as after find all :
$result = Hash::combine($data, '{n}.Product.id', '{n}.Product');
Where $data is the result of find all.
You can have your find method extended in AppModel like this
public function find($type = 'first', $query = array()) {
switch($type) {
case 'keysid':
if($results = parent::find('all', $query)){
if(isset($results[0][$this->alias]['id'])){
return Hash::combine($results, '{n}.'.$this->alias.'.id', '{n}');
}else{
return $results;
}
}
break;
default:
return parent::find($type, $query);
break;
}
}
And afterwards you can call your find method as follows:
$this->Product->find('keysid');
Then you will have a result array as you specified. However you can also do this with one line of code if you need it once. Say $products is your array from the find('all')
if($products = $this->Product->find('all')){
$alteredProducts = Hash::combine($products, '{n}.Product.id', '{n}');
}
Have a look at the Hash utility

Convert flat array to the multi-dimensional

I have an array with tree data (by parent id). I want to convert it to multidimensional array. What is the best way to achieve that? Is there any short function for that?
Source array:
$source = array(
'0' => array(
'Menu' => array(
'id' => 45
'name' => 'Home'
'parent_id' => 1
)
)
'1' => array(
'Menu' => array(
'id' => 47
'name' => 'Get started'
'parent_id' => 1
)
)
'2' => array(
'Menu' => array(
'id' => 72
'name' => 'Attributes'
'parent_id' => 71
)
)
'3' => array(
'Menu' => array(
'id' => 73
'name' => 'Headings'
'parent_id' => 71
)
)
'4' => array(
'Menu' => array(
'id' => 75
'name' => 'Links'
'parent_id' => 71
)
)
'5' => array(
'Menu' => array(
'id' => 59
'name' => 'Images'
'parent_id' => 75
)
)
'6' => array(
'Menu' => array(
'id' => 65
'name' => 'Lists'
'parent_id' => 75
)
)
);
Some parents are missing from the source array. I would like the items with missing parent to be root. Result array:
$result = array(
'0' => array(
'Menu' => array(
'id' => 45
'name' => 'Home'
'parent_id' => 1
)
'Children' => array()
)
'1' => array(
'Menu' => array(
'id' => 47
'name' => 'Get started'
'parent_id' => 1
)
'Children' => array()
)
'2' => array(
'Menu' => array(
'id' => 72
'name' => 'Attributes'
'parent_id' => 71
)
'Children' => array()
)
'3' => array(
'Menu' => array(
'id' => 73
'name' => 'Headings'
'parent_id' => 71
)
'Children' => array()
)
'4' => array(
'Menu' => array(
'id' => 75
'name' => 'Links'
'parent_id' => 71
)
'Children' => array(
'0' => array(
'Menu' => array(
'id' => 59
'name' => 'Images'
'parent_id' => 75
)
'Children' => array()
)
'1' => array(
'Menu' => array(
'id' => 65
'name' => 'Lists'
'parent_id' => 75
)
'Children' => array()
)
)
)
);
Update: removed square brackets.
I don't think there is a built-in function in PHP that does this.
I tried the following code, and it seems to work to prepare the nested array the way you describe:
$nodes = array();
$tree = array();
foreach ($source as &$node) {
$node["Children"] = array();
$id = $node["Menu"]["id"];
$parent_id = $node["Menu"]["parent_id"];
$nodes[$id] =& $node;
if (array_key_exists($parent_id, $nodes)) {
$nodes[$parent_id]["Children"][] =& $node;
} else {
$tree[] =& $node;
}
}
var_dump($tree);
I wrote a similar algorithm in a PHP class I wrote for my presentation Hierarchical Models in SQL and PHP, but I was using objects instead of plain arrays.
I wrote this variant considering root parent_id is 0 or missing. No matter children after parents in DB ($source) or not.
$source_by_id = array();
foreach ($source as &$row){
$source_by_id[$row['id']] = &$row;
}
foreach ($source_by_id as $id => &$row){
$source_by_id[ intval($row['parent_id']) ]['children'][$id] = &$row;
}
// remove cycling itself
unset($source_by_id[0]['children'][0]);
$result = $source_by_id[0]['children'];
Result array keys are appropriate ids. Enjoy!
I was looking for an example of how to do this, with categories. This example assumes that parents will always have a parent id of '0'. The example is using ZF2.
No references, or recursion. The trick is in the output, you look for the [0] index, and for the children, you specify the parent_id as the index.
$categoryLookup = $this->getCategoryLookup($associateById=true);
if ($assignedCategories) {
$categoryHeirarchy = array();
foreach($assignedCategories as $assignedCategory) {
$child = $categoryLookup[$assignedCategory->category_id];
$parent = $categoryLookup[$child->parent_id];
$categoryHeirarchy[$child->parent_id][] = $categoryLookup[$child->category_id];
$categoryHeirarchy[$parent->parent_id][$parent->category_id] = $categoryLookup[$parent->category_id];
}
return $categoryHeirarchy;
}
<h3>Categories</h3>
<dl class="dl-horizontal">
<?php foreach($this->categoryHeirarchy[0] as $parent): ?>
<dt><?php echo $this->escapeHtml($parent->name); ?></dt>
<?php foreach($this->categoryHeirarchy[$parent->category_id] as $child): ?>
<dd><?php echo $this->escapeHtml($child->name); ?></dd>
<?php endforeach; ?>
<?php endforeach; ?>
</dl>

Categories