0

I have a validation loop in a class in an outdated but functional plugin that I need to keep (for now). It uses create_function twice.

        if( is_array($s) ) {

            $c = count($s);

            $a = 0;

            while( $a < $c ) {

                if( isset($s[$a]['validate_callback']) ) {

                    $this->create_function[]    = $s[$a]['id'];

                    $s[$a]['validate_callback'] = '';

                    $file= addslashes(WC_XSI_SETTINGS . 'validate-' . $s[$a]['id'] . '.php');

                    $s[$a]['validate_callback'] = create_function('$fields', 'do_action("wc_xsi_settings_validate",$fields); do_action("wc_xsi_settings_validate_' . $s[$a]['id'] . '",$fields);');

                }

                $a++;

            }

        }

There were several more instances - mainly in widget declations - that I have replaced, but this one stumped me. Is there a way to perform this validation without it? I'll be honest I haven't a notion how to start and really would appreciate a heads up.

2
  • What is $this->create_function[] pointing to in the Class? As you know, you'll have to replace the create_function a few lines down from that, too. Commented Oct 2, 2024 at 16:05
  • It's validating the settings of the plugin. However while looking at the rest of the class it seems to me it's only doing that when you either change the settings or are using it on a multi site setup. The settings have not changed in over five years and don't need changing now, so I am thinking now I'll just ignore it. We'll be replacing the plugin after Christmas anyway. Thanks for your response though. Commented Oct 2, 2024 at 20:05

1 Answer 1

1

You can replace the create_function with a closure like this:

if( is_array($s) ) {

    $c = count($s);
    $a = 0;

    while( $a < $c ) {

        if( isset($s[$a]['validate_callback']) ) {

            $this->create_function[] = $s[$a]['id'];
            $s[$a]['validate_callback'] = '';

            $file = addslashes(WC_XSI_SETTINGS . 'validate-' . $s[$a]['id'] . '.php');

            // Replace create_function with a closure
            $s[$a]['validate_callback'] = function($fields) use ($s, $a) {
                do_action("wc_xsi_settings_validate", $fields);
                do_action("wc_xsi_settings_validate_" . $s[$a]['id'], $fields);
            };
        }

        $a++;
    }
}

Explanation of Changes: Anonymous Function (Closure):

  • The create_function() has been replaced by an anonymous function (function($fields) use ($s, $a)), which is a much safer and modern way to define inline functions in PHP. use ($s, $a):

  • The use keyword is necessary to bring variables from the outer scope ($s and $a) into the closure, as they are required inside the anonymous function for the callbacks. No More String-based Code:

  • The anonymous function avoids the need for string-based function creation, making the code easier to read, maintain, and much safer from potential injection vulnerabilities.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh my goodness, thank you so much. That works perfectly! I also now understand how thanks to your clear explanation. Sorry for taking so long to get back, I had given up!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.