Get multiple values of an Array inside PHP function - php

This is my code:
function menu_MORE (Array $ITEMS){
foreach ($ITEMS as $ITEM) {
echo "<li><i class='$ITEM[icon]'></i>$ITEM[link]</li>";
}
$ITEMS = array('link' => array('Edit','Remove'),
'icon' => array('fa fa-pencil','fa fa-trash'), );
menu_MORE($ITEMS);
I want the output to be:
<li><i class="fa fa-pencil"></i>Edit</li>
<li><i class="fa fa-trash"></i>Remove</li>
I think i need a second rule/parameter but I can't figured it out how.
Thank you in advance!

Your array is er... "inverted" -- you're doing this, where each key has multiple values:
$ITEMS = array(
'link' => array('Edit','Remove'),
'icon' => array('fa fa-pencil','fa fa-trash')
);
You want to do this, where you have multiple entries of items, each with a single value:
$ITEMS = array(
array(
'link' => 'Edit',
'icon' => 'fa fa-pencil',
),
array(
'link' => 'Remove',
'icon' => 'fa fa-trash',
),
);

Related

How to get category list in select box option

I want to add options in my control like key => value pair array of all available options
Like this:
$this->add_control('show_elements', [
'label' => __('Show Elements', 'your-plugin'),
'type' => Controls_Manager::SELECT2,
'options' => [
'title' => __('Title', 'your-plugin'),
'description' => __('Description', 'your-plugin'),
'button' => __('Button', 'your-plugin'),
],
'multiple' => true,
]
);
But in place of title description and button I want to have all the categories of my post so I write a function my_cat
function my_cat() {
$categories = get_categories();
echo '[';
foreach ($categories as $category) :
echo $category->term_id . '=>' . $category->name . ',';
endforeach;
echo ']';
}
And I use it for options
$this->add_control('show_elements', [
'label' => __('Show Elements', 'your-plugin'),
'type' => Controls_Manager::SELECT2,
'options' => my_cat(),
'multiple' => true,
]
);
But I'm not getting option with category list, is there anything wrong with my_cat function ?
Try by replacing you my_cat() with this:
function my_cat() {
$categories = get_categories();
$cat_array = [];
foreach ($categories as $category) :
$cat_array[$category->term_id] = $category->name;
endforeach;
return $cat_array;
}
To do this correctly, in opinion, we want choices to take associative array in this form:
$this->add_control('show_elements', [
'label' => __('Show Elements', 'your-plugin'),
'type' => Controls_Manager::SELECT2,
'choices' => my_cat(), //<-- Check this line.
'multiple' => true,
]
);
Reference: add control
Hope this helps!

Dynamically create jQuery Tabs Markup from PHP Array

What I am trying to achieve is create a jQuery Tabs markup from PHP Array. Basic intention is to add tabs and content dynamically. Both existing StackExchange answers and Google Search left me empty handed here. Finding it pretty dificult with my level of PHP knowledge.
Here are one of the many code that I have tried:
My Array:
$args = array();
$args[] = array(
'name' => 'Shortcode Name',
'tabname' => 'Shortcode Tab Name', //Same As Tab 4
'action' => 'shortcodeaction',
'icon' => 'codeicon',
'image' => 'codeimage',
);
$args[] = array(
'name' => 'Shortcode2 Name',
'tabname' => 'Shortcode2 Tab Name',
'action' => 'shortcodeaction2',
'icon' => 'codeicon2',
'image' => 'codeimage2',
);
$args[] = array(
'name' => 'Shortcode3 Name',
'tabname' => 'Shortcode3 Tab Name',
'action' => 'shortcodeaction3',
'icon' => 'codeicon3',
'image' => 'codeimage3',
);
$args[] = array(
'name' => 'Shortcode4 Name',
'tabname' => 'Shortcode Tab Name', //Same As Tab 1
'action' => 'shortcodeaction4',
'icon' => 'codeicon4',
'image' => 'codeimage4',
);
$args[] = array(
'name' => 'Shortcode5 Name',
'tabname' => 'Shortcode5 Tab Name',
'action' => 'shortcodeaction5',
'icon' => 'codeicon5',
'image' => 'codeimage5',
);
The PHP Code:
echo '<ul>';
foreach ( $args as $arg ) {
echo '<li>'.$arg['tabname'].'</li>';
}
echo </ul>
foreach ( $args as $arg ) {
echo '<div id="' . preg_replace("/[^a-z0-9]+/", "", $arg['tabname'] ) . '"></div>';
}
The tabname key value for Tab 1 and Tab 4 are same, so they should go under same tab name and tab content. This is exactly where I am getting lost. I know I can do a foreach loop to create tabs, but those two are not going under same tab instead they are creating new tab with same name.
Used this to get the count for array with unique value for tabname:
$lists = wp_list_pluck( $args, 'tabname' );
$counts = count( array_unique( $lists ));
// 4
Now a foreach loop will create 3 tabs, but not sure how to pass the $args inside the loops.
I am not asking you to do this for me, but a little head start would be great.
Thanks

Php recursive array counting

I'm trying to write a function which counts array elements recursively.
But result is false.
What could it be problem?
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
function count_r($array, $i = 0){
foreach($array as $k){
if(is_array($k)){ $i += count_r($k, count($k)); }
else{ $i++; }
}
return $i;
}
echo count_r($schema);
This is the second result on Google so I'm adding this as a reference. There is already a built-in function in PHP that you can use: count().
You can use it like this:
count($schema, COUNT_RECURSIVE);
This function can also detect recursion to avoid infinite loops so it's safer than solutions in other answers.
PHP has a built-in method for this purpose, called count(). If passed without any additional parameters, count() returns the number of array keys on the first level. But, if you pass a second parameter to the count method count( $schema, true ), then the result will be the total number of keys in the multi-dimensional array. The response marked as correct only iterates first and second level arrays, if you have a third child in that array, it will not return the correct answer.
This could be written as a recursive function, if you really want to write your own count() method, though.
Transferred from comment below answer:
Basically, as you're adding the count_r of that array to the current level, you don't need to factor in the count in the second argument - you'd basically be adding it twice. You need the "1" in there, however, to count the array itself. If you'd want to count just the elements and not the arrays, you would just make the "1" a "0".
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
function count_r($array, $i = 0){
foreach($array as $k){
if(is_array($k)){ $i += count_r($k, 1); }
else{ $i++; }
}
return $i;
}
echo count_r($schema);
This is tested and works correctly.
your function could be simple as
function count_r($array, $i = 0){
foreach($array as $k){
$i++;
if(is_array($k)){
$i += count_r($k);
}
}
return $i;
}
I have altered you code.. Please check it. It is working fine.
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
function count_r($array){
foreach($array as $k){
if(is_array($k)){
$i += count_r($k);
}
else{
$i++;
}
}
return $i;
}
echo count_r($schema);
If you want to count specific keys/values you can use the built-in array_walk_recursive with a closure function.
$schema = array(
'div' => array(
'class' => 'lines',
'div' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Soap'
),
'layer' => array(
'span' => array(
'key' => 'Product Name'
),
'val' => 'Ball'
)
)
);
$elements = 0;
array_walk_recursive($schema, function($value, $key) use (&$elements) {
if (strstr($value, 'Product')) $elements++;
});
print $elements; // 2
/*
Values
lines
Product Name
Soap
Product Name
Ball
Keys
class
key
val
key
val
*/
count($array, COUNT_RECURSIVE)-count($array)

