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,391 @@
<?php
/**
* IndexNow API
*
* @since 1.0.56
* @package RankMath
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Instant_Indexing;
use RankMath\Helper;
use RankMath\Traits\Hooker;
defined( 'ABSPATH' ) || exit;
/**
* API class.
*
* @codeCoverageIgnore
*/
class Api {
use Hooker;
/**
* IndexNow API URL.
*
* @var string
*/
private $api_url = 'https://api.indexnow.org/indexnow/';
/**
* IndexNow API key.
*
* @var string
*/
protected $api_key = '';
/**
* Was the last request successful.
*
* @var bool
*/
protected $is_success = false;
/**
* Last error.
*
* @var string
*/
protected $last_error = '';
/**
* Last response.
*
* @var array
*/
protected $last_response = '';
/**
* Last response header code.
*
* @var int
*/
protected $last_code = 0;
/**
* Next submission is a manual submission.
*
* @var bool
*/
public $is_manual = true;
/**
* User agent used for the API requests.
*
* @var string
*/
protected $user_agent = '';
/**
* User agent used for the API requests.
*
* @var string
*/
protected $version = '';
/**
* Main instance
*
* Ensure only one instance is loaded or can be loaded.
*
* @return Api
*/
public static function get() {
static $instance;
if ( is_null( $instance ) && ! ( $instance instanceof Api ) ) {
$instance = new Api();
$instance->user_agent = 'RankMath/' . md5( esc_url( home_url( '/' ) ) );
$instance->version = rank_math()->version;
}
return $instance;
}
/**
* Make request to the IndexNow API.
*
* @param array $urls URLs to submit.
* @param bool $manual Whether the request is manual or not.
*
* @return bool
*/
public function submit( $urls, $manual = null ) {
$this->reset();
if ( ! is_null( $manual ) ) {
$this->is_manual = (bool) $manual;
}
$data = $this->get_payload( $urls );
$response = wp_remote_post(
'https://api.indexnow.org/indexnow/',
[
'body' => $data,
'headers' => [
'Content-Type' => 'application/json',
'User-Agent' => $this->user_agent,
'X-Source-Info' => 'https://rankmath.com/' . $this->version . '/' . ( $this->is_manual ? '1' : '' ),
],
]
);
if ( is_wp_error( $response ) ) {
$this->last_error = 'WP_Error: ' . $response->get_error_message();
$this->log( (array) $urls, 0, $this->last_error );
return false;
}
$this->last_code = wp_remote_retrieve_response_code( $response );
$this->last_response = wp_remote_retrieve_body( $response );
if ( in_array( $this->last_code, [ 200, 202, 204 ], true ) ) {
$this->is_success = true;
$this->log( (array) $urls, $this->last_code, 'OK' );
return true;
}
$message = wp_remote_retrieve_response_message( $response );
$this->set_error_message( $message );
$this->log( (array) $urls, $this->last_code, $this->last_error );
return false;
}
/**
* Get the last error message.
*
* @return string
*/
public function get_error() {
return $this->last_error;
}
/**
* Get the last response code.
*
* @return int
*/
public function get_response_code() {
return $this->last_code;
}
/**
* Get the last response.
*
* @return string
*/
public function get_response() {
return $this->last_response;
}
/**
* Get the host parameter value to send to the API.
*
* @return string
*/
public function get_host() {
$host = wp_parse_url( home_url(), PHP_URL_HOST );
if ( empty( $host ) ) {
$host = 'localhost';
}
/**
* Filter the host parameter value to send to the API.
*
* @param string $host Host.
*/
return $this->do_filter( 'instant_indexing/indexnow_host', $host );
}
/**
* Get the API key.
*
* @return string
*/
public function get_key() {
if ( ! empty( $this->api_key ) ) {
return $this->api_key;
}
$api_key = Helper::get_settings( 'instant_indexing.indexnow_api_key' );
/**
* Filter the API key.
*
* @param string $api_key API key.
*/
$this->api_key = $this->do_filter( 'instant_indexing/indexnow_key', $api_key );
return $this->api_key;
}
/**
* Alias for get_key().
*/
public function get_api_key() {
return $this->get_key();
}
/**
* Get the API key location.
*
* @param string $context Key context.
* @return string
*/
public function get_key_location( $context = '' ) {
/**
* Filter the API key location.
*
* @param string $location Location.
*/
return $this->do_filter( 'instant_indexing/indexnow_key_location', trailingslashit( home_url() ) . $this->get_key() . '.txt', $context );
}
/**
* Log the request.
*
* @param array $urls URLs to submit.
* @param int $status Response code.
* @param string $message Response message.
*/
public function log( $urls, $status, $message = '' ) {
$log = get_option( 'rank_math_indexnow_log', [] );
$url = $this->get_loggable_url( $urls );
if ( ! $url ) {
return;
}
$log[] = [
'url' => $url,
'status' => (int) $status,
'manual_submission' => (bool) $this->is_manual,
'message' => $message,
'time' => time(),
];
// Only keep the last 100 entries.
$log = array_slice( $log, -100 );
update_option( 'rank_math_indexnow_log', $log, false );
}
/**
* Get the loggable URL from an array of URLs.
* If multiple URLs are submitted, return the first one and [+12]
*
* @param array $urls URLs to submit.
*
* @return string
*/
public function get_loggable_url( $urls ) {
$urls = array_values( (array) $urls );
$count_urls = count( $urls );
if ( ! $count_urls ) {
return '';
}
$url = $urls[0];
if ( $count_urls > 1 ) {
$url .= ' [+' . ( $count_urls - 1 ) . ']';
}
return $url;
}
/**
* Get the log.
*
* @return array
*/
public function get_log() {
return get_option( 'rank_math_indexnow_log', [] );
}
/**
* Clear the log.
*/
public function clear_log() {
delete_option( 'rank_math_indexnow_log' );
}
/**
* Reset object properties.
*/
private function reset() {
$this->last_error = '';
$this->last_code = 0;
$this->last_response = '';
$this->is_success = false;
}
/**
* Get the additional data to send to the API.
*
* @param array $urls URLs to submit.
*
* @return array
*/
private function get_payload( $urls ) {
return wp_json_encode(
[
'host' => $this->get_host(),
'key' => $this->get_key(),
'keyLocation' => $this->get_key_location( 'request_payload' ),
'urlList' => (array) $urls,
]
);
}
/**
* Get the error message from the response message.
*
* @param string $message Response message.
*/
private function set_error_message( $message ) {
if ( ! empty( $message ) ) {
$this->last_error = $message;
return;
}
$message = __( 'Unknown error.', 'rank-math' );
$message_map = [
400 => __( 'Invalid request.', 'rank-math' ),
403 => __( 'Invalid API key.', 'rank-math' ),
422 => __( 'Invalid URL.', 'rank-math' ),
429 => __( 'Too many requests.', 'rank-math' ),
500 => __( 'Internal server error.', 'rank-math' ),
];
if ( isset( $message_map[ $this->last_code ] ) ) {
$message = $message_map[ $this->last_code ];
}
$this->last_error = $message;
}
/**
* Generate and save a new API key.
*/
public function reset_key() {
$settings = Helper::get_settings( 'instant_indexing', [] );
$settings['indexnow_api_key'] = $this->generate_api_key();
$this->api_key = $settings['indexnow_api_key'];
update_option( 'rank-math-options-instant-indexing', $settings );
}
/**
* Generate new random API key.
*/
private function generate_api_key() {
$api_key = wp_generate_uuid4();
$api_key = preg_replace( '[-]', '', $api_key );
return $api_key;
}
}

