/**
  * Renderer for the Metabox.
  */
 public static function render_meta_box()
 {
     $ajax_nonce = wp_create_nonce("instant-articles-force-submit");
     $post_id = intval($_POST['post_ID']);
     $post = get_post($post_id);
     $adapter = new Instant_Articles_Post($post);
     $article = $adapter->to_instant_article();
     $canonical_url = $adapter->get_canonical_url();
     $submission_status = null;
     $published = 'publish' === $post->post_status;
     $dev_mode = false;
     $force_submit = get_post_meta($post_id, Instant_Articles_Publisher::FORCE_SUBMIT_KEY, true);
     $should_submit_post = apply_filters('instant_articles_should_submit_post', true, $adapter);
     Instant_Articles_Wizard::menu_items();
     $settings_page_href = Instant_Articles_Wizard::get_url();
     $publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
     $publish_with_warnings = $publishing_settings['publish_with_warnings'];
     if ($published) {
         try {
             $fb_app_settings = Instant_Articles_Option_FB_App::get_option_decoded();
             $fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
             $publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
             $dev_mode = isset($publishing_settings['dev_mode']) ? $publishing_settings['dev_mode'] ? true : false : false;
             if (isset($fb_app_settings['app_id']) && isset($fb_app_settings['app_secret']) && isset($fb_page_settings['page_access_token']) && isset($fb_page_settings['page_id'])) {
                 // Instantiate a new Client to get the status of this article.
                 $client = Client::create($fb_app_settings['app_id'], $fb_app_settings['app_secret'], $fb_page_settings['page_access_token'], $fb_page_settings['page_id'], $dev_mode);
                 $submission_status_id = get_post_meta($post_id, Instant_Articles_Publisher::SUBMISSION_ID_KEY, true);
                 if (!empty($submission_status_id)) {
                     $submission_status = $client->getSubmissionStatus($submission_status_id);
                 } else {
                     // Grab the latest status of this article and display.
                     $article_id = $client->getArticleIDFromCanonicalURL($canonical_url);
                     $submission_status = $client->getLastSubmissionStatus($article_id);
                 }
             }
         } catch (FacebookResponseException $e) {
             $submission_status = null;
         }
     }
     include dirname(__FILE__) . '/meta-box-template.php';
     die;
 }
    /**
     * Automatically add meta tag for Instant Articles URL claiming
     * when page is set.
     *
     * @since 0.4
     */
    function inject_url_claiming_meta_tag()
    {
        $publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
        $fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
        if (isset($fb_page_settings['page_id'])) {
            ?>
			<meta property="fb:pages" content="<?php 
            echo esc_attr($fb_page_settings['page_id']);
            ?>
" />
			<?php 
        }
    }
 /**
  * Render post
  *
  * @since 0.1
  * @return InstantArticle
  */
 public function to_instant_article()
 {
     /**
      * Fires before the instant article is rendered.
      *
      * @since 0.1
      * @param Instant_Article_Post  $instant_article_post  The instant article post.
      */
     do_action('instant_articles_before_transform_post', $this);
     // Get time zone configured in WordPress. Default to UTC if no time zone configured.
     $date_time_zone = get_option('timezone_string') ? new DateTimeZone(get_option('timezone_string')) : new DateTimeZone('UTC');
     // Initialize transformer
     $file_path = plugin_dir_path(__FILE__) . 'rules-configuration.json';
     $configuration = file_get_contents($file_path);
     $transformer = new Transformer();
     $this->transformer = $transformer;
     $transformer->loadRules($configuration);
     $transformer = apply_filters('instant_articles_transformer_rules_loaded', $transformer);
     $settings_publishing = Instant_Articles_Option_Publishing::get_option_decoded();
     if (isset($settings_publishing['custom_rules_enabled']) && !empty($settings_publishing['custom_rules_enabled']) && isset($settings_publishing['custom_rules']) && !empty($settings_publishing['custom_rules'])) {
         $transformer->loadRules($settings_publishing['custom_rules']);
     }
     $transformer = apply_filters('instant_articles_transformer_custom_rules_loaded', $transformer);
     $blog_charset = get_option('blog_charset');
     $header = Header::create()->withPublishTime(Time::create(Time::PUBLISHED)->withDatetime(new DateTime($this->_post->post_date, $date_time_zone)))->withModifyTime(Time::create(Time::MODIFIED)->withDatetime(new DateTime($this->_post->post_modified, $date_time_zone)));
     $title = $this->get_the_title();
     if ($title) {
         $document = new DOMDocument();
         libxml_use_internal_errors(true);
         $document->loadHTML('<?xml encoding="' . $blog_charset . '" ?><h1>' . $title . '</h1>');
         libxml_use_internal_errors(false);
         $transformer->transform($header, $document);
     }
     if ($this->has_subtitle()) {
         $header->withSubTitle($this->get_the_subtitle());
     }
     $authors = $this->get_the_authors();
     foreach ($authors as $author) {
         $author_obj = Author::create();
         if ($author->display_name) {
             $author_obj->withName($author->display_name);
         }
         if ($author->bio) {
             $author_obj->withDescription($author->bio);
         }
         if ($author->user_url) {
             $author_obj->withURL($author->user_url);
         }
         $header->addAuthor($author_obj);
     }
     $kicker = $this->get_the_kicker();
     if ($kicker) {
         $header->withKicker($kicker);
     }
     $cover = $this->get_cover_media();
     if ($cover->getUrl()) {
         $header->withCover($cover);
     }
     $this->instant_article = InstantArticle::create()->withCanonicalUrl($this->get_canonical_url())->withHeader($header)->addMetaProperty('op:generator:application', 'facebook-instant-articles-wp')->addMetaProperty('op:generator:application:version', IA_PLUGIN_VERSION);
     $settings_style = Instant_Articles_Option_Styles::get_option_decoded();
     if (isset($settings_style['article_style']) && !empty($settings_style['article_style'])) {
         $this->instant_article->withStyle($settings_style['article_style']);
     } else {
         $this->instant_article->withStyle('default');
     }
     $libxml_previous_state = libxml_use_internal_errors(true);
     $document = new DOMDocument('1.0', get_option('blog_charset'));
     $content = $this->get_the_content();
     // DOMDocument isn’t handling encodings too well, so let’s help it a little.
     if (function_exists('mb_convert_encoding')) {
         $content = mb_convert_encoding($content, 'HTML-ENTITIES', get_option('blog_charset'));
     } else {
         $content = htmlspecialchars_decode(utf8_decode(htmlentities($content, ENT_COMPAT, 'utf-8', false)));
     }
     $result = $document->loadHTML('<!doctype html><html><body>' . $content . '</body></html>');
     // We need to make sure that scripts use absolute URLs and not relative URLs.
     $scripts = $document->getElementsByTagName('script');
     if (!empty($scripts)) {
         foreach ($scripts as $script) {
             $src = $script->getAttribute('src');
             $explode_src = parse_url($src);
             if (is_array($explode_src) && empty($explode_src['scheme']) && !empty($explode_src['host']) && !empty($explode_src['path'])) {
                 $src = 'https://' . $explode_src['host'] . $explode_src['path'];
             }
             $script->setAttribute('src', $src);
         }
     }
     libxml_clear_errors();
     libxml_use_internal_errors($libxml_previous_state);
     $document = apply_filters('instant_articles_parsed_document', $document);
     if ($result) {
         $transformer->transform($this->instant_article, $document);
     }
     $this->add_ads_from_settings();
     $this->add_analytics_from_settings();
     $this->instant_article = apply_filters('instant_articles_transformed_element', $this->instant_article);
     /**
      * Fires after the instant article is rendered.
      *
      * @since 0.1
      * @param Instant_Article_Post  $instant_article_post  The instant article post.
      */
     do_action('instant_articles_after_transform_post', $this);
     return $this->instant_article;
 }
 /**
  * Submits article to Instant Articles.
  *
  * @param string $post_id The identifier of post.
  * @param Post   $post The WP Post.
  */
 public static function submit_article($post_id, $post)
 {
     // Don't process if this is just a revision or an autosave.
     if (wp_is_post_revision($post) || wp_is_post_autosave($post)) {
         return;
     }
     // Don't process if this post is not published
     if ('publish' !== $post->post_status) {
         return;
     }
     // Only process posts
     $post_types = apply_filters('instant_articles_post_types', array('post'));
     if (!in_array($post->post_type, $post_types)) {
         return;
     }
     // Transform the post to an Instant Article.
     $adapter = new Instant_Articles_Post($post);
     $article = $adapter->to_instant_article();
     // Skip empty articles or articles missing title.
     // This is important because the save_post action is also triggered by bulk updates, but in this case
     // WordPress does not load the content field from DB for performance reasons. In this case, articles
     // will be empty here, despite of them actually having content.
     if (count($article->getChildren()) === 0 || !$article->getHeader() || !$article->getHeader()->getTitle()) {
         return;
     }
     // Instantiate an API client.
     try {
         $fb_app_settings = Instant_Articles_Option_FB_App::get_option_decoded();
         $fb_page_settings = Instant_Articles_Option_FB_Page::get_option_decoded();
         $publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
         $dev_mode = isset($publishing_settings['dev_mode']) ? $publishing_settings['dev_mode'] ? true : false : false;
         if (isset($fb_app_settings['app_id']) && isset($fb_app_settings['app_secret']) && isset($fb_page_settings['page_access_token']) && isset($fb_page_settings['page_id'])) {
             $client = Client::create($fb_app_settings['app_id'], $fb_app_settings['app_secret'], $fb_page_settings['page_access_token'], $fb_page_settings['page_id'], $dev_mode);
             // Don't publish posts with password protection
             if (post_password_required($post)) {
                 // Unpublishes if already published and from now on it started to have password protection
                 $client->removeArticle($article->getCanonicalURL());
                 delete_post_meta($post_id, self::SUBMISSION_ID_KEY);
                 return;
             }
             // Don't process if contains warnings and blocker flag for transformation warnings is turned on.
             if (count($adapter->transformer->getWarnings()) > 0 && isset($publishing_settings['block_publish_with_warnings']) && $publishing_settings['block_publish_with_warnings']) {
                 // Unpublishes if already published
                 $client->removeArticle($article->getCanonicalURL());
                 delete_post_meta($post_id, self::SUBMISSION_ID_KEY);
                 return;
             }
             if ($dev_mode) {
                 $published = false;
             } else {
                 // Any publish status other than 'publish' means draft for the Instant Article.
                 $published = true;
             }
             try {
                 // Import the article.
                 $submission_id = $client->importArticle($article, $published);
                 update_post_meta($post_id, self::SUBMISSION_ID_KEY, $submission_id);
             } catch (Exception $e) {
                 // Try without taking live for pages not yet reviewed.
                 $submission_id = $client->importArticle($article, false);
                 update_post_meta($post_id, self::SUBMISSION_ID_KEY, $submission_id);
             }
         }
     } catch (Exception $e) {
         Logger::getLogger('instantarticles-wp-plugin')->error('Unable to submit article.', $e->getTraceAsString());
     }
 }
 /**
  * Render post
  *
  * @since 0.1
  * @return InstantArticle
  */
 public function to_instant_article()
 {
     /**
      * Fires before the instant article is rendered.
      *
      * @since 0.1
      * @param Instant_Article_Post  $instant_article_post  The instant article post.
      */
     do_action('instant_articles_before_transform_post', $this);
     // Get time zone configured in WordPress. Default to UTC if no time zone configured.
     $date_time_zone = get_option('timezone_string') ? new DateTimeZone(get_option('timezone_string')) : new DateTimeZone('UTC');
     // Initialize transformer
     $file_path = plugin_dir_path(__FILE__) . 'rules-configuration.json';
     $configuration = file_get_contents($file_path);
     $transformer = new Transformer();
     $this->transformer = $transformer;
     $transformer->loadRules($configuration);
     $transformer = apply_filters('instant_articles_transformer_rules_loaded', $transformer);
     $settings_publishing = Instant_Articles_Option_Publishing::get_option_decoded();
     if (isset($settings_publishing['custom_rules_enabled']) && !empty($settings_publishing['custom_rules_enabled']) && isset($settings_publishing['custom_rules']) && !empty($settings_publishing['custom_rules'])) {
         $transformer->loadRules($settings_publishing['custom_rules']);
     }
     $transformer = apply_filters('instant_articles_transformer_custom_rules_loaded', $transformer);
     $blog_charset = get_option('blog_charset');
     $header = Header::create()->withPublishTime(Time::create(Time::PUBLISHED)->withDatetime(new DateTime($this->_post->post_date, $date_time_zone)))->withModifyTime(Time::create(Time::MODIFIED)->withDatetime(new DateTime($this->_post->post_modified, $date_time_zone)));
     $title = $this->get_the_title();
     if ($title) {
         $document = new DOMDocument();
         libxml_use_internal_errors(true);
         $document->loadHTML('<?xml encoding="' . $blog_charset . '" ?><h1>' . $title . '</h1>');
         libxml_use_internal_errors(false);
         $transformer->transform($header, $document);
     }
     if ($this->has_subtitle()) {
         $header->withSubTitle($this->get_the_subtitle());
     }
     $authors = $this->get_the_authors();
     foreach ($authors as $author) {
         $author_obj = Author::create();
         if ($author->display_name) {
             $author_obj->withName($author->display_name);
         }
         if ($author->bio) {
             $author_obj->withDescription($author->bio);
         }
         if ($author->user_url) {
             $author_obj->withURL($author->user_url);
         }
         $header->addAuthor($author_obj);
     }
     $kicker = $this->get_the_kicker();
     if ($kicker) {
         $header->withKicker($kicker);
     }
     $cover = $this->get_cover_media();
     if ($cover->getUrl()) {
         $header->withCover($cover);
     }
     $this->instant_article = InstantArticle::create()->withCanonicalUrl($this->get_canonical_url())->withHeader($header)->addMetaProperty('op:generator:application', 'facebook-instant-articles-wp')->addMetaProperty('op:generator:application:version', IA_PLUGIN_VERSION);
     $settings_style = Instant_Articles_Option_Styles::get_option_decoded();
     if (isset($settings_style['article_style']) && !empty($settings_style['article_style'])) {
         $this->instant_article->withStyle($settings_style['article_style']);
     } else {
         $this->instant_article->withStyle('default');
     }
     $transformer->transformString($this->instant_article, $this->get_the_content(), get_option('blog_charset'));
     $this->add_ads_from_settings();
     $this->add_analytics_from_settings();
     $this->instant_article = apply_filters('instant_articles_transformed_element', $this->instant_article);
     /**
      * Fires after the instant article is rendered.
      *
      * @since 0.1
      * @param Instant_Article_Post  $instant_article_post  The instant article post.
      */
     do_action('instant_articles_after_transform_post', $this);
     return $this->instant_article;
 }