0

I have a plugin as a class, where I am using a shortcode attribute to populate the $outlet variable. However, despite sanitize_text_field($atts['outlet']) returning the expected string , $this->outlet = sanitize_text_field($atts['outlet']) isn't updating the value of $outlet. If I set a default value for the class's $outlet initially, it works as expected below in the example_callback(). Everything else with the plugin works as expected. It's just wp_news_shortcode() not assigning the $attr value...

In a word, I need the shortcode attribute value in the ajax_callback() function—is there something I've overlooked?

class Example _Search {
       
        private static $instance = null;

        public $outlet;

        public function __construct() {
            $this->settings = array(
                'plugin_path' => plugin_dir_path(__FILE__),
                'plugin_url' => plugin_dir_url(__FILE__),
                'plugin_base' => dirname(plugin_basename(__FILE__)),
                'plugin_base_url' => plugin_basename(__FILE__),
                'plugin_file' => __FILE__,
                'plugin_version' => '1.0.0',
            );

            $this->run_plugin();
        }

         /**
         * Singleton.
         *
         * @return self Main instance.
         */
        public static function init() {
            if (is_null(self::$instance)) {
                self::$instance = new self();
            }
            return self::$instance;
        }

        /**
         * Main plugin function.
         *
         * @since 1.0.0
         */
        public function run_plugin() {
            add_action('wp_ajax_example_callback', array($this, 'example_callback'));
            add_action('wp_ajax_nopriv_example_callback', array($this, 'example_callback'));
            add_shortcode('wp_example_search', array($this, 'wp_example_shortcode'));
        }

       

        /**
         * Example Search shortcode. Adds form to page and stores "outlet" attribute to options.
         *
         * @since 1.0.0
         * @param array $atts An associative array of attributes.
         * @return string
         */
        public function wp_example_shortcode($atts) {
            $atts = shortcode_atts(
                array(
                    'outlet' => 'google',
                ),
                $atts
            );
            $this->outlet = sanitize_text_field($atts['outlet']);

            $content = '';
            $view = $this->get_view_path('form.php');
            if (file_exists($view)) {
                ob_start();
                include $view;
                $content = ob_get_clean();
            }
            return $content;
        }

        /**
         * Get the path to view.
         *
         * @param string $view_name View name.
         * @param string|boolean $sub_dir_name The sub-directory.
         * @return string
         */
        public function get_view_path($view_name, $sub_dir_name = false) {
            $path = $rel_path = '';
            $plugin_base = 'wp-example-search';
            if (!empty($sub_dir_name)) {
                $rel_path .= "/{$sub_dir_name}";
            }
            $rel_path .= "/{$view_name}";
            $path = $this->settings['plugin_path'] . 'views' . $rel_path;
            return $path;
        }

        /**
         * Handle AJAX request.
         */
        public function example_callback() {

            $_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);

            if (isset($_POST['data'])) {
                $form_data = ($_POST['data']);
                $keyword = trim($form_data['keyword']);

                $endpoint = 'https://example.com?q=' . rawurlencode($keyword) . '&domains=' . 
                $this->outlet . '.com';
                
                ];
                $response = wp_remote_get($endpoint);
                $response_body = wp_remote_retrieve_body($response);
                $result = json_decode($response_body);
                $result_items = $result->items;

                if (is_array($result) && !is_wp_error($result)) {
                    $error_message = $result->get_error_message();
                    echo "Something went wrong: $error_message";
                }  else {
                    $content = '';
                    $view = $this->get_view_path('article.php');
                    if (file_exists($view)) {
                        ob_start();
                        include $view;
                        $content = ob_get_clean();
                    }
                    echo $content;
                }
            }

            die();

        }
    }

    Example_Search::init();

1 Answer 1

0

This isn't how PHP works. A PHP class is not persistent, so setting a property when a shortcode is output is not going to affect subsequent AJAX requests, since the class instance is recreated on each request.

If you have a shortcode that has an "outlet" property that the user can use like this:

[wp_example_search outlet="google"]

And that shortcode outputs a form that runs an AJAX request on submission, and you need the AJAX response to know what "outlet" to use, then the only way to do that is to send that information along with the AJAX request. To do this the shortcode would need to output the relevant outlet in a hidden field or attribute so that the JavaScript can retrieve it and send it along with the request.

1
  • Ah hello again! OK—I had that going at first, but I was thinking it was a little schlocky sending it to the HTML form and then back via the AJAX request. But if that’s the only way, then I’m sold! Commented Jan 5, 2021 at 5:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.