View File

@@ -0,0 +1,450 @@
<?php
/**
* Instant Indexing module.
*
* @since 1.0.56
* @package RankMath
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Instant_Indexing;
use RankMath\KB;
use RankMath\Helper;
use RankMath\Module\Base;
use RankMath\Traits\Hooker;
use RankMath\Traits\Ajax;
use RankMath\Admin\Options;
use RankMath\Admin\Register_Options_Page;
use RankMath\Helpers\Param;
use RankMath\Helpers\Sitepress;
defined( 'ABSPATH' ) || exit;
/**
* Instant_Indexing class.
*/
class Instant_Indexing extends Base {
use Hooker;
use Ajax;
/**
* API Object.
*
* @var string
*/
private $api;
/**
* Keep log of submitted objects to avoid double submissions.
*
* @var array
*/
private $submitted = [];
/**
* Store previous post status that we can check agains in save_post.
*
* @var array
*/
private $previous_post_status = [];
/**
* Store original permalinks for when they get trashed.
*
* @var array
*/
private $previous_post_permalinks = [];
/**
* Restrict to one request every X seconds to a given URL.
*/
const THROTTLE_LIMIT = 5;
/**
* Constructor.
*/
public function __construct() {
parent::__construct();
if ( ! $this->is_configured() ) {
Api::get()->reset_key();
}
$this->action( 'init', 'register_instant_indexing_settings', 125 );
$post_types = $this->get_auto_submit_post_types();
if ( ! empty( $post_types ) ) {
$this->filter( 'wp_insert_post_data', 'before_save_post', 10, 4 );
}
foreach ( $post_types as $post_type ) {
$this->action( 'save_post_' . $post_type, 'save_post', 10, 3 );
$this->filter( "bulk_actions-edit-{$post_type}", 'post_bulk_actions', 11 );
$this->filter( "handle_bulk_actions-edit-{$post_type}", 'handle_post_bulk_actions', 10, 3 );
}
$this->filter( 'post_row_actions', 'post_row_actions', 10, 2 );
$this->filter( 'page_row_actions', 'post_row_actions', 10, 2 );
$this->filter( 'admin_init', 'handle_post_row_actions' );
$this->action( 'wp', 'serve_api_key' );
$this->action( 'rest_api_init', 'init_rest_api' );
}
/**
* Load the REST API endpoints.
*/
public function init_rest_api() {
$rest = new Rest();
$rest->register_routes();
}
/**
* Add bulk actions for applicable posts, pages, CPTs.
*
* @param array $actions Actions.
* @return array New actions.
*/
public function post_bulk_actions( $actions ) {
$actions['rank_math_indexnow'] = esc_html__( 'Instant Indexing: Submit Pages', 'rank-math' );
return $actions;
}
/**
* Action links for the post listing screens.
*
* @param array $actions Action links.
* @param object $post Current post object.
* @return array
*/
public function post_row_actions( $actions, $post ) {
if ( ! Helper::has_cap( 'general' ) ) {
return $actions;
}
if ( 'publish' !== $post->post_status ) {
return $actions;
}
$post_types = $this->get_auto_submit_post_types();
if ( ! in_array( $post->post_type, $post_types, true ) ) {
return $actions;
}
$link = wp_nonce_url(
add_query_arg(
[
'action' => 'rank_math_instant_index_post',
'index_post_id' => $post->ID,
'method' => 'bing_submit',
]
),
'rank_math_instant_index_post'
);
$actions['indexnow_submit'] = '<a href="' . esc_url( $link ) . '" class="rm-instant-indexing-action rm-indexnow-submit">' . __( 'Instant Indexing: Submit Page', 'rank-math' ) . '</a>';
return $actions;
}
/**
* Handle post row action link actions.
*
* @return void
*/
public function handle_post_row_actions() {
if ( 'rank_math_instant_index_post' !== Param::get( 'action' ) ) {
return;
}
$post_id = absint( Param::get( 'index_post_id' ) );
if ( ! $post_id ) {
return;
}
if ( ! wp_verify_nonce( Param::get( '_wpnonce' ), 'rank_math_instant_index_post' ) ) {
return;
}
if ( ! Helper::has_cap( 'general' ) ) {
return;
}
$this->api_submit( get_permalink( $post_id ), true );
Helper::redirect( remove_query_arg( [ 'action', 'index_post_id', 'method', '_wpnonce' ] ) );
exit;
}
/**
* Handle bulk actions for applicable posts, pages, CPTs.
*
* @param string $redirect Redirect URL.
* @param string $doaction Performed action.
* @param array $object_ids Post IDs.
*
* @return string New redirect URL.
*/
public function handle_post_bulk_actions( $redirect, $doaction, $object_ids ) {
if ( 'rank_math_indexnow' !== $doaction || empty( $object_ids ) ) {
return $redirect;
}
if ( ! Helper::has_cap( 'general' ) ) {
return $redirect;
}
$urls = [];
foreach ( $object_ids as $object_id ) {
$urls[] = get_permalink( $object_id );
}
$this->api_submit( $urls, true );
return $redirect;
}
/**
* Register admin page.
*/
public function register_instant_indexing_settings() {
$tabs = [
'url-submission' => [
'icon' => 'rm-icon rm-icon-instant-indexing',
'title' => esc_html__( 'Submit URLs', 'rank-math' ),
'desc' => esc_html__( 'Send URLs directly to the IndexNow API.', 'rank-math' ) . ' <a href="' . KB::get( 'instant-indexing', 'Indexing Submit URLs' ) . '" target="_blank">' . esc_html__( 'Learn more', 'rank-math' ) . '</a>',
'classes' => 'rank-math-advanced-option',
'file' => __DIR__ . '/views/console.php',
],
'settings' => [
'icon' => 'rm-icon rm-icon-settings',
'title' => esc_html__( 'Settings', 'rank-math' ),
/* translators: Link to kb article */
'desc' => sprintf( esc_html__( 'Instant Indexing module settings. %s.', 'rank-math' ), '<a href="' . KB::get( 'instant-indexing', 'Indexing Settings' ) . '" target="_blank">' . esc_html__( 'Learn more', 'rank-math' ) . '</a>' ),
'file' => __DIR__ . '/views/options.php',
],
'history' => [
'icon' => 'rm-icon rm-icon-htaccess',
'title' => esc_html__( 'History', 'rank-math' ),
'desc' => esc_html__( 'The last 100 IndexNow API requests.', 'rank-math' ),
'classes' => 'rank-math-advanced-option',
'file' => __DIR__ . '/views/history.php',
],
];
if ( 'easy' === Helper::get_settings( 'general.setup_mode', 'advanced' ) ) {
// Move ['settings'] to the top.
$tabs = [ 'settings' => $tabs['settings'] ] + $tabs;
}
/**
* Allow developers to add new sections in the IndexNow settings.
*
* @param array $tabs
*/
$tabs = $this->do_filter( 'settings/instant_indexing', $tabs );
new Register_Options_Page(
[
'key' => 'rank-math-options-instant-indexing',
'title' => esc_html__( 'Instant Indexing', 'rank-math' ),
'menu_title' => esc_html__( 'Instant Indexing', 'rank-math' ),
'capability' => 'rank_math_general',
'tabs' => $tabs,
'position' => 11,
]
);
}
/**
* Store previous post status & permalink before saving the post.
*
* @param array $data Post data.
* @param array $postarr Raw post data.
* @param array $unsanitized_postarr Unsanitized post data.
* @param bool $update Whether this is an existing post being updated or not.
*/
public function before_save_post( $data, $postarr, $unsanitized_postarr, $update = false ) {
if ( ! $update ) {
return $data;
}
$this->previous_post_status[ $postarr['ID'] ] = get_post_status( $postarr['ID'] );
$this->previous_post_permalinks[ $postarr['ID'] ] = str_replace( '__trashed', '', get_permalink( $postarr['ID'] ) );
return $data;
}
/**
* When a post from a watched post type is published or updated, submit its URL
* to the API and add notice about it.
*
* @param int $post_id Post ID.
* @param object $post Post object.
*
* @return void
*/
public function save_post( $post_id, $post ) {
// Check if already submitted.
if ( in_array( $post_id, $this->submitted, true ) ) {
return;
}
// Check if post status changed to publish or trash.
if ( ! in_array( $post->post_status, [ 'publish', 'trash' ], true ) ) {
return;
}
// If new status is trash, check if previous status was publish.
if ( 'trash' === $post->post_status && 'publish' !== $this->previous_post_status[ $post_id ] ) {
return;
}
if ( wp_is_post_revision( $post_id ) || wp_is_post_autosave( $post_id ) || ! empty( Helper::get_post_meta( 'lock_modified_date', $post_id ) ) ) {
return;
}
if ( ! Helper::is_post_indexable( $post_id ) ) {
return;
}
// Check if it's a hidden product.
if ( 'product' === $post->post_type && Helper::is_woocommerce_active() ) {
$product = wc_get_product( $post_id );
if ( $product && ! $product->is_visible() ) {
return;
}
}
Sitepress::get()->remove_home_url_filter();
$url = get_permalink( $post );
if ( 'trash' === $post->post_status ) {
$url = $this->previous_post_permalinks[ $post_id ];
}
Sitepress::get()->restore_home_url_filter();
/**
* Filter the URL to be submitted to IndexNow.
* Returning false will prevent the URL from being submitted.
*
* @param string $url URL to be submitted.
* @param WP_POST $post Post object.
*/
$send_url = $this->do_filter( 'instant_indexing/publish_url', $url, $post );
// Early exit if filter is set to false.
if ( ! $send_url ) {
return;
}
$this->api_submit( $send_url, false );
$this->submitted[] = $post_id;
}
/**
* Is module configured.
*
* @return boolean
*/
private function is_configured() {
return (bool) Helper::get_settings( 'instant_indexing.indexnow_api_key' );
}
/**
* Serve API key for search engines.
*/
public function serve_api_key() {
global $wp;
$api = Api::get();
$key = $api->get_key();
$key_location = $api->get_key_location( 'serve_api_key' );
$current_url = home_url( $wp->request );
if ( isset( $current_url ) && $key_location === $current_url ) {
header( 'Content-Type: text/plain' );
header( 'X-Robots-Tag: noindex' );
status_header( 200 );
echo esc_html( $key );
exit();
}
}
/**
* Submit URL to IndexNow API.
*
* @param string $url URL to be submitted.
* @param bool $is_manual_submission Whether the URL is submitted manually by the user.
*
* @return bool
*/
private function api_submit( $url, $is_manual_submission ) {
$api = Api::get();
/**
* Filter the URL to be submitted to IndexNow.
* Returning false will prevent the URL from being submitted.
*
* @param bool $is_manual_submission Whether the URL is submitted manually by the user.
*/
$url = $this->do_filter( 'instant_indexing/submit_url', $url, $is_manual_submission );
if ( ! $url ) {
return false;
}
$api_logs = $api->get_log();
if ( ! $is_manual_submission && ! empty( $api_logs ) ) {
$logs = array_values( array_reverse( $api_logs ) );
if ( ! empty( $logs[0] ) && $logs[0]['url'] === $url && time() - $logs[0]['time'] < self::THROTTLE_LIMIT ) {
return false;
}
}
$submitted = $api->submit( $url, $is_manual_submission );
if ( ! $is_manual_submission ) {
return $submitted;
}
$count = is_array( $url ) ? count( $url ) : 1;
$this->add_submit_message_notice( $submitted, $count );
return $submitted;
}
/**
* Add notice after submitting one or more URLs.
*
* @param bool $success Whether the submission was successful.
* @param int $count Number of submitted URLs.
*
* @return void
*/
private function add_submit_message_notice( $success, $count ) {
$notification_type = 'error';
$notification_message = __( 'Error submitting page to IndexNow.', 'rank-math' );
if ( $success ) {
$notification_type = 'success';
$notification_message = sprintf(
/* translators: %s: Number of pages submitted. */
_n( '%s page submitted to IndexNow.', '%s pages submitted to IndexNow.', $count, 'rank-math' ),
$count
);
}
Helper::add_notification( $notification_message, [ 'type' => $notification_type ] );
}
/**
* Get post types where auto-submit is enabled.
*
* @return array
*/
private function get_auto_submit_post_types() {
$post_types = Helper::get_settings( 'instant_indexing.bing_post_types', [] );
return $post_types;
}
}

