| Server IP : 104.21.21.239 / Your IP : 216.73.216.68 Web Server : Apache/2.4.68 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-69-123.ec2.internal 6.1.176-223.369.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Jul 24 13:34:27 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/home2/mommybites/wp-content/plugins/fb-instant-articles/ |
Upload File : |
<?php
/**
* Plugin Name: Instant Articles for WP
* Description: Add support for Instant Articles for Facebook to your WordPress site.
* Author: Automattic, Dekode, Facebook
* Author URI: https://vip.wordpress.com/plugins/instant-articles/
* Version: 4.2.1
* Text Domain: instant-articles
* License: GPLv2
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
*
* @package default
*/
/**
* Prints error about incompatible version. Extracted as function issue: #390
*
* @since 3.3.4
*/
function show_version_incompatible_warning() {
echo '<div class="error"><p>' .
esc_html__( 'Instant Articles for WP requires PHP 5.4 to function properly. Please upgrade PHP or deactivate Instant Articles for WP.', 'instant-articles' ) . '</p></div>';
}
if ( version_compare( PHP_VERSION, '5.4', '<' ) ) {
add_action(
'admin_notices',
'show_version_incompatible_warning'
);
return;
} else {
$autoloader = require __DIR__ . '/vendor/autoload.php';
$autoloader->add( 'Facebook\\', __DIR__ . '/vendor/facebook/facebook-instant-articles-sdk-php/src' );
$autoloader->add( 'Facebook\\', __DIR__ . '/vendor/facebook/facebook-instant-articles-sdk-extensions-in-php/src' );
defined( 'ABSPATH' ) || die( 'Shame on you' );
define( 'IA_PLUGIN_VERSION', '4.2.1' );
define( 'IA_PLUGIN_PATH_FULL', __FILE__ );
define( 'IA_PLUGIN_PATH', plugin_basename( __FILE__ ) );
define( 'IA_PLUGIN_FILE_BASENAME', pathinfo( __FILE__, PATHINFO_FILENAME ) );
define( 'IA_PLUGIN_TEXT_DOMAIN', 'instant-articles' );
define( 'IA_PLUGIN_FORCE_SUBMIT_KEY', 'instant_articles_force_submit' );
// Let users define their own feed slug.
if ( ! defined( 'INSTANT_ARTICLES_SLUG' ) ) {
define( 'INSTANT_ARTICLES_SLUG', 'instant-articles' );
}
require_once( dirname( __FILE__ ) . '/embeds.php' );
require_once( dirname( __FILE__ ) . '/class-instant-articles-post.php' );
require_once( dirname( __FILE__ ) . '/wizard/class-instant-articles-wizard.php' );
require_once( dirname( __FILE__ ) . '/meta-box/class-instant-articles-meta-box.php' );
require_once( dirname( __FILE__ ) . '/class-instant-articles-amp-markup.php' );
require_once( dirname( __FILE__ ) . '/class-instant-articles-signer.php' );
/**
* Plugin activation hook to add our rewrite rules.
*
* @since 0.1
*/
function instant_articles_activate() {
instant_articles_init();
flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'instant_articles_activate' );
/**
* Show a message to set up the plugin when it is activated
*/
add_action( 'admin_notices', 'instant_articles_setup_admin_notice' );
add_action( 'network_admin_notices', 'instant_articles_setup_admin_notice' ); // also show message on multisite
function instant_articles_setup_admin_notice() {
global $pagenow;
if ( $pagenow === 'plugins.php' && ! Instant_Articles_Option_FB_Page::get_option_decoded()[ "page_id" ] ) {
$settings_url = Instant_Articles_Wizard::get_url();
echo '<div class="updated settings-error notice is-dismissible">';
echo '<p>Congrats, you\'ve installed the Instant Articles for WP plugin. Now <a href="' . esc_url_raw($settings_url) . '">set it up</a> to start publishing Instant Articles.';
echo '</div>';
}
}
/**
* Plugin activation hook to remove our rewrite rules.
*
* @since 0.1
*/
function instant_articles_deactivate() {
flush_rewrite_rules();
}
register_deactivation_hook( __FILE__, 'instant_articles_deactivate' );
/**
* Load plugin textdomain.
*
* @since 0.1
*/
function instant_articles_load_textdomain() {
load_plugin_textdomain( 'instant-articles', false, plugin_dir_path( __FILE__ ) . '/languages' );
}
add_action( 'plugins_loaded', 'instant_articles_load_textdomain' );
/**
* Plugin hook to load compat layers.
*
* @since 2.0
*/
function instant_articles_load_compat() {
require_once( dirname( __FILE__ ) . '/compat.php' );
}
add_action( 'plugins_loaded', 'instant_articles_load_compat' );
/**
* Register our special feed.
*
* @since 0.1
*/
function instant_articles_init() {
add_feed( INSTANT_ARTICLES_SLUG, 'instant_articles_feed' );
}
add_action( 'init', 'instant_articles_init' );
/**
* Feed display callback.
*
* @since 0.1
*/
function instant_articles_feed() {
// Load the feed template.
include( dirname( __FILE__ ) . '/feed-template.php' );
}
/**
* Whether currently processing an instant article.
*
* @param bool Set the status
* @return bool
*/
function is_transforming_instant_article( $set_status = null ) {
static $is_instant_article = false;
if ( isset( $set_status ) ) {
$is_instant_article = (bool) $set_status;
}
return $is_instant_article;
}
/**
* Modify the main query for our feed.
*
* We want the posts in the modified order, to provide Facebook with content updates even for older posts.
* Facebook will only import 100 posts at the time.
* Facebook will only update posts modified within the last 24 hours
*
* @param WP_Query $query The WP_Query object. Passed by reference.
*/
function instant_articles_query( $query ) {
if ( $query->is_main_query() && $query->is_feed( INSTANT_ARTICLES_SLUG ) ) {
$query->set( 'orderby', 'modified' );
$query->set( 'posts_per_page', 10 );
$query->set( 'posts_per_rss', 10 );
/**
* Filter the post types to include in the query.
*
* Default to `post` only, but allow other post types to be included by the theme/plugins.
*
* @since 2.12
*
* @param array $post_types Array of post types
*/
$post_types = apply_filters( 'instant_articles_post_types', array( 'post' ) );
$query->set( 'post_type', $post_types );
/**
* If the constant INSTANT_ARTICLES_LIMIT_POSTS is set to true, we will limit the feed
* to only include posts which are modified within the last 24 hours.
* Facebook will initially need 100 posts to pass the review, but will only update
* already imported articles if they are modified within the last 24 hours.
*/
if ( defined( 'INSTANT_ARTICLES_LIMIT_POSTS' ) && INSTANT_ARTICLES_LIMIT_POSTS ) {
$query->set( 'date_query', array(
array(
'column' => 'post_modified',
'after' => '1 day ago',
),
) );
}
}
}
add_action( 'pre_get_posts', 'instant_articles_query', 10, 1 );
/**
* Filter the SQL query to not include posts with empty content -- FB will complain.
*
* @since 0.1
* @param string $where The original where part of the SQL statement.
* @param WP_Query $query The WP_Query instance.
* @return string The modified where part of the SQL statement.
*/
function instant_articles_query_where( $where, $query ) {
// Don’t modify the SQL query with a potentially expensive WHERE clause if we’re OK with fewer posts than 100 and are OK with filtering in the loop.
if ( defined( 'INSTANT_ARTICLES_LIMIT_POSTS' ) && INSTANT_ARTICLES_LIMIT_POSTS ) {
return $where;
}
if ( $query->is_main_query() && $query->is_feed( INSTANT_ARTICLES_SLUG ) ) {
global $wpdb;
$where .= " AND {$wpdb->posts}.post_content NOT LIKE ''";
}
return $where;
}
add_filter( 'posts_where' , 'instant_articles_query_where', 10, 2 );
/**
* Register all scripts and styles for the admin UI.
*
* @since 0.4
*/
function instant_articles_register_scripts() {
wp_register_style(
'instant-articles-meta-box',
plugins_url( '/css/instant-articles-meta-box.css', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_style(
'instant-articles-settings',
plugins_url( '/css/instant-articles-settings.css', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_style(
'instant-articles-wizard',
plugins_url( '/css/instant-articles-wizard.css', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_style(
'instant-articles-index-column',
plugins_url( '/css/instant-articles-index-column.css', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_script(
'instant-articles-meta-box',
plugins_url( '/js/instant-articles-meta-box.js', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_script(
'instant-articles-option-ads',
plugins_url( '/js/instant-articles-option-ads.js', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_script(
'instant-articles-option-analytics',
plugins_url( '/js/instant-articles-option-analytics.js', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_script(
'instant-articles-option-publishing',
plugins_url( '/js/instant-articles-option-publishing.js', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
wp_register_script(
'instant-articles-settings',
plugins_url( '/js/instant-articles-settings.js', __FILE__ ),
null,
IA_PLUGIN_VERSION,
false
);
}
add_action( 'init', 'instant_articles_register_scripts' );
/**
* Enqueue all scripts and styles for the admin UI.
*
* @since 0.4
*/
function instant_articles_enqueue_scripts() {
wp_enqueue_style( 'instant-articles-meta-box' );
wp_enqueue_style( 'instant-articles-settings-wizard' );
wp_enqueue_style( 'instant-articles-settings' );
wp_enqueue_style( 'instant-articles-wizard' );
wp_enqueue_style( 'instant-articles-index-column' );
wp_enqueue_script( 'instant-articles-meta-box' );
wp_enqueue_script( 'instant-articles-option-ads' );
wp_enqueue_script( 'instant-articles-option-analytics' );
wp_enqueue_script( 'instant-articles-option-publishing' );
wp_enqueue_script( 'instant-articles-settings' );
wp_enqueue_script( 'instant-articles-wizard' );
}
add_action( 'admin_enqueue_scripts', 'instant_articles_enqueue_scripts' );
/**
* 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
}
}
add_action( 'wp_head', 'inject_url_claiming_meta_tag' );
/**
* Automatically add meta tag for Instant Articles Open Publish scraper
*
* @since 4.0
*/
function inject_ia_markup_meta_tag() {
$post = get_post();
// If there's no current post, return
if ( ! $post ) {
return;
}
// Transform the post to an Instant Article.
$adapter = new Instant_Articles_Post( $post );
if ( $adapter->should_submit_post() ) {
$url = $adapter->get_canonical_url();
$url = add_query_arg( 'ia_markup', '1', $url );
$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 ( $dev_mode ) {
?>
<meta property="ia:markup_url_dev" content="<?php echo esc_attr( $url ); ?>" />
<?php
} else {
?>
<meta property="ia:markup_url" content="<?php echo esc_attr( $url ); ?>" />
<?php
}
}
}
add_action( 'wp_head', 'inject_ia_markup_meta_tag' );
// Injects the <link rel...> tag if the AMP Markup is enabled
add_action( 'wp_head', array('Instant_Articles_AMP_Markup', 'inject_link_rel') );
// Initialize the Instant Articles meta box.
Instant_Articles_Meta_Box::init();
function ia_markup_version( ) {
$post = get_post();
if (isset( $_GET[ 'ia_markup' ] ) && $_GET[ 'ia_markup' ]) {
// Transform the post to an Instant Article.
$adapter = new Instant_Articles_Post( $post );
$article = $adapter->to_instant_article();
echo $article->render( null, true );
die();
}
}
add_action( 'wp', 'ia_markup_version' );
// Add hook for generating the AMP markup
add_action( 'wp', array('Instant_Articles_AMP_Markup', 'markup_version') );
Instant_Articles_Wizard::init();
Instant_Articles_Signer::init();
function invalidate_post_transformation_info_cache( $post_id, $post ) {
// These post metas are caches on the calculations made to decide if
// a post is in good state to be converted to an Instant Article or not
delete_post_meta( $post_id, '_has_warnings_after_transformation' );
delete_post_meta( $post_id, '_is_empty_after_transformation' );
}
add_action( 'save_post', 'invalidate_post_transformation_info_cache', 10, 2 );
// We also need to invalidate the transformation caches when the option containing
// the custom transformer rules is updated
function invalidate_all_posts_transformation_info_cache( $option ) {
if ( $option === Instant_Articles_Option_Publishing::OPTION_KEY ) {
// These post metas are caches on the calculations made to decide if
// a post is in good state to be converted to an Instant Article or not
delete_post_meta_by_key( '_has_warnings_after_transformation' );
delete_post_meta_by_key( '_is_empty_after_transformation' );
}
}
add_action( 'updated_option', 'invalidate_all_posts_transformation_info_cache', 10, 1 );
function fbia_indicator_column_heading( $columns ) {
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
$display_warning_column = isset( $publishing_settings[ 'display_warning_column' ] ) ? $publishing_settings[ 'display_warning_column' ] : '0';
if( "1" === $display_warning_column ) {
$columns[ 'FBIA' ] = "<span title='Facebook Instant Article Distribution Status' class='fbia-col-heading'>FB IA Status</span>";
}
return $columns;
}
add_filter( 'manage_posts_columns', 'fbia_indicator_column_heading' );
function fbia_indication_column( $column_name, $post_ID ) {
$publishing_settings = Instant_Articles_Option_Publishing::get_option_decoded();
$display_warning_column = isset( $publishing_settings[ 'display_warning_column' ] ) ? $publishing_settings[ 'display_warning_column' ] : '0';
if( "1" === $display_warning_column ) {
$red_light = '<span title="Instant article is empty after transformation." class="instant-articles-col-status error"></span>';
$yellow_light = '<span title="Instant article has warnings after transformation." class="instant-articles-col-status warning"></span>';
$green_light = '<span title="Instant article transformed successfully." class="instant-articles-col-status ok"></span>';
if ( $column_name === "FBIA" ) {
$post = get_post( $post_ID );
$instant_articles_post = new \Instant_Articles_Post( $post );
$is_empty = $instant_articles_post->is_empty_after_transformation();
if ( true === $is_empty ) {
echo wp_kses_post( $red_light );
return;
}
$has_warnings = $instant_articles_post->has_warnings_after_transformation();
if ( true === $has_warnings ) {
echo wp_kses_post( $yellow_light );
return;
}
echo wp_kses_post( $green_light );
return;
}
}
}
add_action( 'manage_posts_custom_column', 'fbia_indication_column', 10, 2 );
function invalidate_scrape_on_update( $post_ID, $post_after, $post_before ) {
$adapter = new Instant_Articles_Post( $post_after );
if ( $adapter->should_submit_post() ) {
$fb_app_settings = Instant_Articles_Option_FB_App::get_option_decoded();
if (
( isset( $fb_app_settings[ 'page_access_token' ] ) && $fb_app_settings[ 'page_access_token' ] ) &&
( isset( $fb_app_settings[ 'app_id' ] ) && $fb_app_settings[ 'app_id' ] ) &&
( isset( $fb_app_settings[ 'app_secret' ] ) && $fb_app_settings[ 'app_secret' ] )
) {
// Fetches the right URL to invalidate
$url = $adapter->get_canonical_url();
// oAuth info
$app_id = $fb_app_settings[ 'app_id' ];
$app_secret = $fb_app_settings[ 'app_secret' ];
$access_token = $fb_app_settings[ 'page_access_token' ];
// Build Graph SDK instance
$fb = new \Facebook\Facebook([
'app_id' => $app_id,
'app_secret' => $app_secret,
'default_access_token' => $access_token
]);
function admin_notice__scrape_invalidation_failed() {
?>
<div class="notice notice-error is-dismissible">
<p>
<?php _e( 'It was not possible to automatically invalidate the scrape for this article.', IA_PLUGIN_TEXT_DOMAIN ) ?>
<?php _e( 'Please trigger a new scrape manually using the Facebook Share Debugger.', IA_PLUGIN_TEXT_DOMAIN ) ?>
</p>
</div>
<?php
}
function admin_notice__scrape_invalidation_success() {
?>
<div class="notice notice-success is-dismissible">
<p>
<?php _e( 'Successfully refreshed the Instant Articles cache for this article.', IA_PLUGIN_TEXT_DOMAIN ) ?>
</p>
</div>
<?php
}
// Make call
$graph_api_call = '/';
$graph_api_call = add_query_arg( 'id', rawurlencode($url), $graph_api_call);
$graph_api_call = add_query_arg( 'scrape', 'true', $graph_api_call);
try {
$fb->post( $graph_api_call, [], $access_token );
add_action( 'admin_notices', 'admin_notice__scrape_invalidation_success' );
} catch(Facebook\Exceptions\FacebookResponseException $e) {
echo '<pre>';
print_r($e->getTraceAsString());
add_action( 'admin_notices', 'admin_notice__scrape_invalidation_failed' );
} catch(Facebook\Exceptions\FacebookSDKException $e) {
add_action( 'admin_notices', 'admin_notice__scrape_invalidation_failed' );
}
}
}
}
add_action( 'post_updated', 'invalidate_scrape_on_update', 10, 3 );
function rescrape_article( $post_id, $post ) {
$adapter = new Instant_Articles_Post( $post );
$old_slugs = get_post_meta( $post_id, '_wp_old_slug' );
if ( $adapter->should_submit_post() ) {
$fb_app_settings = Instant_Articles_Option_FB_App::get_option_decoded();
if (
( isset( $fb_app_settings[ 'page_access_token' ] ) && $fb_app_settings[ 'page_access_token' ] ) &&
( isset( $fb_app_settings[ 'app_id' ] ) && $fb_app_settings[ 'app_id' ] ) &&
( isset( $fb_app_settings[ 'app_secret' ] ) && $fb_app_settings[ 'app_secret' ] )
) {
// Defer to access_token if configured to ensure backwards compatibility
return;
}
try {
if ( extension_loaded('openssl') ) {
$client = Facebook\HttpClients\HttpClientsFactory::createHttpClient( null );
$url_encoded = urlencode($adapter->get_canonical_url());
$client->send(
Instant_Articles_Signer::sign_request_path(
"https://graph.facebook.com/?id=$url_encoded&scrape=true"
),
'POST',
'',
array(),
60
);
foreach ( $old_slugs as $slug ) {
$clone_post = clone $post;
$clone_post->post_name = $slug;
$clone_adapter = new Instant_Articles_Post( $clone_post );
$url_encoded = urlencode($clone_adapter->get_canonical_url());
$client->send(
Instant_Articles_Signer::sign_request_path(
"https://graph.facebook.com/?id=$url_encoded&scrape=true"
),
'POST',
'',
array(),
60
);
}
}
} catch ( Exception $e ) {
error_log( 'Unable to submit article.'.$e->getTraceAsString() );
}
}
}
add_action( 'save_post', 'rescrape_article', 999, 2 );
}