How to merge php array

PHP Original array is a two-dimensional array.
I want to extract all the different value(the key name is parentMenu) to be a new two-dimensional array's key name
at the same time old array will be the new array's value
what and how should id do?
below is array example
//the menuList is get from mysql result
$menuList = array(
0=>array(
'navId' =>1,
'parentMenu' => 'HOME', //Previous Menu
'subMenu' => 'SHOW USER', //Sub Menu
'ctrl' => 'Index',
'action' => 'index'
),
1=>array(
'navId' =>2,
'parentMenu' => 'HOME',
'subMenu' => 'MODIFY PASSWORD',
'ctrl' => 'Modify',
'action' => 'index'
),
2=>array(
'navId' =>3,
'parentMenu' => 'ITEM LIST',
'subMenu' => 'CURRENT LIST',
'ctrl' => 'Current',
'action' => 'index'
),
3=> array(
'navId' =>4,
'parentMenu' =>'ITEM LIST',
'subMenu' =>'HISTORY LIST',
'ctrl' =>'History',
'action' =>'index'
)
);
//After processing the menuList
//The new MenuList what I want is like below
$newMenu = array(
/*parentMenu's value to be key*/
'HOME'=>array( array('navId' =>1,'subMenu' =>'SHOW USER' ,'ctrl' =>'Index' ,'action' =>'index'),
array('navId' =>2,'subMenu' =>'MODIFY PASSWORD','ctrl' =>'Modify' ,'action' =>'index')
),
'ITEM LIST'=>array(
array('navId' =>3,'subMenu' =>'CURRENT LIST','ctrl' =>'Current' ,'action' =>'index'),
array('navId' =>4,'subMenu' =>'HISTORY LIST','ctrl' =>'History' ,'action' =>'index')
)
);
$newMenu = array();
foreach($menuList as $item) {
$key = $item['parentMenu'];
unset($item['parentMenu']); // remove the parentMenu
if(!isset($newMenu[$key])) {
$newMenu[$key]] = array($item);
} else {
//array_push($newMenu[$key], $item);
$newMenu[$key][] = $item;
}
}
UPDATE: adjusted codes according to #Anyone's suggestion