View File

@@ -0,0 +1,234 @@
<?php
/**
* The Global functionality of the plugin.
*
* Defines the functionality loaded on admin.
*
* @since 1.0.49
* @package RankMath
* @subpackage RankMath\Rest
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Instant_Indexing;
use RankMath\Helper;
use WP_Error;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Controller;
use WP_REST_Response;
use RankMath\Helpers\Arr;
defined( 'ABSPATH' ) || exit;
/**
* Rest class.
*/
class Rest extends WP_REST_Controller {
/**
* Constructor.
*/
public function __construct() {
$this->namespace = \RankMath\Rest\Rest_Helper::BASE . '/in';
}
/**
* Register REST routes.
*
* @return void
*/
public function register_routes() {
$namespace = $this->namespace;
register_rest_route(
$namespace,
'/submitUrls',
[
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'submit_urls' ],
'permission_callback' => [ $this, 'has_permission' ],
'args' => [
'urls' => [
'description' => __( 'The list of urls to submit to the Instant Indexing API.', 'rank-math' ),
'type' => 'string',
'required' => true,
],
],
],
]
);
register_rest_route(
$namespace,
'/getLog',
[
[
'methods' => WP_REST_Server::CREATABLE,
'callback' => [ $this, 'get_log' ],
'permission_callback' => [ $this, 'has_permission' ],
'args' => [
'filter' => [
'description' => __( 'Filter log by type.', 'rank-math' ),
'type' => 'string',
'enum' => [ 'all', 'manual', 'auto' ],
'default' => 'all',
],
],
],
]
);
register_rest_route(
$namespace,
'/clearLog',
[
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'clear_log' ],
'permission_callback' => [ $this, 'has_permission' ],
'args' => [
'filter' => [
'description' => __( 'Clear log by type.', 'rank-math' ),
'type' => 'string',
'enum' => [ 'all', 'manual', 'auto' ],
'default' => 'all',
],
],
],
]
);
register_rest_route(
$namespace,
'/resetKey',
[
[
'methods' => WP_REST_Server::EDITABLE,
'callback' => [ $this, 'reset_key' ],
'permission_callback' => [ $this, 'has_permission' ],
],
]
);
}
/**
* Submit URLs.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return WP_REST_Response|WP_Error
*/
public function submit_urls( WP_REST_Request $request ) {
$urls = $request->get_param( 'urls' );
if ( empty( $urls ) ) {
return new WP_Error( 'empty_urls', __( 'No URLs provided.', 'rank-math' ) );
}
$urls = Arr::from_string( $urls, "\n" );
$urls = array_values( array_unique( array_filter( $urls, 'wp_http_validate_url' ) ) );
if ( ! $urls ) {
return new WP_Error( 'invalid_urls', __( 'Invalid URLs provided.', 'rank-math' ) );
}
$result = Api::get()->submit( $urls );
if ( ! $result ) {
return new WP_Error( 'submit_failed', __( 'Failed to submit URLs. See details in the History tab.', 'rank-math' ) );
}
$urls_number = count( $urls );
return new WP_REST_Response(
[
'success' => true,
'message' => sprintf(
// Translators: %s is the number of URLs submitted.
_n(
'Successfully submitted %s URL.',
'Successfully submitted %s URLs.',
$urls_number,
'rank-math'
),
$urls_number
),
]
);
}
/**
* Get log.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return WP_REST_Response|WP_Error
*/
public function get_log( WP_REST_Request $request ) {
$filter = $request->get_param( 'filter' );
$result = Api::get()->get_log();
$total = count( $result );
foreach ( $result as $key => $value ) {
$result[ $key ]['timeFormatted'] = wp_date( 'Y-m-d H:i:s', $value['time'] );
// Translators: placeholder is human-readable time, e.g. "1 hour".
$result[ $key ]['timeHumanReadable'] = sprintf( __( '%s ago', 'rank-math' ), human_time_diff( $value['time'] ) );
if ( 'manual' === $filter && empty( $result[ $key ]['manual_submission'] ) ) {
unset( $result[ $key ] );
} elseif ( 'auto' === $filter && ! empty( $result[ $key ]['manual_submission'] ) ) {
unset( $result[ $key ] );
}
}
$result = array_values( array_reverse( $result ) );
return new WP_REST_Response(
[
'data' => $result,
'total' => $total,
]
);
}
/**
* Clear log.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return WP_REST_Response|WP_Error
*/
public function clear_log( WP_REST_Request $request ) {
Api::get()->clear_log();
return new WP_REST_Response( [ 'status' => 'ok' ] );
}
/**
* Reset key.
*
* @param WP_REST_Request $request Full details about the request.
*
* @return WP_REST_Response|WP_Error
*/
public function reset_key( WP_REST_Request $request ) {
$api = Api::get();
$api->reset_key();
$key = $api->get_key();
$location = $api->get_key_location( 'reset_key' );
return new WP_REST_Response(
[
'status' => 'ok',
'key' => $key,
'location' => $location,
]
);
}
/**
* Determine if the current user can manage instant indexing.
*
* @return bool
*/
public function has_permission() {
return Helper::has_cap( 'general' );
}
}

