Commit inicial - WordPress Análisis de Precios Unitarios

- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
root
2025-11-03 21:04:30 -06:00
commit a22573bf0b
24068 changed files with 4993111 additions and 0 deletions

View File

@@ -0,0 +1,246 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Admin_Post_List
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID;
/**
* Class for adding RRM elements to the WP Admin post list.
*
* @since 1.148.0
* @access private
* @ignore
*/
class Admin_Post_List {
/**
* Post_Product_ID instance.
*
* @since 1.148.0
*
* @var Post_Product_ID
*/
private $post_product_id;
/**
* Settings instance.
*
* @since 1.148.0
*
* @var Settings
*/
private $settings;
/**
* Constructor.
*
* @since 1.148.0
*
* @param Settings $settings Module settings instance.
* @param Post_Product_ID $post_product_id Post Product ID.
*/
public function __construct( Settings $settings, Post_Product_ID $post_product_id ) {
$this->settings = $settings;
$this->post_product_id = $post_product_id;
}
/**
* Registers functionality through WordPress hooks.
*
* @since 1.148.0
*/
public function register() {
$post_types = $this->get_post_types();
foreach ( $post_types as $post_type ) {
add_filter(
"manage_{$post_type}_posts_columns",
array( $this, 'add_column' )
);
add_action(
"manage_{$post_type}_posts_custom_column",
array( $this, 'fill_column' ),
10,
2
);
}
add_action(
'bulk_edit_custom_box',
array( $this, 'bulk_edit_field' ),
10,
2
);
add_action( 'save_post', array( $this, 'save_field' ) );
}
/**
* Adds a custom column to the post list.
*
* @since 1.148.0
*
* @param array $columns Columns.
* @return array Modified columns.
*/
public function add_column( $columns ) {
$columns['rrm_product_id'] = __( 'Reader Revenue CTA', 'google-site-kit' );
return $columns;
}
/**
* Fills the custom column with data.
*
* @since 1.148.0
*
* @param string $column Column name.
* @param int $post_id Post ID.
*/
public function fill_column( $column, $post_id ) {
if ( 'rrm_product_id' !== $column ) {
return;
}
$post_product_id = $this->post_product_id->get( $post_id );
if ( ! empty( $post_product_id ) ) {
switch ( $post_product_id ) {
case 'none':
esc_html_e( 'None', 'google-site-kit' );
break;
case 'openaccess':
esc_html_e( 'Open access', 'google-site-kit' );
break;
default:
$separator_index = strpos( $post_product_id, ':' );
if ( false === $separator_index ) {
echo esc_html( $post_product_id );
} else {
echo esc_html(
substr( $post_product_id, $separator_index + 1 )
);
}
}
return;
}
$settings = $this->settings->get();
$snippet_mode = $settings['snippetMode'];
$cta_post_types = apply_filters( 'googlesitekit_reader_revenue_manager_cta_post_types', $settings['postTypes'] );
if ( 'per_post' === $snippet_mode || ( 'post_types' === $snippet_mode && ! in_array( get_post_type(), $cta_post_types, true ) ) ) {
esc_html_e( 'None', 'google-site-kit' );
return;
}
esc_html_e( 'Default', 'google-site-kit' );
}
/**
* Adds a custom field to the bulk edit form.
*
* @since 1.148.0
*/
public function bulk_edit_field() {
$settings = $this->settings->get();
$product_ids = $settings['productIDs'] ?? array();
$default_options = array(
'-1' => __( '— No Change —', 'google-site-kit' ),
'' => __( 'Default', 'google-site-kit' ),
'none' => __( 'None', 'google-site-kit' ),
'openaccess' => __( 'Open access', 'google-site-kit' ),
);
?>
<fieldset class="inline-edit-col-right">
<div class="inline-edit-col">
<label style="align-items: center; display: flex; gap: 16px; line-height: 1;">
<span><?php esc_html_e( 'Reader Revenue CTA', 'google-site-kit' ); ?></span>
<select name="rrm_product_id">
<?php foreach ( $default_options as $value => $label ) : ?>
<option value="<?php echo esc_attr( $value ); ?>">
<?php echo esc_html( $label ); ?>
</option>
<?php endforeach; ?>
<?php foreach ( $product_ids as $product_id ) : ?>
<?php list( , $label ) = explode( ':', $product_id, 2 ); ?>
<option value="<?php echo esc_attr( $product_id ); ?>">
<?php
echo esc_html( $label );
?>
</option>
<?php endforeach; ?>
</select>
</label>
</div>
</fieldset>
<?php
}
/**
* Saves the custom field value from the bulk edit form.
*
* @since 1.148.0
*
* @param int $post_id Post ID.
*/
public function save_field( $post_id ) {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
if ( ! isset( $_REQUEST['_wpnonce'] ) ) {
return;
}
$nonce = sanitize_key( wp_unslash( $_REQUEST['_wpnonce'] ) );
if ( ! wp_verify_nonce( $nonce, 'bulk-posts' ) ) {
return;
}
if ( isset( $_REQUEST['rrm_product_id'] ) && '-1' !== $_REQUEST['rrm_product_id'] ) {
$post_product_id = sanitize_text_field(
wp_unslash( $_REQUEST['rrm_product_id'] )
);
$this->post_product_id->set(
$post_id,
$post_product_id
);
}
}
/**
* Retrieves the public post types that support the block editor.
*
* @since 1.148.0
*
* @return array Array of post types.
*/
protected function get_post_types() {
$post_types = get_post_types( array( 'public' => true ), 'objects' );
$supported_post_types = array();
foreach ( $post_types as $post_type => $post_type_obj ) {
if (
post_type_supports( $post_type, 'editor' ) &&
! empty( $post_type_obj->show_in_rest )
) {
$supported_post_types[] = $post_type;
}
}
return $supported_post_types;
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Contribute_With_Google_Block
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Context;
use Google\Site_Kit\Core\Modules\Module_Settings;
use Google\Site_Kit\Modules\Reader_Revenue_Manager\Tag_Guard;
/**
* Contribute with Google Gutenberg block.
*
* @since 1.148.0
* @access private
* @ignore
*/
class Contribute_With_Google_Block {
/**
* Context instance.
*
* @since 1.148.0
*
* @var Context
*/
protected $context;
/**
* Tag_Guard instance.
*
* @since 1.148.0
*
* @var Tag_Guard
*/
private $tag_guard;
/**
* Settings instance.
*
* @since 1.148.0
*
* @var Module_Settings
*/
private $settings;
/**
* Constructor.
*
* @since 1.148.0
*
* @param Context $context Plugin context.
* @param Tag_Guard $tag_guard Tag_Guard instance.
* @param Module_Settings $settings Module_Settings instance.
*/
public function __construct( Context $context, Tag_Guard $tag_guard, Module_Settings $settings ) {
$this->context = $context;
$this->tag_guard = $tag_guard;
$this->settings = $settings;
}
/**
* Register this block.
*
* @since 1.148.0
*/
public function register() {
add_action(
'init',
function () {
register_block_type(
dirname( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) . '/dist/assets/blocks/reader-revenue-manager/contribute-with-google/block.json',
array(
'render_callback' => array( $this, 'render_callback' ),
)
);
},
99
);
}
/**
* Render callback for the block.
*
* @since 1.148.0
*
* @return string Rendered block.
*/
public function render_callback() {
// If the payment option is not `contributions` or the tag is not placed, do not render the block.
$settings = $this->settings->get();
$is_contributions_payment_option = isset( $settings['paymentOption'] ) && 'contributions' === $settings['paymentOption'];
if ( ! ( $is_contributions_payment_option && $this->tag_guard->can_activate() ) ) {
return '';
}
// Ensure the button is centered to match the editor preview.
// TODO: Add a stylesheet to the page and style the button container using a class.
return '<div style="margin: 0 auto;"><button swg-standard-button="contribution"></button></div>';
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Core\Storage\Meta_Setting_Trait;
use Google\Site_Kit\Core\Storage\Post_Meta;
use Google\Site_Kit\Modules\Reader_Revenue_Manager\Settings;
/**
* Class for associating product ID to post meta.
*
* @since 1.145.0
* @access private
* @ignore
*/
class Post_Product_ID {
use Meta_Setting_Trait;
/**
* Settings instance.
*
* @since 1.148.0
*
* @var Settings
*/
private $settings;
/**
* Post_Product_ID constructor.
*
* @since 1.145.0
*
* @param Post_Meta $post_meta Post_Meta instance.
* @param Settings $settings Reader Revenue Manager module settings instance.
*/
public function __construct( Post_Meta $post_meta, Settings $settings ) {
$this->meta = $post_meta;
$this->settings = $settings;
}
/**
* Gets the meta key for the setting.
*
* @since 1.145.0
*
* @return string Meta key.
*/
protected function get_meta_key(): string {
$publication_id = $this->settings->get()['publicationID'];
return 'googlesitekit_rrm_' . $publication_id . ':productID';
}
/**
* Returns the object type.
*
* @since 1.146.0
*
* @return string Object type.
*/
protected function get_object_type(): string {
return 'post';
}
/**
* Gets the `show_in_rest` value for this postmeta setting value.
*
* @since 1.145.0
*
* @return bool|Array Any valid value for the `show_in_rest`
*/
protected function get_show_in_rest() {
return true;
}
}

View File

@@ -0,0 +1,189 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Settings
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2021 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Core\Modules\Module_Settings;
use Google\Site_Kit\Core\Storage\Setting_With_Owned_Keys_Interface;
use Google\Site_Kit\Core\Storage\Setting_With_Owned_Keys_Trait;
use Google\Site_Kit\Core\Storage\Setting_With_ViewOnly_Keys_Interface;
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;
/**
* Class for RRM settings.
*
* @since 1.132.0
* @access private
* @ignore
*/
class Settings extends Module_Settings implements Setting_With_Owned_Keys_Interface, Setting_With_ViewOnly_Keys_Interface {
use Setting_With_Owned_Keys_Trait;
use Method_Proxy_Trait;
const OPTION = 'googlesitekit_reader-revenue-manager_settings';
/**
* Various Reader Revenue Manager onboarding statuses.
*/
const ONBOARDING_STATE_UNSPECIFIED = 'ONBOARDING_STATE_UNSPECIFIED';
const ONBOARDING_STATE_ACTION_REQUIRED = 'ONBOARDING_ACTION_REQUIRED';
const ONBOARDING_STATE_PENDING_VERIFICATION = 'PENDING_VERIFICATION';
const ONBOARDING_STATE_COMPLETE = 'ONBOARDING_COMPLETE';
/**
* Registers the setting in WordPress.
*
* @since 1.132.0
*/
public function register() {
parent::register();
$this->register_owned_keys();
}
/**
* Returns keys for owned settings.
*
* @since 1.132.0
*
* @return array An array of keys for owned settings.
*/
public function get_owned_keys() {
return array( 'publicationID' );
}
/**
* Gets the default value.
*
* @since 1.132.0
*
* @return array
*/
protected function get_default() {
$defaults = array(
'ownerID' => 0,
'publicationID' => '',
'publicationOnboardingState' => '',
'publicationOnboardingStateChanged' => false,
'productIDs' => array(),
'paymentOption' => '',
'snippetMode' => 'post_types',
'postTypes' => array( 'post' ),
'productID' => 'openaccess',
);
return $defaults;
}
/**
* Returns keys for view-only settings.
*
* @since 1.132.0
*
* @return array An array of keys for view-only settings.
*/
public function get_view_only_keys() {
$keys = array(
'publicationID',
'snippetMode',
'postTypes',
'paymentOption',
);
return $keys;
}
/**
* Gets the callback for sanitizing the setting's value before saving.
*
* @since 1.132.0
*
* @return callable|null
*/
protected function get_sanitize_callback() {
return function ( $option ) {
if ( isset( $option['publicationID'] ) ) {
if ( ! preg_match( '/^[a-zA-Z0-9_-]+$/', $option['publicationID'] ) ) {
$option['publicationID'] = '';
}
}
if ( isset( $option['publicationOnboardingStateChanged'] ) ) {
if ( ! is_bool( $option['publicationOnboardingStateChanged'] ) ) {
$option['publicationOnboardingStateChanged'] = false;
}
}
if ( isset( $option['publicationOnboardingState'] ) ) {
$valid_onboarding_states = array(
self::ONBOARDING_STATE_UNSPECIFIED,
self::ONBOARDING_STATE_ACTION_REQUIRED,
self::ONBOARDING_STATE_PENDING_VERIFICATION,
self::ONBOARDING_STATE_COMPLETE,
);
if ( ! in_array( $option['publicationOnboardingState'], $valid_onboarding_states, true ) ) {
$option['publicationOnboardingState'] = '';
}
}
if ( isset( $option['productIDs'] ) ) {
if ( ! is_array( $option['productIDs'] ) ) {
$option['productIDs'] = array();
} else {
$option['productIDs'] = array_values(
array_filter(
$option['productIDs'],
'is_string'
)
);
}
}
if ( isset( $option['paymentOption'] ) ) {
if ( ! is_string( $option['paymentOption'] ) ) {
$option['paymentOption'] = '';
}
}
if ( isset( $option['snippetMode'] ) ) {
$valid_snippet_modes = array( 'post_types', 'per_post', 'sitewide' );
if ( ! in_array( $option['snippetMode'], $valid_snippet_modes, true ) ) {
$option['snippetMode'] = 'post_types';
}
}
if ( isset( $option['postTypes'] ) ) {
if ( ! is_array( $option['postTypes'] ) ) {
$option['postTypes'] = array( 'post' );
} else {
$filtered_post_types = array_values(
array_filter(
$option['postTypes'],
'is_string'
)
);
$option['postTypes'] = ! empty( $filtered_post_types )
? $filtered_post_types
: array( 'post' );
}
}
if ( isset( $option['productID'] ) ) {
if ( ! is_string( $option['productID'] ) ) {
$option['productID'] = 'openaccess';
}
}
return $option;
};
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Subscribe_With_Google_Block
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Context;
use Google\Site_Kit\Core\Modules\Module_Settings;
use Google\Site_Kit\Modules\Reader_Revenue_Manager\Tag_Guard;
/**
* Subscribe with Google Gutenberg block.
*
* @since 1.148.0
* @access private
* @ignore
*/
class Subscribe_With_Google_Block {
/**
* Context instance.
*
* @since 1.148.0
*
* @var Context
*/
protected $context;
/**
* Tag_Guard instance.
*
* @since 1.148.0
*
* @var Tag_Guard
*/
private $tag_guard;
/**
* Settings instance.
*
* @since 1.148.0
*
* @var Module_Settings
*/
private $settings;
/**
* Constructor.
*
* @since 1.148.0
*
* @param Context $context Plugin context.
* @param Tag_Guard $tag_guard Tag_Guard instance.
* @param Module_Settings $settings Module_Settings instance.
*/
public function __construct( Context $context, Tag_Guard $tag_guard, Module_Settings $settings ) {
$this->context = $context;
$this->tag_guard = $tag_guard;
$this->settings = $settings;
}
/**
* Register this block.
*
* @since 1.148.0
*/
public function register() {
add_action(
'init',
function () {
register_block_type(
dirname( GOOGLESITEKIT_PLUGIN_MAIN_FILE ) . '/dist/assets/blocks/reader-revenue-manager/subscribe-with-google/block.json',
array(
'render_callback' => array( $this, 'render_callback' ),
)
);
},
99
);
}
/**
* Render callback for the block.
*
* @since 1.148.0
*
* @return string Rendered block.
*/
public function render_callback() {
// If the payment option is not `subscriptions` or the tag is not placed, do not render the block.
$settings = $this->settings->get();
$is_subscriptions_payment_option = isset( $settings['paymentOption'] ) && 'subscriptions' === $settings['paymentOption'];
if ( ! ( $is_subscriptions_payment_option && $this->tag_guard->can_activate() ) ) {
return '';
}
// Ensure the button is centered to match the editor preview.
// TODO: Add a stylesheet to the page and style the button container using a class.
return '<div style="margin: 0 auto;"><button swg-standard-button="subscription"></button></div>';
}
}

View File

@@ -0,0 +1,204 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Synchronize_Publication
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2025 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Core\Permissions\Permissions;
use Google\Site_Kit\Core\Storage\User_Options;
use Google\Site_Kit\Core\Util\Feature_Flags;
use Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit_Dependencies\Google\Service\SubscribewithGoogle\Publication;
use Google\Site_Kit_Dependencies\Google\Service\SubscribewithGoogle\PaymentOptions;
/**
* Class for synchronizing the onboarding state.
*
* @since 1.146.0
* @access private
* @ignore
*/
class Synchronize_Publication {
/**
* Cron event name for synchronizing the publication info.
*/
const CRON_SYNCHRONIZE_PUBLICATION = 'googlesitekit_cron_synchronize_publication';
/**
* Reader_Revenue_Manager instance.
*
* @var Reader_Revenue_Manager
*/
protected $reader_revenue_manager;
/**
* User_Options instance.
*
* @var User_Options
*/
protected $user_options;
/**
* Constructor.
*
* @since 1.146.0
*
* @param Reader_Revenue_Manager $reader_revenue_manager Reader Revenue Manager instance.
* @param User_Options $user_options User_Options instance.
*/
public function __construct( Reader_Revenue_Manager $reader_revenue_manager, User_Options $user_options ) {
$this->reader_revenue_manager = $reader_revenue_manager;
$this->user_options = $user_options;
}
/**
* Registers functionality through WordPress hooks.
*
* @since 1.146.0
*
* @return void
*/
public function register() {
add_action(
self::CRON_SYNCHRONIZE_PUBLICATION,
function () {
$this->synchronize_publication_data();
}
);
}
/**
* Cron callback for synchronizing the publication.
*
* @since 1.146.0
*
* @return void
*/
protected function synchronize_publication_data() {
$owner_id = $this->reader_revenue_manager->get_owner_id();
$restore_user = $this->user_options->switch_user( $owner_id );
if ( user_can( $owner_id, Permissions::VIEW_AUTHENTICATED_DASHBOARD ) ) {
$connected = $this->reader_revenue_manager->is_connected();
// If not connected, return early.
if ( ! $connected ) {
return;
}
$publications = $this->reader_revenue_manager->get_data( 'publications' );
// If publications is empty, return early.
if ( empty( $publications ) ) {
return;
}
$settings = $this->reader_revenue_manager->get_settings()->get();
$publication_id = $settings['publicationID'];
$filtered_publications = array_filter(
$publications,
function ( $pub ) use ( $publication_id ) {
return $pub->getPublicationId() === $publication_id;
}
);
// If there are no filtered publications, return early.
if ( empty( $filtered_publications ) ) {
return;
}
// Re-index the filtered array to ensure sequential keys.
$filtered_publications = array_values( $filtered_publications );
$publication = $filtered_publications[0];
$onboarding_state = $settings['publicationOnboardingState'];
$new_onboarding_state = $publication->getOnboardingState();
$new_settings = array(
'publicationOnboardingState' => $new_onboarding_state,
'productIDs' => $this->get_product_ids( $publication ),
'paymentOption' => $this->get_payment_option( $publication ),
);
// Let the client know if the onboarding state has changed.
if ( $new_onboarding_state !== $onboarding_state ) {
$new_settings['publicationOnboardingStateChanged'] = true;
}
$this->reader_revenue_manager->get_settings()->merge( $new_settings );
}
$restore_user();
}
/**
* Returns the products IDs for the given publication.
*
* @since 1.146.0
*
* @param Publication $publication Publication object.
* @return array Product IDs.
*/
protected function get_product_ids( Publication $publication ) {
$products = $publication->getProducts();
$product_ids = array();
if ( ! empty( $products ) ) {
foreach ( $products as $product ) {
$product_ids[] = $product->getName();
}
}
return $product_ids;
}
/**
* Returns the payment option for the given publication.
*
* @since 1.146.0
*
* @param Publication $publication Publication object.
* @return string Payment option.
*/
protected function get_payment_option( Publication $publication ) {
$payment_options = $publication->getPaymentOptions();
$payment_option = '';
if ( $payment_options instanceof PaymentOptions ) {
foreach ( $payment_options as $option => $value ) {
if ( true === $value ) {
$payment_option = $option;
break;
}
}
}
return $payment_option;
}
/**
* Maybe schedule the synchronize onboarding state cron event.
*
* @since 1.146.0
*
* @return void
*/
public function maybe_schedule_synchronize_publication() {
$connected = $this->reader_revenue_manager->is_connected();
$cron_already_scheduled = wp_next_scheduled( self::CRON_SYNCHRONIZE_PUBLICATION );
if ( $connected && ! $cron_already_scheduled ) {
wp_schedule_single_event(
time() + HOUR_IN_SECONDS,
self::CRON_SYNCHRONIZE_PUBLICATION
);
}
}
}

View File

@@ -0,0 +1,117 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Tag_Guard
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2024 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Core\Modules\Module_Settings;
use Google\Site_Kit\Core\Modules\Tags\Module_Tag_Guard;
use Google\Site_Kit\Modules\Reader_Revenue_Manager\Post_Product_ID;
/**
* Class for the Reader Revenue Manager tag guard.
*
* @since 1.132.0
* @access private
* @ignore
*/
class Tag_Guard extends Module_Tag_Guard {
/**
* Post_Product_ID instance.
*
* @since 1.148.0
*
* @var Post_Product_ID
*/
private $post_product_id;
/**
* Constructor.
*
* @since 1.148.0
*
* @param Module_Settings $settings Module settings instance.
* @param Post_Product_ID $post_product_id Post_Product_ID instance.
*/
public function __construct( Module_Settings $settings, $post_product_id ) {
parent::__construct( $settings );
$this->post_product_id = $post_product_id;
}
/**
* Determines whether the guarded tag can be activated or not.
*
* @since 1.132.0
*
* @return bool|WP_Error TRUE if guarded tag can be activated, otherwise FALSE or an error.
*/
public function can_activate() {
$settings = $this->settings->get();
if ( empty( $settings['publicationID'] ) ) {
return false;
}
if ( is_singular() ) {
return $this->can_activate_for_singular_post();
}
return 'sitewide' === $settings['snippetMode'];
}
/**
* Determines whether the guarded tag can be activated for a singular post or not.
*
* @since 1.148.0
*
* @return bool TRUE if guarded tag can be activated for a singular post, otherwise FALSE.
*/
private function can_activate_for_singular_post() {
$post_product_id = $this->post_product_id->get( get_the_ID() );
if ( 'none' === $post_product_id ) {
return false;
}
if ( ! empty( $post_product_id ) ) {
return true;
}
$settings = $this->settings->get();
// If the snippet mode is `per_post` and there is no post product ID,
// we don't want to render the tag.
if ( 'per_post' === $settings['snippetMode'] ) {
return false;
}
// If the snippet mode is `post_types`, we only want to render the tag
// if the current post type is in the list of allowed post types.
if ( 'post_types' === $settings['snippetMode'] ) {
/**
* Filters the post types where Reader Revenue Manager CTAs should appear.
*
* @since 1.140.0
*
* @param array $cta_post_types The array of post types.
*/
$cta_post_types = apply_filters(
'googlesitekit_reader_revenue_manager_cta_post_types',
$settings['postTypes']
);
return in_array( get_post_type(), $cta_post_types, true );
}
// Snippet mode is `sitewide` at this point, so we want to render the tag.
return true;
}
}

View File

@@ -0,0 +1,38 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Tag_Matchers
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2024 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Core\Modules\Tags\Module_Tag_Matchers;
use Google\Site_Kit\Core\Tags\Tag_Matchers_Interface;
/**
* Class for Tag matchers.
*
* @since 1.132.0
* @access private
* @ignore
*/
class Tag_Matchers extends Module_Tag_Matchers implements Tag_Matchers_Interface {
/**
* Holds array of regex tag matchers.
*
* @since 1.132.0
*
* @return array Array of regex matchers.
*/
public function regex_matchers() {
return array(
"/<script\s+[^>]*src=['|\"]https?:\/\/news\.google\.com\/swg\/js\/v1\/swg-basic\.js['|\"][^>]*>/",
'/\(self\.SWG_BASIC=self\.SWG_BASIC\|\|\[\]\)\.push/',
);
}
}

View File

@@ -0,0 +1,152 @@
<?php
/**
* Class Google\Site_Kit\Modules\Reader_Revenue_Manager\Web_Tag
*
* @package Google\Site_Kit\Modules\Reader_Revenue_Manager
* @copyright 2024 Google LLC
* @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
* @link https://sitekit.withgoogle.com
*/
namespace Google\Site_Kit\Modules\Reader_Revenue_Manager;
use Google\Site_Kit\Core\Modules\Tags\Module_Web_Tag;
use Google\Site_Kit\Core\Tags\Tag_With_DNS_Prefetch_Trait;
use Google\Site_Kit\Core\Util\Method_Proxy_Trait;
/**
* Class for Web tag.
*
* @since 1.132.0
* @access private
* @ignore
*/
class Web_Tag extends Module_Web_Tag {
use Method_Proxy_Trait;
use Tag_With_DNS_Prefetch_Trait;
/**
* Product ID.
*
* @since 1.148.0
*
* @var string
*/
private $product_id;
/**
* Sets the product ID.
*
* @since 1.148.0
*
* @param string $product_id Product ID.
*/
public function set_product_id( $product_id ) {
$this->product_id = $product_id;
}
/**
* Registers tag hooks.
*
* @since 1.132.0
*/
public function register() {
add_action( 'wp_enqueue_scripts', $this->get_method_proxy( 'enqueue_swg_script' ) );
add_filter(
'script_loader_tag',
$this->get_method_proxy( 'add_snippet_comments' ),
10,
2
);
add_filter(
'wp_resource_hints',
$this->get_dns_prefetch_hints_callback( '//news.google.com' ),
10,
2
);
$this->do_init_tag_action();
}
/**
* Enqueues the Reader Revenue Manager (SWG) script.
*
* @since 1.132.0
* @since 1.140.0 Updated to enqueue the script only on singular posts.
*/
protected function enqueue_swg_script() {
$locale = str_replace( '_', '-', get_locale() );
/**
* Filters the Reader Revenue Manager product ID.
*
* @since 1.148.0
*
* @param string $product_id The array of post types.
*/
$product_id = apply_filters(
'googlesitekit_reader_revenue_manager_product_id',
$this->product_id
);
$subscription = array(
'type' => 'NewsArticle',
'isPartOfType' => array( 'Product' ),
'isPartOfProductId' => $this->tag_id . ':' . $product_id,
'clientOptions' => array(
'theme' => 'light',
'lang' => $locale,
),
);
$json_encoded_subscription = wp_json_encode( $subscription );
if ( ! $json_encoded_subscription ) {
$json_encoded_subscription = 'null';
}
$swg_inline_script = sprintf(
'(self.SWG_BASIC=self.SWG_BASIC||[]).push(basicSubscriptions=>{basicSubscriptions.init(%s);});',
$json_encoded_subscription
);
// phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion
wp_register_script( 'google_swgjs', 'https://news.google.com/swg/js/v1/swg-basic.js', array(), null, true );
wp_script_add_data( 'google_swgjs', 'strategy', 'async' );
wp_add_inline_script( 'google_swgjs', $swg_inline_script, 'before' );
wp_enqueue_script( 'google_swgjs' );
}
/**
* Add snippet comments around the tag.
*
* @since 1.132.0
*
* @param string $tag The tag.
* @param string $handle The script handle.
*
* @return string The tag with snippet comments.
*/
protected function add_snippet_comments( $tag, $handle ) {
if ( 'google_swgjs' !== $handle ) {
return $tag;
}
$before = sprintf( "\n<!-- %s -->\n", esc_html__( 'Google Reader Revenue Manager snippet added by Site Kit', 'google-site-kit' ) );
$after = sprintf( "\n<!-- %s -->\n", esc_html__( 'End Google Reader Revenue Manager snippet added by Site Kit', 'google-site-kit' ) );
return $before . $tag . $after;
}
/**
* Outputs snippet.
*
* @since 1.132.0
*/
protected function render() {
// Do nothing, script is enqueued.
}
}