• Resolved ashique12009

    (@ashique12009)


    Hello, I am creating multiple shortcode with foreach, but always it returns me the last shortcode, any hints? Thanks.
    Like I 2 shorcode tag name: cld_form_id-50874d91-05c7-45e4-957c-86b360312861 and cld_form_id-50874d91-05c7-45e4-957c-86b360312862
    In a page I put the first one as [cld_form_id-50874d91-05c7-45e4-957c-86b360312861] which has 3 fields
    but it is printing two fields where 2nd form have two fields.
    Code:

    <?php 
    /**
     * The shorcode handler class
     */
    class Shortcode_Handler {
      private $field_array;
      private $form_id;
    
      function __construct() {
        add_action('init', [$this, 'cld_add_custom_shortcode']);
      }
    
      public function cld_add_custom_shortcode() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'options';
        $results = $wpdb->get_results("SELECT * FROM $table_name WHERE option_name LIKE '%cld_form_id-%'");
        foreach ($results as $value) {
          $shorcode_tag_name = $value->option_name;
          $this->form_id = $value->option_name;
          $this->field_array = maybe_unserialize($value->option_value);
          add_shortcode($shorcode_tag_name, [$this, 'cld_generate_form']);
        }
      }
    
      public function cld_generate_form() {
        // Get form fields
        $fields = $this->field_array;
        $form_id = $this->form_id;  
        $form = '<form id="'.$form_id.'" method="post">';
        foreach ($fields as $value) {
          $form .= '<input name="'.$value.'" value="" />';
        }
        $form .= '<input type="submit" name="submit">';
        $form .= '</form>';
        return $form;
      }
    }

    Any hints?
    Thanks.

    • This topic was modified 5 years, 1 month ago by ashique12009.
Viewing 3 replies - 1 through 3 (of 3 total)
  • The two shortcodes are sharing the same object of class Shortcode_Handler, it has two fields which are updated in the foreach loop in your function cld_add_custom_shortcode, hence when the shortcodes get invoked only the last set values are there.
    You need to create a new object for each shortcode and pass this distinct object into the add_shortcode function. This way the shortcode name is paired with an object that remembers the fileds for that shortcode.

    It is risky to edit your code like this, but I will try.
    Note that the variables are now public.

    <?php 
    /**
     * The shorcode handler class
     */
    class Shortcode_Handler {
      public $field_array;
      public $form_id;
    
      public function cld_generate_form() {
        // Get form fields
        $fields = $this->field_array;
        $form_id = $this->form_id;  
        $form = '<form id="'.$form_id.'" method="post">';
        foreach ($fields as $value) {
          $form .= '<input name="'.$value.'" value="" />';
        }
        $form .= '<input type="submit" name="submit">';
        $form .= '</form>';
        return $form;
      }
    }
    
    /* register the shortcodes */
    function cld_add_custom_shortcode() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'options';
        $results = $wpdb->get_results("SELECT * FROM $table_name WHERE option_name LIKE '%cld_form_id-%'");
        foreach ($results as $value) {
          $shorcode_tag_name = $value->option_name;
          $sc_object = new Shortcode_Handler;
          $sc_object->form_id = $value->option_name;
          $sc_object->field_array = maybe_unserialize($value->option_value);
          add_shortcode($shorcode_tag_name, [$sc_object, 'cld_generate_form']);
        }
     }
    
      add_action('init', 'cld_add_custom_shortcode');
    
    Thread Starter ashique12009

    (@ashique12009)

    Thanks @rossmitchell at last solved it by below way:

    class Shortcode_Handler {
    
      function __construct() {
        add_action('init', [$this, 'cld_add_custom_shortcode']);
      }
    
      public function cld_add_custom_shortcode() {
        global $wpdb;
    
        $table_name = $wpdb->prefix . 'options';
        $results = $wpdb->get_results("SELECT * FROM $table_name WHERE option_name LIKE '%cld_form_id-%'");
    
        foreach ($results as $value) {
          $form_id = $value->option_name;
          $field_array = maybe_unserialize($value->option_value);
          $this->cld_gen_form($form_id, $field_array);
        }
      }
    
      public function cld_gen_form($form_id, $field_array) {
        add_shortcode($form_id, function () use ($form_id, $field_array) {
          $form = '<form id="' . $form_id . '" method="post">';
          foreach ($field_array as $val) {
            $form .= '<input name="' . $val . '" value="" />';
          }
          $form .= '<input type="submit" name="submit">';
          $form .= '</form>';
          return $form;
        });
      }
    }

    Very tidy.
    If you have resolved your issue, could you mark this thread as resolved.

Viewing 3 replies - 1 through 3 (of 3 total)

The topic ‘Multiple shortcode is not working in foreach’ is closed to new replies.