View File

@@ -0,0 +1,44 @@
<?php
/**
* IndexNow Options: Console tab.
*
* @since 1.0.56
* @package Rank_Math
*/
defined( 'ABSPATH' ) || exit;
$cmb->add_field(
[
'id' => 'indexnow_description',
'type' => 'raw',
'content' => '<div class="bing-api-description description"><p>' . esc_html__( 'Insert URLs to send to the IndexNow API (one per line, up to 10,000):', 'rank-math' ) . '</p></div>',
]
);
$cmb->add_field(
[
'id' => 'indexnow_urls',
'type' => 'textarea_small',
'sanitization_cb' => '__return_false',
'attributes' => [
'class' => 'instant-indexing-urls',
'placeholder' => trailingslashit( home_url() ) . _x( 'hello-world', 'URL slug placeholder', 'rank-math' ),
],
'after_field' => '<a href="#" id="indexnow_submit" class="button button-primary large-button" style="margin-top: 20px;">' . esc_html__( 'Submit URLs', 'rank-math' ) . '</a> <span class="spinner" id="indexnow_spinner"></span>',
]
);
$cmb->add_field(
[
'id' => 'educational_note',
'type' => 'notice',
'what' => 'info',
'save_field' => false,
'content' => sprintf(
/* translators: Note text */
esc_html__( '%s The URLs will be submitted to Bing and Yandex only, and not to Google.', 'rank-math' ),
'<b>' . esc_html__( 'Note:', 'rank-math' ) . '</b>'
),
]
);

