/**
  *    parse_post_content_on_save
  *
  *    any time a post is saved, we need to check for any EE shortcodes that may be embedded in the content,
  *    and then track what posts those shortcodes are on, so that we can initialize shortcodes well before the_content() runs.
  *    this allows us to do things like enqueue scripts for shortcodes ONLY on the pages the shortcodes are actually used on
  *
  * @access    public
  * @param $post_ID
  * @param $post
  * @return    void
  */
 public static function parse_post_content_on_save($post_ID, $post)
 {
     // default post types
     $post_types = array('post' => 0, 'page' => 1);
     // add CPTs
     $CPTs = EE_Register_CPTs::get_CPTs();
     $post_types = array_merge($post_types, $CPTs);
     // for default or CPT posts...
     if (isset($post_types[$post->post_type])) {
         // post on frontpage ?
         $page_for_posts = EE_Config::get_page_for_posts();
         $maybe_remove_from_posts = array();
         // critical page shortcodes that we do NOT want added to the Posts page (blog)
         $critical_shortcodes = EE_Registry::instance()->CFG->core->get_critical_pages_shortcodes_array();
         // array of shortcodes indexed by post name
         EE_Registry::instance()->CFG->core->post_shortcodes = isset(EE_Registry::instance()->CFG->core->post_shortcodes) ? EE_Registry::instance()->CFG->core->post_shortcodes : array();
         // whether to proceed with update, if an entry already exists for this post, then we want to update
         $update_post_shortcodes = isset(EE_Registry::instance()->CFG->core->post_shortcodes[$post->post_name]) ? true : false;
         // empty both arrays
         EE_Registry::instance()->CFG->core->post_shortcodes[$post->post_name] = array();
         // check that posts page is already being tracked
         if (!isset(EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts])) {
             // if not, then ensure that it is properly added
             EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts] = array();
         }
         // loop thru shortcodes
         foreach (EE_Registry::instance()->shortcodes as $EES_Shortcode => $shortcode_dir) {
             // convert to UPPERCASE to get actual shortcode
             $EES_Shortcode = strtoupper($EES_Shortcode);
             // is the shortcode in the post_content ?
             if (strpos($post->post_content, $EES_Shortcode) !== FALSE) {
                 // map shortcode to post names and post IDs
                 EE_Registry::instance()->CFG->core->post_shortcodes[$post->post_name][$EES_Shortcode] = $post_ID;
                 // if the shortcode is NOT one of the critical page shortcodes like ESPRESSO_TXN_PAGE
                 if (!in_array($EES_Shortcode, $critical_shortcodes)) {
                     // add shortcode to "Posts page" tracking
                     EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts][$EES_Shortcode] = $post_ID;
                 }
                 $update_post_shortcodes = TRUE;
                 unset($maybe_remove_from_posts[$EES_Shortcode]);
             } else {
                 $maybe_remove_from_posts[$EES_Shortcode] = $post_ID;
             }
         }
         if ($update_post_shortcodes) {
             // remove shortcodes from $maybe_remove_from_posts that are still being used
             foreach (EE_Registry::instance()->CFG->core->post_shortcodes as $post_name => $shortcodes) {
                 if ($post_name == $page_for_posts) {
                     continue;
                 }
                 // compute difference between active post_shortcodes array and $maybe_remove_from_posts array
                 $maybe_remove_from_posts = array_diff_key($maybe_remove_from_posts, $shortcodes);
             }
             // now unset unused shortcodes from the $page_for_posts post_shortcodes
             foreach ($maybe_remove_from_posts as $shortcode => $post_ID) {
                 unset(EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts][$shortcode]);
             }
             EE_Registry::instance()->CFG->update_post_shortcodes($page_for_posts);
         }
     }
 }
 /**
  *    This function adds a critical page's shortcode to the post_shortcodes array
  *
  * @access private
  * @static
  * @param array $critical_page
  * @return void
  */
 private static function _track_critical_page_post_shortcodes($critical_page = array())
 {
     // check the goods
     if (!$critical_page['post'] instanceof WP_Post) {
         $msg = sprintf(__('The Event Espresso critical page shortcode for the page %s can not be tracked because it is not a WP_Post object.', 'event_espresso'), $critical_page['name']);
         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
         return;
     }
     $EE_Core_Config = EE_Registry::instance()->CFG->core;
     // map shortcode to post
     $EE_Core_Config->post_shortcodes[$critical_page['post']->post_name][$critical_page['code']] = $critical_page['post']->ID;
     // and make sure it's NOT added to the WP "Posts Page"
     // name of the WP Posts Page
     $posts_page = EE_Config::get_page_for_posts();
     if (isset($EE_Core_Config->post_shortcodes[$posts_page])) {
         unset($EE_Core_Config->post_shortcodes[$posts_page][$critical_page['code']]);
     }
     if ($posts_page !== 'posts' && isset($EE_Core_Config->post_shortcodes['posts'])) {
         unset($EE_Core_Config->post_shortcodes['posts'][$critical_page['code']]);
     }
     // update post_shortcode CFG
     if (!EE_Config::instance()->update_espresso_config(FALSE, FALSE)) {
         $msg = sprintf(__('The Event Espresso critical page shortcode for the %s page could not be configured properly.', 'event_espresso'), $critical_page['name']);
         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
     }
 }
 /**
  *    update_post_shortcodes
  *
  * @access    public
  * @param $page_for_posts
  * @return    void
  */
 public function update_post_shortcodes($page_for_posts = '')
 {
     // make sure page_for_posts is set
     $page_for_posts = !empty($page_for_posts) ? $page_for_posts : EE_Config::get_page_for_posts();
     // critical page shortcodes that we do NOT want added to the Posts page (blog)
     $critical_shortcodes = $this->core->get_critical_pages_shortcodes_array();
     // allow others to mess stuff up :D
     do_action('AHEE__EE_Config__update_post_shortcodes', $this->core->post_shortcodes, $page_for_posts);
     // verify that post_shortcodes is set
     $this->core->post_shortcodes = isset($this->core->post_shortcodes) && is_array($this->core->post_shortcodes) ? $this->core->post_shortcodes : array();
     // cycle thru post_shortcodes
     foreach ($this->core->post_shortcodes as $post_name => $shortcodes) {
         // are there any shortcodes to track ?
         if (!empty($shortcodes)) {
             // loop thru list of tracked shortcodes
             foreach ($shortcodes as $shortcode => $post_id) {
                 // if shortcode is for a critical page, BUT this is NOT the corresponding critical page for that shortcode
                 if (isset($critical_shortcodes[$post_id]) && $post_name == $page_for_posts) {
                     // then remove this shortcode, because we don't want critical page shortcodes like ESPRESSO_TXN_PAGE running on the "Posts Page" (blog)
                     unset($this->core->post_shortcodes[$post_name][$shortcode]);
                 }
                 // skip the posts page, because we want all shortcodes registered for it
                 if ($post_name == $page_for_posts) {
                     continue;
                 }
                 // make sure post still exists
                 $post = get_post($post_id);
                 if ($post) {
                     // check that the post name matches what we have saved
                     if ($post->post_name == $post_name) {
                         // if so, then break before hitting the unset below
                         continue;
                     }
                 }
                 // we don't like missing posts around here >:(
                 unset($this->core->post_shortcodes[$post_name]);
             }
         } else {
             // you got no shortcodes to keep track of !
             unset($this->core->post_shortcodes[$post_name]);
         }
     }
     //only show errors
     $this->update_espresso_config();
 }
 /**
  *    _initialize_shortcodes - calls init method on shortcodes that have been determined to be in the_content for the currently requested page
  *
  * @access    public
  * @param WP $WP
  * @return    void
  */
 public function _initialize_shortcodes(WP $WP)
 {
     do_action('AHEE__EE_Front_Controller__initialize_shortcodes__begin', $WP, $this);
     $this->Request_Handler->set_request_vars($WP);
     // grab post_name from request
     $current_post = apply_filters('FHEE__EE_Front_Controller__initialize_shortcodes__current_post_name', $this->Request_Handler->get('post_name'));
     $show_on_front = get_option('show_on_front');
     // if it's not set, then check if frontpage is blog
     if (empty($current_post)) {
         // yup.. this is the posts page, prepare to load all shortcode modules
         $current_post = 'posts';
         // unless..
         if ($show_on_front === 'page') {
             // some other page is set as the homepage
             $page_on_front = get_option('page_on_front');
             if ($page_on_front) {
                 // k now we need to find the post_name for this page
                 global $wpdb;
                 $page_on_front = $wpdb->get_var($wpdb->prepare("SELECT post_name from {$wpdb->posts} WHERE post_type='page' AND post_status='publish' AND ID=%d", $page_on_front));
                 // set the current post slug to what it actually is
                 $current_post = $page_on_front ? $page_on_front : $current_post;
             }
         }
     }
     // where are posts being displayed ?
     $page_for_posts = EE_Config::get_page_for_posts();
     // in case $current_post is hierarchical like: /parent-page/current-page
     $current_post = basename($current_post);
     // are we on a category page?
     $term_exists = is_array(term_exists($current_post, 'category')) || array_key_exists('category_name', $WP->query_vars);
     // make sure shortcodes are set
     if (isset($this->Registry->CFG->core->post_shortcodes)) {
         if (!isset($this->Registry->CFG->core->post_shortcodes[$page_for_posts])) {
             $this->Registry->CFG->core->post_shortcodes[$page_for_posts] = array();
         }
         // cycle thru all posts with shortcodes set
         foreach ($this->Registry->CFG->core->post_shortcodes as $post_name => $post_shortcodes) {
             // filter shortcodes so
             $post_shortcodes = apply_filters('FHEE__Front_Controller__initialize_shortcodes__post_shortcodes', $post_shortcodes);
             // now cycle thru shortcodes
             foreach ($post_shortcodes as $shortcode_class => $post_id) {
                 // are we on this page, or on the blog page, or an EE CPT category page ?
                 if ($current_post === $post_name || $term_exists) {
                     // maybe init the shortcode
                     $this->initialize_shortcode_if_active_on_page($shortcode_class, $current_post, $page_for_posts, $post_id, $term_exists, $WP);
                     // if this is NOT the "Posts page" and we have a valid entry
                     // for the "Posts page" in our tracked post_shortcodes array
                     // but the shortcode is not being tracked for this page
                 } else {
                     if ($post_name !== $page_for_posts && isset($this->Registry->CFG->core->post_shortcodes[$page_for_posts]) && !isset($this->Registry->CFG->core->post_shortcodes[$page_for_posts][$shortcode_class])) {
                         // then remove the "fallback" shortcode processor
                         remove_shortcode($shortcode_class);
                     }
                 }
             }
         }
     }
     do_action('AHEE__EE_Front_Controller__initialize_shortcodes__end', $this);
 }
 /**
  *    _initialize_shortcodes - calls init method on shortcodes that have been determined to be in the_content for the currently requested page
  *
  * @access    public
  * @param WP $WP
  * @return    void
  */
 public function _initialize_shortcodes(WP $WP)
 {
     do_action('AHEE__EE_Front_Controller__initialize_shortcodes__begin', $WP, $this);
     // grab post_name from request
     $current_post = apply_filters('FHEE__EE_Front_Controller__initialize_shortcodes__current_post_name', EE_Registry::instance()->REQ->get('post_name'));
     // if it's not set, then check if frontpage is blog
     if (empty($current_post) && get_option('show_on_front') == 'posts') {
         // yup.. this is the posts page, prepare to load all shortcode modules
         $current_post = 'posts';
     } else {
         if (empty($current_post) && get_option('show_on_front') == 'page') {
             // some other page is set as the homepage
             $page_on_front = get_option('page_on_front');
             if ($page_on_front) {
                 // k now we need to find the post_name for this page
                 global $wpdb;
                 $SQL = "SELECT post_name from {$wpdb->posts} WHERE post_type='page' AND post_status='publish' AND ID=%d";
                 $page_on_front = $wpdb->get_var($wpdb->prepare($SQL, $page_on_front));
                 // set the current post slug to what it actually is
                 $current_post = $page_on_front ? $page_on_front : $current_post;
             }
         }
     }
     // where are posts being displayed ?
     $page_for_posts = EE_Config::get_page_for_posts();
     // in case $current_post is hierarchical like: /parent-page/current-page
     $current_post = basename($current_post);
     // are we on a category page?
     $term_exists = is_array(term_exists($current_post, 'category')) || array_key_exists('category_name', $WP->query_vars);
     // make sure shortcodes are set
     if (isset(EE_Registry::instance()->CFG->core->post_shortcodes)) {
         // d( EE_Registry::instance()->CFG->core->post_shortcodes );
         // cycle thru all posts with shortcodes set
         foreach (EE_Registry::instance()->CFG->core->post_shortcodes as $post_name => $post_shortcodes) {
             // filter shortcodes so
             $post_shortcodes = apply_filters('FHEE__Front_Controller__initialize_shortcodes__post_shortcodes', $post_shortcodes);
             // now cycle thru shortcodes
             foreach ($post_shortcodes as $shortcode_class => $post_id) {
                 // are we on this page, or on the blog page, or an EE CPT category page ?
                 if ($current_post == $post_name || $term_exists) {
                     // verify shortcode is in list of registered shortcodes
                     if (!isset(EE_Registry::instance()->shortcodes->{$shortcode_class})) {
                         if ($current_post != $page_for_posts && current_user_can('edit_post', $post_id)) {
                             $msg = sprintf(__('The [%s] shortcode has not been properly registered or the corresponding addon/module is not active for some reason. Either fix/remove the shortcode from the post, or activate the addon/module the shortcode is associated with.', 'event_espresso'), $shortcode_class);
                             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
                             add_filter('FHEE_run_EE_the_content', '__return_true');
                         }
                         add_shortcode($shortcode_class, array('EES_Shortcode', 'invalid_shortcode_processor'));
                         continue;
                     }
                     // is this : a shortcodes set exclusively for this post, or for the home page, or a category, or a taxonomy ?
                     if (isset(EE_Registry::instance()->CFG->core->post_shortcodes[$current_post]) || $term_exists || $current_post == $page_for_posts) {
                         // let's pause to reflect on this...
                         $sc_reflector = new ReflectionClass('EES_' . $shortcode_class);
                         // ensure that class is actually a shortcode
                         if (!$sc_reflector->isSubclassOf('EES_Shortcode') && defined('WP_DEBUG') && WP_DEBUG === TRUE) {
                             $msg = sprintf(__('The requested %s shortcode is not of the class "EES_Shortcode". Please check your files.', 'event_espresso'), $shortcode_class);
                             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
                             add_filter('FHEE_run_EE_the_content', '__return_true');
                             continue;
                         }
                         // and pass the request object to the run method
                         EE_Registry::instance()->shortcodes->{$shortcode_class} = $sc_reflector->newInstance();
                         // fire the shortcode class's run method, so that it can activate resources
                         EE_Registry::instance()->shortcodes->{$shortcode_class}->run($WP);
                     }
                     // if this is NOT the "Posts page" and we have a valid entry for the "Posts page" in our tracked post_shortcodes array
                 } else {
                     if ($post_name != $page_for_posts && isset(EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts])) {
                         // and the shortcode is not being tracked for this page
                         if (!isset(EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts][$shortcode_class])) {
                             // then remove the "fallback" shortcode processor
                             remove_shortcode($shortcode_class);
                         }
                     }
                 }
             }
         }
     }
     do_action('AHEE__EE_Front_Controller__initialize_shortcodes__end', $this);
 }
 /**
  *    update_post_shortcodes
  *
  * @access    public
  * @param $page_for_posts
  * @return    void
  */
 public static function update_post_shortcodes($page_for_posts = '')
 {
     // make sure page_for_posts is set
     $page_for_posts = !empty($page_for_posts) ? $page_for_posts : \EE_Config::get_page_for_posts();
     // allow others to mess stuff up :D
     do_action('AHEE__\\EventEspresso\\core\\admin\\PostShortcodeTracking__update_post_shortcodes', \EE_Config::instance()->core->post_shortcodes, $page_for_posts);
     // keep old hookpoint for now, will deprecate later
     do_action('AHEE__EE_Config__update_post_shortcodes', \EE_Config::instance()->core->post_shortcodes, $page_for_posts);
     // verify that post_shortcodes is set
     \EE_Config::instance()->core->post_shortcodes = isset(\EE_Config::instance()->core->post_shortcodes) && is_array(\EE_Config::instance()->core->post_shortcodes) ? \EE_Config::instance()->core->post_shortcodes : array();
     // cycle thru post_shortcodes
     foreach (\EE_Config::instance()->core->post_shortcodes as $post_name => $shortcodes) {
         // are there any shortcodes to track ?
         if (!empty($shortcodes)) {
             // loop thru list of tracked shortcodes
             foreach ($shortcodes as $shortcode => $post_id) {
                 // if shortcode is for a critical page,
                 // BUT this is NOT the corresponding critical page for that shortcode
                 if ($post_name === $page_for_posts) {
                     continue;
                 }
                 // skip the posts page, because we want all shortcodes registered for it
                 if ($post_name === $page_for_posts) {
                     continue;
                 }
                 // make sure post still exists
                 $post = get_post($post_id);
                 // check that the post name matches what we have saved
                 if ($post && $post->post_name === $post_name) {
                     // if so, then break before hitting the unset below
                     continue;
                 }
                 // we don't like missing posts around here >:(
                 unset(\EE_Config::instance()->core->post_shortcodes[$post_name]);
             }
         } else {
             // you got no shortcodes to keep track of !
             unset(\EE_Config::instance()->core->post_shortcodes[$post_name]);
         }
     }
     // critical page shortcodes that we do NOT want added to the Posts page (blog)
     $critical_shortcodes = \EE_Config::instance()->core->get_critical_pages_shortcodes_array();
     $critical_shortcodes = array_flip($critical_shortcodes);
     foreach ($critical_shortcodes as $critical_shortcode) {
         unset(\EE_Config::instance()->core->post_shortcodes[$page_for_posts][$critical_shortcode]);
     }
     //only show errors
     \EE_Config::instance()->update_espresso_config();
 }
 /**
  *    parse_post_content_on_save
  *
  *    any time a post is saved, we need to check for any EE shortcodes that may be embedded in the content,
  *    and then track what posts those shortcodes are on, so that we can initialize shortcodes well before the_content() runs.
  *    this allows us to do things like enqueue scripts for shortcodes ONLY on the pages the shortcodes are actually used on
  *
  * @access    public
  * @param $post_ID
  * @param $post
  * @return    void
  */
 public static function parse_post_content_on_save($post_ID, $post)
 {
     // default post types
     $post_types = array('post' => 0, 'page' => 1);
     // add CPTs
     $CPTs = EE_Register_CPTs::get_CPTs();
     $post_types = array_merge($post_types, $CPTs);
     // for default or CPT posts...
     if (isset($post_types[$post->post_type])) {
         // whether to proceed with update
         $update_post_shortcodes = FALSE;
         // post on frontpage ?
         $page_for_posts = EE_Config::get_page_for_posts();
         // critical page shortcodes that we do NOT want added to the Posts page (blog)
         $critical_shortcodes = EE_Registry::instance()->CFG->core->get_critical_pages_shortcodes_array();
         // array of shortcodes indexed by post name
         EE_Registry::instance()->CFG->core->post_shortcodes = isset(EE_Registry::instance()->CFG->core->post_shortcodes) ? EE_Registry::instance()->CFG->core->post_shortcodes : array();
         // empty both arrays
         EE_Registry::instance()->CFG->core->post_shortcodes[$post->post_name] = array();
         // loop thru shortcodes
         foreach (EE_Registry::instance()->shortcodes as $EES_Shortcode => $shortcode_dir) {
             // convert to UPPERCASE to get actual shortcode
             $EES_Shortcode = strtoupper($EES_Shortcode);
             // is the shortcode in the post_content ?
             if (strpos($post->post_content, $EES_Shortcode) !== FALSE) {
                 // map shortcode to post names and post IDs
                 EE_Registry::instance()->CFG->core->post_shortcodes[$post->post_name][$EES_Shortcode] = $post_ID;
                 // if the shortcode is NOT one of the critical page shortcodes like ESPRESSO_TXN_PAGE
                 if (!in_array($EES_Shortcode, $critical_shortcodes)) {
                     // check that posts page is already being tracked
                     if (!isset(EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts])) {
                         // if not, then ensure that it is properly added
                         EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts] = array();
                     }
                     // add shortcode to "Posts page" tracking
                     EE_Registry::instance()->CFG->core->post_shortcodes[$page_for_posts][$EES_Shortcode] = $post_ID;
                 }
                 $update_post_shortcodes = TRUE;
             }
         }
         if ($update_post_shortcodes) {
             EE_Registry::instance()->CFG->update_post_shortcodes($page_for_posts);
         }
     }
 }