0

I'm working with a custom PHP script that interacts with the Wordpress database and I've bumped into a small issue.

I've written a function that I would like to be able to run multiple times with different variable values sent to it each time it is run, the function is as such:

function ProductByCategory()
{
    // Globalize the Wordpress Database Variable
    GLOBAL $wpdb;
    GLOBAL $term;
    GLOBAL $default;
    // Return All Products in the Category Set by $term
    $return = $wpdb->get_results("SELECT term_id FROM wplz_terms WHERE name = '$term';");
    // Properly Format the Result for an Array
    $array = json_decode(json_encode($return),true);
    // Flatten Array to Simple Array Function
    function array_flatten_recursive($array) { 
    if (!$array) return false;
        $flat = array();
        $RII = new RecursiveIteratorIterator(new RecursiveArrayIterator($array));
        foreach ($RII as $value) $flat[] = $value;
        return $flat;
    }
    $flat = array_flatten_recursive($array);    
    // Format for Next MySQL Query
    $in = implode(',', $flat);
    // Resolve Term ID to Object ID(s) 
    $return = $wpdb->get_results("SELECT object_id FROM wplz_term_relationships WHERE term_taxonomy_id IN ($in);");
    // Properly Format the Result for an Array
    $array = json_decode(json_encode($return),true);
    // Refresh $flat Value
    $flat = array_flatten_recursive($array);
    // Format for Next MySQL Query
    $in = implode(',', $flat);  
    // Resolve Products by the Resulting Object ID(s)
    $return = $wpdb->get_results("SELECT p.id, p.post_title, pm.meta_value FROM wplz_posts p INNER JOIN wplz_postmeta pm ON pm.post_id=p.id AND pm.meta_key = '_price' WHERE p.id IN ($in) AND p.post_status = 'publish' ORDER BY p.post_title ASC;");
    // Properly Format the Result for an Array
    $array = json_decode(json_encode($return),true);
    // Set Default Select Value
    echo("<option>" . $default . "</option>");

    foreach($array as $line)
    {
        echo('<option>');
            echo($line['post_title']);
            echo(' - ' . number_format($line['meta_value']) . 'THB');
        echo('</option>');
    }

}

And then in the area of the page where I want to run the function I simply put:

<!-- Select CPU Dropdown -->
<!-- Open HTML Select Structure -->
<div class="btn-group bootstrap-select"><select class="selectpicker form-control">

    <?php
    // Set Default Value for Select Drop Down Menu(s)
    $default = "-- None Selected --";
    // Resolve CPU Products
    $term = "CPU";
    // Run ProductByCategory Function
    ProductByCategory();
    ?>

<!-- Close HTML Select Structure -->
</select></div>

For whatever reason, this function runs perfectly the first time that it is called. However whenever I try to redefine $term and $default and then call the function again with the updated variables it simply refuses to return anything. I'm rather confused because after quite a while of looking at it I'm not sure where things are going wrong, and thus I have submitted it to you fine people. Thank you for your help.

John Doe
  • 158
  • 10
  • 2
    I don't see that function returning anything at all. It just echoes some HTML? You should also learn how to pass variables to your method instead of using `global` when it isn't needed. Globals should be avoided when ever possible. – M. Eriksson Oct 02 '16 at 15:16
  • Can't you pass the arguments to your function normally instead of using global variables? – Daniel Stasiak Oct 02 '16 at 15:19
  • It seems your example calls the function only once. – Hagen von Eitzen Oct 02 '16 at 15:19
  • 2
    Regarding creating functions in functions in PHP, you should read this question: http://stackoverflow.com/questions/1631535/function-inside-a-function. Like it says, you can do it, but it won't behave as expected.. – M. Eriksson Oct 02 '16 at 15:22
  • I have to ask about this: `json_decode(json_encode($return),true)`? – M. Eriksson Oct 02 '16 at 15:24
  • For you to run the function also, you will need to make sure the database tables match your setup (I'm on shared hosting, thus the weird table names). Also I'm running WooCommerce and have some products under some categories, the variable `$term` corresponds to some of the category names. – John Doe Oct 02 '16 at 15:27
  • Daniel Stasiak - I'll give that a try. Magnus Eriksson - the return from the `$return` query has some extra information in it that is not needed in the array for the next query, so I'm using json_decode to clean up the return before pushing it into the correct array format. – John Doe Oct 02 '16 at 15:31
  • Hagen von Eitzen - In the example I only call it once, to call it again I would simply repeat the `select` HTML and PHP structure and redefine the `$default` and `$term` variables. – John Doe Oct 02 '16 at 15:33
  • Daniel Stasiak - I get the same result when using arguments instead of the global variables, but thanks for the input - really because I only need to pass two strings to the function, arguments should be used instead of `$GLOBAL`... – John Doe Oct 02 '16 at 15:42
  • Magnus Eriksson - You are absolutely right, I missed that entirely... >_< I un-nested the two functions and everything works swimmingly now. Please post your comment as an answer so that I can mark it as correct. :) – John Doe Oct 02 '16 at 15:50
  • @MagnusEriksson - OP says your comment (about nested functions) fixed his problem, and he would upvote / mark correct if you posted that as an answer. (I assume you missed this as OP didn't @ you in his comment response). – random_user_name Oct 02 '16 at 20:33
  • 1
    Added the comment as an answer. Thanks @cale_b for the heads up. :) – M. Eriksson Oct 03 '16 at 05:56

1 Answers1

3

Regarding creating functions inside other functions in PHP, you should read this SO Q&A:

Function inside a function.?

Like it says, you can do it, but it won't behave as expected. An excerpt from that answer:

(x() = outer function & y() = inner function):

Although functions are not limited in scope (which means that you can safely 'nest' function definitions), this particular example is prone to errors:

1) You can't call y() before calling x(), because function y() won't actually be defined until x() has executed once.

2) Calling x() twice will cause PHP to redeclare function y(), leading to a fatal error:

Community
  • 1
  • 1
M. Eriksson
  • 13,450
  • 4
  • 29
  • 40