View File

@@ -0,0 +1,47 @@
<?php
/**
* IndexNow Options: History tab.
*
* @since 1.0.56
* @package Rank_Math
*/
defined( 'ABSPATH' ) || exit;
$history_content = '';
$history_content .= '<a href="#" id="indexnow_clear_history" class="button alignright hidden">' . esc_html__( 'Clear History', 'rank-math' ) . '</a>';
$history_content .= '<div class="history-filter-links hidden" id="indexnow_history_filters"><a href="#" data-filter="all" class="current">' . esc_html__( 'All', 'rank-math' ) . '</a> | <a href="#" data-filter="manual">' . esc_html__( 'Manual', 'rank-math' ) . '</a> | <a href="#" data-filter="auto">' . esc_html__( 'Auto', 'rank-math' ) . '</a></div>';
$history_content .= '<div class="clear"></div>';
$history_content .= '<table class="wp-list-table widefat striped" id="indexnow_history"><thead><tr><th class="col-date">' . esc_html__( 'Time', 'rank-math' ) . '</th><th class="col-url">' . esc_html__( 'URL', 'rank-math' ) . '</th><th class="col-status">' . esc_html__( 'Response', 'rank-math' ) . '</th></tr></thead><tbody>';
$history_content .= '</tbody></table>';
$cmb->add_field(
[
'id' => 'indexnow_history',
'type' => 'raw',
/* translators: daily quota */
'content' => $history_content,
]
);
$help_contents = '';
$help_contents .= '<a href="#" id="indexnow_show_response_codes">' . esc_html__( 'Response Code Help', 'rank-math' ) . '<span class="dashicons dashicons-arrow-down"></span></a>';
$help_contents .= '<table class="wp-list-table widefat striped hidden" id="indexnow_response_codes"><thead><tr><th class="col-response-code">' . esc_html__( 'Response Code', 'rank-math' ) . '</th><th class="col-response-message">' . esc_html__( 'Response Message', 'rank-math' ) . '</th><th class="col-reasons">' . esc_html__( 'Reasons', 'rank-math' ) . '</th></tr></thead><tbody>';
$help_contents .= '<tr><td class="col-response-code">200</td><td class="col-response-message">' . esc_html__( 'OK', 'rank-math' ) . '</td><td class="col-reasons">' . esc_html__( 'The URL was successfully submitted to the IndexNow API.', 'rank-math' ) . '</td></tr>';
$help_contents .= '<tr><td class="col-response-code">202</td><td class="col-response-message">' . esc_html__( 'Accepted', 'rank-math' ) . '</td><td class="col-reasons">' . esc_html__( 'The URL was successfully submitted to the IndexNow API, but the API key will be checked later.', 'rank-math' ) . '</td></tr>';
$help_contents .= '<tr><td class="col-response-code">400</td><td class="col-response-message">' . esc_html__( 'Bad Request', 'rank-math' ) . '</td><td class="col-reasons">' . esc_html__( 'The request was invalid.', 'rank-math' ) . '</td></tr>';
$help_contents .= '<tr><td class="col-response-code">403</td><td class="col-response-message">' . esc_html__( 'Forbidden', 'rank-math' ) . '</td><td class="col-reasons">' . esc_html__( 'The key was invalid (e.g. key not found, file found but key not in the file).', 'rank-math' ) . '</td></tr>';
$help_contents .= '<tr><td class="col-response-code">422</td><td class="col-response-message">' . esc_html__( 'Unprocessable Entity', 'rank-math' ) . '</td><td class="col-reasons">' . esc_html__( 'The URLs don\'t belong to the host or the key is not matching the schema in the protocol.', 'rank-math' ) . '</td></tr>';
$help_contents .= '<tr><td class="col-response-code">429</td><td class="col-response-message">' . esc_html__( 'Too Many Requests', 'rank-math' ) . '</td><td class="col-reasons">' . esc_html__( 'Too Many Requests (potential Spam).', 'rank-math' ) . '</td></tr>';
$help_contents .= '</tbody></table>';
$cmb->add_field(
[
'id' => 'indexnow_help',
'type' => 'raw',
/* translators: daily quota */
'content' => $help_contents,
]
);

