1

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.

zaqfx
  • 31
  • 6
  • Are those commented `if`s supposed to be inside the others? Because you are testing if A=B. Then if it is, you test if A=C. Of course it is not. – sidyll Jan 05 '17 at 13:14
  • Well, it seems like none of these attributes will pass both of those conditions (once uncommented). Are you sure they are supposed to be nested like you have it? – segFault Jan 05 '17 at 13:14
  • your logic doesnt make sense. Maybe give us your logic in pseudocode so that we know what you are trying to accomplish – CodeGodie Jan 05 '17 at 13:45
  • The first if condition is to check 2 specific type of products then the second condition is to check the size I got: 4, 6, 8, 11, 12 ,14. Allowing only '14_anos'. – zaqfx Jan 05 '17 at 15:16
  • @sidyll well first if check A=B works, but then I need to check if C=D (attribute for sizes of the respetive product) but it isn't working – zaqfx Jan 05 '17 at 17:47

3 Answers3

1

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
}
sidyll
  • 57,726
  • 14
  • 108
  • 151
0

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;

                }

        }

  }
datascript
  • 51
  • 4
  • I can't make it working.. I need to switch to another subarray, I got differents parameters, I've to switch between [option] => s_produto to [option] => s_tamanho_produto where it check if isn't [value] => 14_anos – zaqfx Jan 05 '17 at 18:55
0

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;
                }

            }
        }
    }
}
CodeGodie
  • 12,116
  • 6
  • 37
  • 66