I'm having a difficult to finish a if statement twice.. The rest works fine but when I try to check in another subarray it doesn't work.
EDIT:
- The first if condition is to check the type of products
- The second if condition is to check the size attributes.
- Products: sweatshirt_crianca and sweatshirtc_crianca_capuz
- Sizes: 4_anos, 6_anos, 8_anos, 11_anos, 12_anos and 14_anos
Need to disable ( $this->enabled = false; ) Those sizes except 14_anos.
This is what I get from $order->products[$i]
Array
(
[qty] => 1
[name] => .Mr Mickey T-shirt
[model] =>
[image] => blusa-mr-mrs-blusao-sweat-camisolas-portugal.png
[tax] => 20
[tax_description] => IVA 23%
[price] => 10.8333
[final_price] => 16.6666
[weight] => 0.00
[id] => 1342{18}135{17}132{19}148
[attributes] => Array
(
[0] => Array
(
[option] => s_cor_produto
[value] => branco
[option_id] => 18
[value_id] => 135
[prefix] => +
[price] => 0.0000
)
[1] => Array
(
[option] => s_produto
[value] => sweatshirt_crianca
[option_id] => 17
[value_id] => 132
[prefix] => +
[price] => 5.8333
)
[2] => Array
(
[option] => s_tamanho_produto
[value] => 8_anos
[option_id] => 19
[value_id] => 148
[prefix] => +
[price] => 0.0000
)
)
)
Array
(
[qty] => 1
[name] => Adivinha quem vai ser mama shirt
[model] =>
[image] => adivinha-quem-vai-ser-mama-tshirt-gravida.png
[tax] => 20
[tax_description] => IVA 23%
[price] => 10.8333
[final_price] => 10.8333
[weight] => 0.00
[id] => 1860{20}157{18}139{17}128{19}152
[attributes] => Array
(
[0] => Array
(
[option] => s_cor_impressao
[value] => branco
[option_id] => 20
[value_id] => 157
[prefix] => +
[price] => 0.0000
)
[1] => Array
(
[option] => s_cor_produto
[value] => azul_royal
[option_id] => 18
[value_id] => 139
[prefix] => +
[price] => 0.0000
)
[2] => Array
(
[option] => s_produto
[value] => tshirt_mulher
[option_id] => 17
[value_id] => 128
[prefix] => +
[price] => 0.0000
)
[3] => Array
(
[option] => s_tamanho_produto
[value] => M
[option_id] => 19
[value_id] => 152
[prefix] => +
[price] => 0.0000
)
)
)
Sometimes it can contains 1 or 4 subarrays. This is cod payment from osCommerce, I'm trying to exclude specific products from this method based on the attributes of it.
This works fine in the first if statement to check the [value] but the lines that are commented the syntax is correct but it's not working. This is the code I got:
for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
if ($order->products[$i]['weight'] > '0.00') {
$this->enabled = false;
}
if ( (isset($order->products[$i]['attributes'])) && (sizeof($order->products[$i]['attributes']) > 0) ) {
for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
if ( ($order->products[$i]['attributes'][$j]['option'] == 's_produto') && ($order->products[$i]['attributes'][$j]['value'] == 'sweatshirt_crianca') ) {
//if ( ($order->products[$i]['attributes'][$j]['option'] == 's_tamanho_produto') && ($order->products[$i]['attributes'][$j]['value'] == '14_anos') ) {
$this->enabled = false;
//}
}
else if ( ($order->products[$i]['attributes'][$j]['option'] == 's_produto') && ($order->products[$i]['attributes'][$j]['value'] == 'sweatshirtc_crianca_capuz') ) {
//if ( ($order->products[$i]['attributes'][$j]['option'] == 's_tamanho_produto') && ($order->products[$i]['attributes'][$j]['value'] != '14_anos') ) {
$this->enabled = false;
//}
}
}
}
}
Any solutions? Thanks.
The main problem with your code is that you want to test for different
array elements but you're doing it while iterating one by one. The code
inside the for loop will only see the current element on the
iteration. So when you nest the if statements, you're basically
testing if the current element is equal to something, and then if it
is you test if this very same element is equal to something else. This
logic will fail.
Since apparently only the option and value keys are important, I
suggest creating another array with those first. Then, you can access
all these properties at once -- and not only the current attribute
inside an iterator. For example, here is a simplified attributes array
for your last example in the question:
$attributes = [
s_cor_impressao => 'branco'
s_cor_produto => 'azul_royal'
s_produto => 'tshirt_mulher'
s_tamanho_produto => 'M'
];
To create this easily and also to simplify your code, I suggest using
the foreach ... as loop. Also, you don't need to check if the
array has items. If there are no items, simply the foreach won't be
executed at all. It is worth checking if it is set, like you did, if you
don't know in advance. But another way is to just skip directly to the
next iteration if it is not set with the continue control
structure.
foreach ($order->products as $product) {
if ($product['weight'] > 0)
$this->enabled = false;
if (!isset($product['attributes']) || !is_array($product['attributes']))
continue;
$attributes = [];
foreach ($products['attributes'] as $attr)
$attributes[ $attr['option'] ] = $attr['value'];
# [tests]
}
Now, in the tests mark above you can do your tests like:
if ($attr['s_produto'] == 'sweatshirt_crianca' &&
$attr['s_tamanho_produto'] == '14_anos') {
# do something
# $this->enabled = false;
} else if (...) {
# do something else
}
I would rewrite your loop using foreach to make it more readable and prone to less errors. Also, watch out for your comparisons (== vs. ===). Try it in this manner:
foreach ($order->products as $product) {
if ($product['weight'] > 0.00) {
$this->enabled = false;
}
if (!empty($product['attributes'])) {
foreach ($product['attributes'] as $attribute) {
if ($attribute['option'] === 's_produto') {
switch ($attribute['value']) {
case "sweatshirt_crianca" :
// .. do some code
break;
case "s_tamanho_produto" :
// .. do some code
break;
case "14_anos" :
// .. do some code
break;
case "something else" :
// .. do some code
break;
default:
break;
}
}
}
}
}
Sidyll beat me to it but I was thinking along similar lines:
// loop through each product
foreach ( $order->products as $prod )
{
if($prod['weight'] > '0.00')
{
$this->enabled = false;
}
if( isset($prod['attributes']) && is_array($prod['attributes']) )
{
$matching_product_type_found = false;
$matching_valid_size_found = false;
foreach ( $prod['attributes'] as $attr )
{
if ( $attr['option'] == 's_produto' &&
( $attr['value'] == 'sweatshirt_crianca' ||
$attr['value'] == 'sweatshirtc_crianca_capuz'
) )
{
$matching_product_type_found = true;
}
if ( $attr['option'] == 's_tamanho_produto' && $attr['value'] == '14_anos' )
{
$matching_valid_size_found = true;
}
}
if( $matching_product_type_found == true )
{
$this->enabled = $matching_valid_size_found;
}
}
}
Related
I'm just a beginner and would like to select a value of an array inside an object. I'm quite lost and don't know how to do.
ie : how to get de value of "thailande" inside this object ?
Forminator_Form_Entry_Model Object
(
[entry_id] => 42
[entry_type] => custom-forms
[form_id] => 24342
[is_spam] => 0
[date_created_sql] => 2020-07-02 11:42:21
[date_created] => 2 Juil 2020
[time_created] => 2 Juil 2020 # 11:42
[meta_data] => Array
(
[select-1] => Array
(
[id] => 87
[value] => thailande
)
[radio-1] => Array
(
[id] => 88
[value] => 1
)
[number-1] => Array
(
[id] => 89
[value] => 10
)
[_forminator_user_ip] => Array
(
[id] => 90
[value] => 84.101.156.169
)
)
[table_name:protected] => politis_5_frmt_form_entry
[table_meta_name:protected] => politis_5_frmt_form_entry_meta
)
thx a lot for your help.
It's fairly straightforward - you just go down the hierarchy one step at a time referencing the index you need.
So, assuming $obj in this example is an instance of Forminator_Form_Entry_Model then you would write
$obj->meta_data["select-1"]["value"]
which will point to the data you're looking for.
N.B. The ->index syntax is used to get properties of an object. the ["index"] syntax is used to get properties of an array.
You can try Callback Functions
function array_search_id($val_for_search, $array_data, $search_in_path='root') {
if(is_array($array_data) && count($array_data) > 0) { // if value has child
foreach($array_data as $key => $value) {
$paths_list = $search_in_path;
// Adding current key to search path
array_push($paths_list, $key);
if(is_array($value) && count($value) > 0) { // if value has child
$res = array_search_id($val_for_search, $value, $paths_list);//callback function
if ($res != null)
return $res;
}
else if($value == $val_for_search){
//if you wants path + result
return end($paths_list);
/*
//if you wants path
return join(" --> ", $paths_list);
*/
} //if value find in array return val
}
}
return null;
}
array_search_id('thailande', $your_array);
I have faced a problem during get unique value in foreach loop.
Following is my array.
Array
(
[20] => Array
(
[0] => Array
(
[id] => 4
[category_title] => Specialist Range
[parent] => 20
[front_active] => 1
[category_date] => 2019-05-21 04:04:17
)
[1] => Array
(
[id] => 4
[category_title] => Specialist Range
[parent] => 20
[front_active] => 1
[category_date] => 2019-05-21 04:04:17
)
[2] => Array
(
[id] => 4
[category_title] => Specialist Range
[parent] => 20
[front_active] => 1
[category_date] => 2019-05-21 04:04:17
)
[3] => Array
(
[id] => 6
[category_title] => Cater Foil Rolls
[parent] => 20
[front_active] => 1
[category_date] => 2019-05-21 04:04:24
)
)
[21] => Array
(
[8] => Array
(
[id] => 24
[category_title] => Specialist Range
[parent] => 21
[front_active] => 1
[category_date] => 2019-05-21 04:07:59
)
[9] => Array
(
[id] => 24
[category_title] => Specialist Range
[parent] => 21
[front_active] => 1
[category_date] => 2019-05-21 04:07:59
)
)
)
I written following script for getting unique value in loop
$catArray = array();
foreach($catagory_list as $key=>$catagory){
$catArray[$catagory['parent']][$key] = $catagory;
}
ksort($catArray, SORT_NUMERIC);
foreach ($catArray as $key => $value) {
if($key == 20 ){
$catName ='local';
}elseif ($key == 21) {
$catName ='interstate';
}elseif ($key == 22) {
$catName ='wholesale';
}elseif ($key == 23) {
$catName ='tst';
}
//echo $key;
foreach(array_unique($value) as $keys => $valuess){
echo $valuess['category_title'];
?>
<tr class="table_header">
<th><?php echo $catName." - ".$valuess['category_title'];?> </th>
</tr>
<?php
}
}
Problem is 20 has 4 category_title but when i used array_unique Cater Foil Rolls category title of first parent array is not display.
Output only display
Specialist Range not showing (Cater Foil Rolls)
If you are trying to find unique records in this nested array, then I would key your associative array off of the value of "id". If you are only trying to find unique category_title, then I would key off the value of "category_title". In any case I would use the associate array functionality to ensure uniqueness on whatever key you choose. Then you can apply sorting, etc. on the result.
// find first unique records
$result = [];
foreach($parents as $key1=>$child1) {
foreach($child1 as $key2=>$child2) {
if(!isset($result[$child2['id']])) {
$result[$child2['id']] = $child2;
}
}
}
// result = # => record
OR:
// find first unique categories
$result = [];
foreach($parents as $key1=>$child1) {
foreach($child1 as $key2=>$child2) {
if(!isset($result[$child2['category_title']])) {
$result[$child2['category_title']] = $child2;
}
}
}
// result = category => record
I'm not convinced that array_unique works on multi-dimensional arrays.
See this question.
I am fairly new to working with arrays and I am stuck on being able to delete an entry.
If I have:
$del_itemid = 58;
$del_modiifier = 1;
How do I search through my array $orders and unset the array containing these variables ?
$orders = Array
(
[0] => Array
(
[itemid] => 67
[modifier] => 1
[quantity] => 1
[unit_price] => 17.00
[categoryid] => 2
)
[1] => Array
(
[itemid] => 58
[modifier] => 1
[quantity] => 1
[unit_price] => 18.00
[categoryid] => 5
)
[2] => Array
(
[itemid] => 72
[modifier] => 1
[quantity] => 1
[unit_price] => 10.00
[categoryid] => 3
)
)
EDIT:
This is what I have been trying:
$i = 0;
foreach($orders as $key => $value) {
$itemid = $value['itemid'];
$modifier = $value['modifier'];
if ($itemid == $del_itemid && $modifier == $del_modifier) {
unset($_SESSION['cart'][$i]);
break;
}
$i++;
}
Since you want to check 2 values, I would use array_filter() to loop through the array and filter all subArrays out, where both values are equal to your search values, e.g.
$newArray = array_filter($orders, function($v)use($del_itemid, $del_modiifier){
if($v["itemid"] == $del_itemid && $v["modifier"] == $del_modiifier)
return FALSE;
return TRUE;
});
I found a solution based on what I was originally trying to achieve with the loop. If I use array_splice() instead of unset() it will reset the index so that it remains possible to loop through the array without there being holes in the index:
$i = 0;
foreach($orders as $key => $value) {
$itemid = $value['itemid'];
$modifier = $value['modifier'];
if ($itemid == $del_itemid && $modifier == $del_modifier) {
array_splice($orders, $i,1);
}
$i++;
}
I have a recursive function like below.
public function findnodeintree($cats,$cat_id)
{
foreach($cats as $node)
{
if((int)$node['id'] == $cat_id)
{
echo "finded";
$finded = $node;
break;
}
else
{
if(is_array($node) && array_key_exists('children', $node)){
$this->findnodeintree($node['children'],$cat_id);
}
}
}
return $finded;
}
For Example
$node =$this->findnodeintree($category_Array, 169);
It gaves me
"founded"
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: finded
Array Structure is like
[0] => Array
(
[id] => 0
[name] => MAIN CATEGORY
[depth] => 0
[lft] => 1
[rgt] => 296
[children] => Array
(
[0] => Array
(
[id] => 167
[name] => CAT 0
[depth] => 1
[lft] => 2
[rgt] => 17
[children] => Array
(
[0] => Array
(
[id] => 169
[name] => CAT 1
[depth] => 2
[lft] => 3
[rgt] => 4
)
[1] => Array
(
[id] => 170
[name] => CAT 2
[depth] => 2
[lft] => 5
[rgt] => 10
[children] => Array
(
[0] => Array
(
[id] => 171
[name] => CAT 5
[depth] => 3
[lft] => 6
[rgt] => 7
)
[1] => Array
(
[id] => 172
[name] => CAT 3
[depth] => 3
[lft] => 8
[rgt] => 9
)
)
)
To get the right value from recursion, your recursion call must not discard the return value. And since you want to walk back up the recursion tree as soon as you get a hit, and actually return the matching node, you have to break your loop at that point too.
Otherwise subsequent recursion calls overwrite your variable and the wrong node, false, or null is returned.
This should be what works:
public function findnodeintree($cats,$cat_id)
{
foreach($cats as $node)
{
if((int)$node['id'] == $cat_id){
return $node;
}
elseif(array_key_exists('children', $node)) {
$r = $this->findnodeintree($node['children'], $cat_id);
if($r !== null){
return $r;
}
}
}
return null;
}
Note: I removed the is_array because at that point $node has to be an array or throw an error at the first branch condition.
Change your recursion line to this:
$finded = $this->findnodeintree($node['children'],$cat_id);
You want to be able to get the line, if you recall the function, that line have to fill your variable, otherwise it will be filled in the last occuring situation but will never return the result to your first call.
Hence, $finded will be empty or non-existing in your first call.
The recursive call findnodeintree will go through certain loops will not "find" anything and yet they still return a variable $finded. Except that since in their loop it was never found, that variable is indeed not declared. Try this:
public function findnodeintree($cats,$cat_id)
{
$finded = NULL;
foreach($cats as $node)
{
if((int)$node['id'] == $cat_id)
{
echo "finded";
$finded = $node;
break;
}
else
{
if(is_array($node) && array_key_exists('children', $node)){
$this->findnodeintree($node['children'],$cat_id);
}
}
}
return $finded;
}
I have a codeigniter shopping cart going and its "cart" array is the following:
Array (
[a87ff679a2f3e71d9181a67b7542122c] => Array
(
[rowid] => a87ff679a2f3e71d9181a67b7542122c
[id] => 4
[qty] => 1
[price] => 12.95
[name] => Maroon Choir Stole
[image] => 2353463627maroon_3.jpg
[custprod] => 0
[subtotal] => 12.95
)
[8f14e45fceea167a5a36dedd4bea2543] => Array
(
[rowid] => 8f14e45fceea167a5a36dedd4bea2543
[id] => 7
[qty] => 1
[price] => 12.95
[name] => Shiny Red Choir Stole
[image] => 2899638984red_vstole_1.jpg
[custprod] => 0
[subtotal] => 12.95
)
[eccbc87e4b5ce2fe28308fd9f2a7baf3] => Array
(
[rowid] => eccbc87e4b5ce2fe28308fd9f2a7baf3
[id] => 3
[qty] => 1
[price] => 14.95
[name] => Royal Blue Choir Stole
[image] => 1270984005royal_vstole.jpg
[custprod] => 1
[subtotal] => 14.95
)
)
My goal is to loop through this multidimensional array some how and if ANY product with the key value pair "custprod == 1" exists, then my checkout page will display one thing, and if no custom products are in the cart it displays another thing. Any help is appreciated. Thanks.
Rather than looping over it, you can check for the custprod key using array_key_exists. Or simply check to see if arr['custprod'] isset (both functions handle null differently).
$key = "custprod";
$arr = Array(
"custprod" => 1,
"someprop" => 23
);
if (array_key_exists($key, $arr) && 1 == $arr[$key]) {
// 'custprod' exists and is 1
}
function item_exists($cart, $custprod) {
foreach($cart as $item) {
if(array_key_exists("custprod", $item) && $item["custprod"] == $custprod) {
return true;
}
}
return false;
}
Now, you can use this function to check if product exist in stack:
if(item_exists($cart, 1)) {
// true
} else {
// false
}
You still need to loop the array to check it:
$cust_prod_found = false;
foreach($this->cart->contents() as $item){
if (array_key_exists("custprod", $item) && 1 == $item["custprod"]) {
$cust_prod_found = true; break;
}
}
if ($cust_prod_found) {
// display one thing
} else {
// display another thing
}