View File

@@ -0,0 +1 @@
<?php // Silence is golden.

View File

@@ -0,0 +1,64 @@
<?php
/**
* IndexNow Settings.
*
* @since 1.0.56
* @package RankMath
* @subpackage RankMath\Settings
*/
namespace RankMath\Instant_Indexing;
use RankMath\Helper;
defined( 'ABSPATH' ) || exit;
$cmb->add_field(
[
'id' => 'bing_post_types',
'type' => 'multicheck',
'name' => esc_html__( 'Auto-Submit Post Types', 'rank-math' ),
'desc' => esc_html__( 'Submit posts from these post types automatically to the IndexNow API when a post is published, updated, or trashed.', 'rank-math' ),
'options' => Helper::choices_post_types(),
]
);
$cmb->add_field(
[
'id' => 'indexnow_api_key',
'name' => esc_html__( 'API Key', 'rank-math' ),
'desc' => esc_html__( 'The IndexNow API key proves the ownership of the site. It is generated automatically. You can change the key if it becomes known to third parties.', 'rank-math' ),
'type' => 'text',
'after_field' => '<a href="#" id="indexnow_reset_key" class="button button-secondary large-button"><span class="dashicons dashicons-update"></span> ' . esc_html__( 'Change Key', 'rank-math' ) . '</a>',
'classes' => 'rank-math-advanced-option',
'attributes' => [
'readonly' => 'readonly',
],
]
);
$key_location = Api::get()->get_key_location( 'settings_field' );
$field_label = esc_html__( 'API Key Location', 'rank-math' );
$check_key_label = esc_html__( 'Check Key', 'rank-math' );
// Translators: %s is the words "Check Key".
$field_desc = sprintf( esc_html__( 'Use the %1$s button to verify that the key is accessible for search engines. Clicking on it should open the key file in your browser and show the API key.', 'rank-math' ), '<strong>' . $check_key_label . '</strong>' );
$location_field = '<div class="cmb-row cmb-type-text cmb2-id-indexnow-api-key-location table-layout rank-math-advanced-option" data-fieldtype="text">
<div class="cmb-th">
<label for="indexnow_api_key_location">' . $field_label . '</label>
</div>
<div class="cmb-td">
<code id="indexnow_api_key_location">' . esc_url( $key_location ) . '</code>
<p class="cmb2-metabox-description">' . $field_desc . '</p>
<a href="' . esc_url( $key_location ) . '" id="indexnow_check_key" class="button button-secondary large-button" target="_blank"><span class="dashicons dashicons-search"></span> ' . $check_key_label . '</a>
</div>
</div>';
$cmb->add_field(
[
'id' => 'indexnow_api_key_location',
'type' => 'raw',
'content' => $location_field,
]
);