Adding to Array where Key equals Variable

I always have trouble wrapping my head around these foreach array things, and SO has been an incredibly value resource in getting me there, so I hope you guys can help with this one.
public function progress_bar()
{
$items = array(
array(
'step-name' => 'Setup',
'url' => '/projects/new/setup/',
),
array(
'step-name' => 'Artwork',
'url' => '/projects/new/artwork/',
),
array(
'step-name' => 'Review',
'url' => '/projects/new/review/',
),
array(
'step-name' => 'Shipping',
'url' => '/projects/new/shipping-info/',
),
array(
'step-name' => 'Billing',
'url' => '/projects/new/billing/',
),
array(
'step-name' => 'Receipt',
'url' => '/projects/new/receipt/',
),
);
// Status can be active, editing, or complete.
foreach ($this->progress as $step => $status)
{
foreach ($items as $item)
{
$item['step-name'] == ucfirst($step) ? $item['status'] = $status : '';
}
}
return $items;
}
$this->progress contains an array of statuses ('setup' => 'active', 'artwork' => 'editing')
I want to add to the $items array the status of each matching item in $this->progress
$items = array(
array(
'step-name' => 'Setup',
'url' => '/projects/new/setup',
'status' => 'active',
),
etc...
);
If I understand your question correctly, the problem is that you are trying to add an array element to $items, but what you're actually doing is adding the element to a temporary variable ($item), which does not reference the original $items variable.
I'd suggest approaching it like this:
foreach ($this->progress as $step => $status)
{
// Having the $key here allows us to reference the
// original $items variable.
foreach ($items as $key => $item)
{
if ($item['step-name'] == ucfirst($step) )
{
$items[$key]['status'] = $status;
}
}
}
return $items;
Are you locked into using an array to store $items? If so, you're going to be stuck doing a nested loop ("For each element in $this->progress, check each element in $items. If match, update $items" or something like that). If you have some flexibility, I would use a hash for $items (associative array in php-speak), where the index is the step name. So $items['Setup'] would contain 'url' => ... and 'status' => ... etc. Does that make sense? Then your algorithm breaks down to "For each element in $this->progress, get the element in $items by name ($items[$step_name]) and update it's info."
I would change how you have the $items array keyed and do it like this. Stops you from having the nested loops.
public function progress_bar()
{
$items = array(
'Setup' => array(
'url' => '/projects/new/setup/',
),
'Artwork' => array(
'url' => '/projects/new/artwork/',
),
'Review' => array(
'url' => '/projects/new/review/',
),
'Shipping' => array(
'url' => '/projects/new/shipping-info/',
),
'Billing' => array(
'url' => '/projects/new/billing/',
),
'Receipt' => array(
'url' => '/projects/new/receipt/',
)
);
// Status can be active, editing, or complete.
foreach ($this->progress as $step => $status)
{
$item[ucfirst($step)]['status'] = $status;
}
return $items;
}

Categories