Commit realizado el 12:13:52 08-04-2024

This commit is contained in:
Pagina Web Monito
2024-04-08 12:13:55 -04:00
commit 0c33094de9
7815 changed files with 1365694 additions and 0 deletions

View File

@@ -0,0 +1,209 @@
<?php
/**
* The Content Processor.
*
* Extract and save links from the content of a given post.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Links
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\Links;
use RankMath\Helpers\Str;
use RankMath\Helper;
use RankMath\Sitemap\Classifier;
defined( 'ABSPATH' ) || exit;
/**
* ContentProcessor class.
*/
class ContentProcessor {
/**
* Link storage.
*
* @var Storage
*/
public $storage;
/**
* Link classifier.
*
* @var Classifier
*/
protected $classifier;
/**
* The Constructor
*/
public function __construct() {
$this->storage = new Storage();
$this->classifier = new Classifier( home_url() );
}
/**
* Process the content.
*
* @param int $post_id The post ID.
* @param string $content The content.
*/
public function process( $post_id, $content ) {
$links = $this->extract( $content );
$counts = [
'internal_link_count' => 0,
'external_link_count' => 0,
];
$new_links = [];
$post_permalink = $this->normalize_link( get_permalink( $post_id ) );
foreach ( $links as $link ) {
$normalized_link = $this->normalize_link( $link );
if ( $post_permalink === $normalized_link ) {
continue;
}
$this->process_link( $link, $new_links, $counts );
}
$old_links = $this->get_stored_internal_links( $post_id );
$this->storage->cleanup( $post_id );
$this->storage->save_links( $post_id, $new_links );
$this->storage->update_link_counts( $post_id, $counts, array_merge( $new_links, $old_links ) );
}
/**
* Process a link.
*
* @param string $link Link to process.
* @param array $list Links to add after process.
* @param array $counts Counts array.
*/
private function process_link( $link, &$list, &$counts ) {
$link_type = $this->is_valid_link_type( $link );
if ( empty( $link_type ) ) {
return;
}
$target_post_id = 0;
if ( Classifier::TYPE_INTERNAL === $link_type ) {
$target_post_id = url_to_postid( $link );
if ( 0 === $target_post_id ) {
// Maybe a product with altered url!
$target_post_id = $this->maybe_product_id( $link );
}
}
$counts[ "{$link_type}_link_count" ] += 1;
$list[] = new Link( $link, $target_post_id, $link_type );
}
/**
* Extract href property values from HTML string.
*
* @param string $content Content to extract links from.
*
* @return array The extracted links.
*/
public function extract( $content ) {
$links = [];
if ( false === Str::contains( 'href', $content ) ) {
return $links;
}
$regexp = '<a\s[^>]*href=("??)([^" >]*?)\\1[^>]*>';
// Case insensitive & ungreedy modifiers.
if ( preg_match_all( "/$regexp/iU", $content, $matches, PREG_SET_ORDER ) ) {
foreach ( $matches as $match ) {
$links[] = trim( $match[2], "'" );
}
}
return $links;
}
/**
* Retrieves the stored internal links for the supplied post.
*
* @param int $post_id The post to fetch links for.
*
* @return Link[] List of internal links connected to the post.
*/
public function get_stored_internal_links( $post_id ) {
$links = $this->storage->get_links( $post_id );
return array_filter( $links, [ $this, 'filter_internal_link' ] );
}
/**
* Filter internal links.
*
* @param Link $link Link to test.
*
* @return bool True if internal, false if external.
*/
protected function filter_internal_link( Link $link ) {
return $link->get_type() === Classifier::TYPE_INTERNAL;
}
/**
* Check if link is valid.
*
* @param string $link Link to check.
*
* @return boolean
*/
private function is_valid_link_type( $link ) {
$type = false;
if ( ! empty( $link ) && '#' !== $link[0] ) {
$type = $this->classifier->classify( $link );
}
if ( Classifier::TYPE_INTERNAL === $type && preg_match( '/\.(jpg|jpeg|png|gif|bmp|pdf|mp3|zip)$/i', $link ) ) {
$type = false;
}
/**
* Filter: 'rank_math/links/link_type' - Allow developers to filter the link type.
*/
return apply_filters( 'rank_math/links/link_type', $type, $link );
}
/**
* Normalize a link: remove trailing slash, remove fragment identifier, remove home_url.
*
* @param string $link The link to normalize.
* @return string
*/
private function normalize_link( $link ) {
$normalized = untrailingslashit( str_replace( home_url(), '', explode( '#', $link )[0] ) );
return $normalized;
}
/**
* Gets the post id from a modified link.
*
* @param string $link Link to process.
* @return int
*/
private function maybe_product_id( $link ) {
// Early bail if Remove Base option is not enabled.
if ( ! Helper::get_settings( 'general.wc_remove_product_base' ) ) {
return 0;
}
$product = get_page_by_path( basename( untrailingslashit( $link ) ), OBJECT, [ 'product' ] );
if ( ! $product ) {
return 0;
}
return $product->ID;
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* The SEO Link class.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Links
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\Links;
defined( 'ABSPATH' ) || exit;
/**
* Link class.
*/
class Link {
/**
* Link URL.
*
* @var string
*/
protected $url;
/**
* Link post ID.
*
* @var int
*/
protected $target_post_id;
/**
* Link type.
*
* @var string
*/
protected $type;
/**
* Sets the properties for the object.
*
* @param string $url The URL.
* @param int $target_post_id ID to the post where the link refers to.
* @param string $type The URL type: internal or external.
*/
public function __construct( $url, $target_post_id, $type ) {
$this->url = $url;
$this->target_post_id = $target_post_id;
$this->type = $type;
}
/**
* Returns the URL.
*
* @return string The URL.
*/
public function get_url() {
return $this->url;
}
/**
* Returns the target post ID.
*
* @return int The target post ID.
*/
public function get_target_post_id() {
return (int) $this->target_post_id;
}
/**
* Return the link type (internal/external).
*
* @return string The link type.
*/
public function get_type() {
return $this->type;
}
}

View File

@@ -0,0 +1,216 @@
<?php
/**
* The Link Counter module.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Links
* @author Rank Math <support@rankmath.com>
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
namespace RankMath\Links;
use WP_Post;
use RankMath\Helper;
use RankMath\Traits\Hooker;
use RankMath\Admin\Database\Database;
use RankMath\Admin\Post_Columns;
defined( 'ABSPATH' ) || exit;
/**
* Links class.
*/
class Links {
use Hooker;
/**
* Links data.
*
* @var array
*/
private $links_data = [];
/**
* The Constructor.
*/
public function __construct() {
$this->action( 'save_post', 'save_post', 10, 2 );
$this->action( 'delete_post', 'delete_post' );
$this->action( 'rank_math/post/column/seo_details', 'post_column_content', 11, 3 );
$this->action( 'rank_math/links/internal_links', 'cron_job' );
}
/**
* Process and save the links in a post.
*
* @param int $post_id The post ID to check.
* @param WP_Post $post The post object.
*/
public function save_post( $post_id, $post ) {
if ( ! $post instanceof WP_Post || ! $this->is_processable( $post ) ) {
return;
}
$this->process( $post_id, $post->post_content );
}
/**
* Remove the links data when the post is deleted.
*
* @param int $post_id The post ID.
*/
public function delete_post( $post_id ) {
if ( ! $this->is_processable( get_post( $post_id ) ) ) {
return;
}
$processor = new ContentProcessor();
// Get links to update linked objects.
$links = $processor->get_stored_internal_links( $post_id );
// Remove all links for this post.
$processor->storage->cleanup( $post_id );
// Update link counts.
$processor->storage->update_link_counts( $post_id, [], $links );
}
/**
* Post column content.
*
* @param int $post_id Post ID.
* @param array $post_data Current post SEO data.
* @param array $data All posts SEO data.
*/
public function post_column_content( $post_id, $post_data, $data ) {
if ( ! Post_Columns::is_post_indexable( $post_id ) || empty( $data ) ) {
return;
}
if ( empty( $this->links_data ) ) {
$this->get_links_data( array_keys( $data ) );
}
$counts = ! empty( $this->links_data[ $post_id ] ) ? $this->links_data[ $post_id ] : (object) [
'internal_link_count' => 0,
'external_link_count' => 0,
'incoming_link_count' => 0,
];
?>
<span class="rank-math-column-display rank-math-link-count">
<strong><?php esc_html_e( 'Links: ', 'rank-math' ); ?></strong>
<span title="<?php esc_attr_e( 'Internal Links', 'rank-math' ); ?>">
<span class="dashicons dashicons-admin-links"></span>
<span><?php echo isset( $counts->internal_link_count ) ? esc_html( $counts->internal_link_count ) : ''; ?></span>
</span>
<span class="divider"></span>
<span title="<?php esc_attr_e( 'External Links', 'rank-math' ); ?>">
<span class="dashicons dashicons-external"></span>
<span><?php echo isset( $counts->external_link_count ) ? esc_html( $counts->external_link_count ) : ''; ?></span>
</span>
<span class="divider"></span>
<span title="<?php esc_attr_e( 'Incoming Links', 'rank-math' ); ?>">
<span class="dashicons dashicons-external internal"></span>
<span><?php echo isset( $counts->incoming_link_count ) ? esc_html( $counts->incoming_link_count ) : ''; ?></span>
</span>
</span>
<?php
}
/**
* Process old posts if this is an old installation.
*/
public function cron_job() {
$post_types = Helper::get_accessible_post_types();
unset( $post_types['attachment'] );
$posts = get_posts(
[
'post_type' => array_keys( $post_types ),
'post_status' => [ 'publish', 'future' ],
'meta_query' => [
[
'key' => 'rank_math_internal_links_processed',
'compare' => 'NOT EXISTS',
],
],
]
);
// Early Bail.
if ( empty( $posts ) ) {
wp_clear_scheduled_hook( 'rank_math/links/internal_links' );
return;
}
// Process.
foreach ( $posts as $post ) {
$this->save_post( $post->ID, $post );
}
}
/**
* Process the content for a given post.
*
* @param int $post_id The post ID.
* @param string $content The content.
*/
private function process( $post_id, $content ) {
/**
* Filter to change the content passed to the Link processor.
*
* @param string $content Post content.
* @param int $post_id Post ID.
*/
$content = $this->do_filter( 'links/content', apply_filters( 'the_content', $content ), $post_id );
$content = str_replace( ']]>', ']]&gt;', $content );
$processor = new ContentProcessor();
$processor->process( $post_id, $content );
update_post_meta( $post_id, 'rank_math_internal_links_processed', true );
}
/**
* Check if the post is processable.
*
* @param WP_Post $post The post object.
*
* @return bool True if processable.
*/
private function is_processable( $post ) {
/**
* Filter to prevent processing the post.
*
* @param boolean $value Whether to process the post.
* @param WP_POST $post The Post object.
*/
if ( wp_is_post_revision( $post->ID ) || ! $this->do_filter( 'links/process_post', true, $post ) ) {
return false;
}
if ( in_array( $post->post_status, [ 'auto-draft', 'trash' ], true ) ) {
return false;
}
$post_types = Helper::get_accessible_post_types();
unset( $post_types['attachment'] );
return isset( $post_types[ $post->post_type ] );
}
/**
* Get links data by post id.
*
* @param array $post_ids The post ids.
*/
private function get_links_data( $post_ids ) {
$results = Database::table( 'rank_math_internal_meta' )->select( '*' )->whereIn( 'object_id', $post_ids )->groupBy( 'object_id' )->get();
$this->links_data = array_combine( array_column( $results, 'object_id' ), $results );
}
}

View File

@@ -0,0 +1,181 @@
<?php
/**
* The DB interface.
*
* @since 0.9.0
* @package RankMath
* @subpackage RankMath\Links
* @author Rank Math <support@rankmath.com>
*/
namespace RankMath\Links;
defined( 'ABSPATH' ) || exit;
/**
* Storage class.
*
* @copyright Copyright (C) 2008-2019, Yoast BV
* The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
*/
class Storage {
/**
* Get query builder.
*
* @return \RankMath\Admin\Database\Query_Builder
*/
private function table() {
return \RankMath\Helpers\DB::query_builder( 'rank_math_internal_links' );
}
/**
* Removes all data for a given post.
*
* @param int $post_id The post ID to remove the records for.
*
* @return int|false The number of rows updated, or false on error.
*/
public function cleanup( $post_id ) {
return $this->table()->where( 'post_id', $post_id )->delete();
}
/**
* Get array of links from the database for given post.
*
* @param int $post_id The post to get the links for.
*
* @return Link[] The links array.
*/
public function get_links( $post_id ) {
$links = [];
$results = $this->table()
->select( [ 'url', 'post_id', 'target_post_id', 'type' ] )
->where( 'post_id', $post_id )
->get();
foreach ( $results as $link ) {
$links[] = new Link( $link->url, $link->target_post_id, $link->type );
}
return $links;
}
/**
* Save links for a post.
*
* @param integer $post_id The post ID to save.
* @param Link[] $links The links to save.
*
* @return void
*/
public function save_links( $post_id, array $links ) {
foreach ( $links as $link ) {
$this->table()->insert(
[
'url' => $link->get_url(),
'post_id' => $post_id,
'target_post_id' => $link->get_target_post_id(),
'type' => $link->get_type(),
],
[ '%s', '%d', '%d', '%s' ]
);
}
}
/**
* Update the link counts for a post and its referenced posts.
*
* @param int $post_id Post to update.
* @param int|null $counts Links count.
* @param Link[] $links Links to update incoming link count.
*/
public function update_link_counts( $post_id, $counts, array $links ) {
$counts = wp_parse_args(
$counts,
[
'internal_link_count' => 0,
'external_link_count' => 0,
]
);
$this->save_meta_data( $post_id, $counts );
$this->update_incoming_links( $post_id, $links );
}
/**
* Update the incoming link count.
*
* @param int $post_id Post which is processed.
* @param Link[] $links Links we need to update the incoming link count of.
*
* @return void
*/
public function update_incoming_links( $post_id, $links ) {
$post_ids = $this->get_internal_post_ids( $links );
$post_ids = array_merge( [ $post_id ], $post_ids );
$this->update_incoming_link_count( $post_ids );
}
/**
* Get post IDs from the link objects.
*
* @param Link[] $links Links we need to update the incoming link count of.
*
* @return int[] List of post IDs.
*/
protected function get_internal_post_ids( $links ) {
$post_ids = [];
foreach ( $links as $link ) {
$post_ids[] = $link->get_target_post_id();
}
return array_filter( $post_ids );
}
/**
* Update the incoming link count.
*
* @param array $post_ids The posts to update the link count for.
*/
public function update_incoming_link_count( array $post_ids ) {
$results = $this->table()
->selectCount( 'id', 'incoming' )
->select( 'target_post_id as post_id' )
->whereIn( 'target_post_id', $post_ids )
->groupBy( 'target_post_id' )->get();
$post_ids_non_zero = [];
foreach ( $results as $result ) {
$this->save_meta_data( $result->post_id, [ 'incoming_link_count' => $result->incoming ] );
$post_ids_non_zero[] = $result->post_id;
}
$post_ids_zero = array_diff( $post_ids, $post_ids_non_zero );
foreach ( $post_ids_zero as $post_id ) {
$this->save_meta_data( $post_id, [ 'incoming_link_count' => 0 ] );
}
}
/**
* Save the link count to the database.
*
* @param int $post_id The ID to save the link count for.
* @param array $meta_data The total amount of links.
*/
public function save_meta_data( $post_id, array $meta_data ) {
global $wpdb;
$where = [ 'object_id' => $post_id ];
$exists = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}rank_math_internal_meta WHERE object_id = %d", $post_id ) );
if ( $exists ) {
$result = $wpdb->update( $wpdb->prefix . 'rank_math_internal_meta', $meta_data, $where );
return $result;
}
$data = array_merge( $where, $meta_data );
$result = $wpdb->insert( $wpdb->prefix . 'rank_math_internal_meta', $data );
return $result;
}
}