| Current Path : /home/x/b/o/xbodynamge/namtation/wp-content/ |
| Current File : /home/x/b/o/xbodynamge/namtation/wp-content/Image.php.tar |
namtation/wp-content/plugins/all-in-one-seo-pack/app/Common/Schema/Graphs/Traits/Image.php 0000644 00000005462 15113767543 0030436 0 ustar 00 home/xbodynamge <?php
namespace AIOSEO\Plugin\Common\Schema\Graphs\Traits;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Trait that handles images for the graphs.
*
* @since 4.2.5
*/
trait Image {
/**
* Builds the graph data for a given image with a given schema ID.
*
* @since 4.0.0
*
* @param int $imageId The image ID.
* @param string $graphId The graph ID (optional).
* @return array $data The image graph data.
*/
protected function image( $imageId, $graphId = '' ) {
$attachmentId = is_string( $imageId ) && ! is_numeric( $imageId ) ? aioseo()->helpers->attachmentUrlToPostId( $imageId ) : $imageId;
$imageUrl = wp_get_attachment_image_url( $attachmentId, 'full' );
$data = [
'@type' => 'ImageObject',
'url' => $imageUrl ? $imageUrl : $imageId,
];
if ( $graphId ) {
$baseUrl = aioseo()->schema->context['url'] ?? aioseo()->helpers->getUrl();
$data['@id'] = trailingslashit( $baseUrl ) . '#' . $graphId;
}
if ( ! $attachmentId ) {
return $data;
}
$metaData = wp_get_attachment_metadata( $attachmentId );
if ( $metaData && ! empty( $metaData['width'] ) && ! empty( $metaData['height'] ) ) {
$data['width'] = (int) $metaData['width'];
$data['height'] = (int) $metaData['height'];
}
$caption = $this->getImageCaption( $attachmentId );
if ( ! empty( $caption ) ) {
$data['caption'] = $caption;
}
return $data;
}
/**
* Get the image caption.
*
* @since 4.1.4
*
* @param int $attachmentId The attachment ID.
* @return string The caption.
*/
private function getImageCaption( $attachmentId ) {
$caption = wp_get_attachment_caption( $attachmentId );
if ( ! empty( $caption ) ) {
return $caption;
}
return get_post_meta( $attachmentId, '_wp_attachment_image_alt', true );
}
/**
* Returns the graph data for the avatar of a given user.
*
* @since 4.0.0
*
* @param int $userId The user ID.
* @param string $graphId The graph ID.
* @return array The graph data.
*/
protected function avatar( $userId, $graphId ) {
if ( ! get_option( 'show_avatars' ) ) {
return [];
}
$avatar = get_avatar_data( $userId );
if ( ! $avatar['found_avatar'] ) {
return [];
}
return array_filter( [
'@type' => 'ImageObject',
'@id' => aioseo()->schema->context['url'] . "#$graphId",
'url' => $avatar['url'],
'width' => $avatar['width'],
'height' => $avatar['height'],
'caption' => get_the_author_meta( 'display_name', $userId )
] );
}
/**
* Returns the graph data for the post's featured image.
*
* @since 4.2.5
*
* @return string The featured image URL.
*/
protected function getFeaturedImage() {
$post = aioseo()->helpers->getPost();
return has_post_thumbnail( $post ) ? $this->image( get_post_thumbnail_id() ) : '';
}
} home/xbodynamge/namtation/wp-content/plugins/all-in-one-seo-pack/app/Common/Social/Image.php 0000644 00000017435 15114025711 0026021 0 ustar 00 <?php
namespace AIOSEO\Plugin\Common\Social;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use AIOSEO\Plugin\Common\Models;
/**
* Handles the Open Graph and Twitter Image.
*
* @since 4.0.0
*/
class Image {
/**
* The type of image ("facebook" or "twitter").
*
* @since 4.1.6.2
*
* @var string
*/
protected $type;
/**
* The post object.
*
* @since 4.1.6.2
*
* @var \WP_Post
*/
private $post;
/**
* The default thumbnail size.
*
* @since 4.0.0
*
* @var string
*/
protected $thumbnailSize;
/**
* Whether or not to use the cached images.
*
* @since 4.1.6
*
* @var boolean
*/
public $useCache = true;
/**
* Returns the Facebook or Twitter image.
*
* @since 4.0.0
*
* @param string $type The type ("Facebook" or "Twitter").
* @param string $imageSource The image source.
* @param \WP_Post|null $post The post object.
* @return string|array The image data.
*/
public function getImage( $type, $imageSource, $post = null ) {
$this->type = $type;
$this->post = $post;
$this->thumbnailSize = apply_filters( 'aioseo_thumbnail_size', 'fullsize' );
$hash = md5( wp_json_encode( [ $type, $imageSource, $post ] ) );
static $images = [];
if ( isset( $images[ $hash ] ) ) {
return $images[ $hash ];
}
if ( 'auto' === $imageSource && aioseo()->helpers->getPostPageBuilderName( $post->ID ) ) {
$imageSource = 'default';
}
if ( is_a( $this->post, 'WP_Post' ) ) {
switch ( $imageSource ) {
case 'featured':
$image = $this->getFeaturedImage();
break;
case 'attach':
$image = $this->getFirstAttachedImage();
break;
case 'content':
$image = $this->getFirstImageInContent();
break;
case 'author':
$image = $this->getAuthorAvatar();
break;
case 'auto':
$image = $this->getFirstAvailableImage();
break;
case 'custom':
$image = $this->getCustomFieldImage();
break;
case 'custom_image':
$metaData = aioseo()->meta->metaData->getMetaData( $post );
if ( empty( $metaData ) ) {
break;
}
$image = 'facebook' === strtolower( $this->type )
? $metaData->og_image_custom_url
: $metaData->twitter_image_custom_url;
break;
case 'default':
default:
$image = aioseo()->options->social->{$this->type}->general->defaultImagePosts;
}
}
if ( empty( $image ) ) {
$image = aioseo()->options->social->{$this->type}->general->defaultImagePosts;
}
if ( is_array( $image ) ) {
$images[ $hash ] = $image;
return $images[ $hash ];
}
$imageWithoutDimensions = aioseo()->helpers->removeImageDimensions( $image );
$attachmentId = aioseo()->helpers->attachmentUrlToPostId( $imageWithoutDimensions );
$images[ $hash ] = $attachmentId ? wp_get_attachment_image_src( $attachmentId, $this->thumbnailSize ) : $image;
return $images[ $hash ];
}
/**
* Returns the Featured Image for the post.
*
* @since 4.0.0
*
* @return array The image data.
*/
private function getFeaturedImage() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
$imageId = get_post_thumbnail_id( $this->post->ID );
return $imageId ? wp_get_attachment_image_src( $imageId, $this->thumbnailSize ) : '';
}
/**
* Returns the first attached image.
*
* @since 4.0.0
*
* @return string The image data.
*/
private function getFirstAttachedImage() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
if ( 'attachment' === get_post_type( $this->post->ID ) ) {
return wp_get_attachment_image_src( $this->post->ID, $this->thumbnailSize );
}
$attachments = get_children(
[
'post_parent' => $this->post->ID,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
]
);
return $attachments && count( $attachments ) ? wp_get_attachment_image_src( array_values( $attachments )[0]->ID, $this->thumbnailSize ) : '';
}
/**
* Returns the first image found in the post content.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getFirstImageInContent() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
$postContent = aioseo()->helpers->getPostContent( $this->post );
preg_match_all( '|<img.*?src=[\'"](.*?)[\'"].*?>|i', (string) $postContent, $matches ); // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
// Ignore cover block background image - WP >= 5.7.
if ( ! empty( $matches[0] ) && apply_filters( 'aioseo_social_image_ignore_cover_block', true, $this->post, $matches ) ) {
foreach ( $matches[0] as $key => $match ) {
if ( false !== stripos( $match, 'wp-block-cover__image-background' ) ) {
unset( $matches[1][ $key ] );
}
}
}
return ! empty( $matches[1] ) ? current( $matches[1] ) : '';
}
/**
* Returns the author avatar.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getAuthorAvatar() {
$avatar = get_avatar( $this->post->post_author, 300 );
preg_match( "/src='(.*?)'/i", (string) $avatar, $matches );
return ! empty( $matches[1] ) ? $matches[1] : '';
}
/**
* Returns the first available image.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getFirstAvailableImage() {
// Disable the cache.
$this->useCache = false;
$image = $this->getCustomFieldImage();
if ( ! $image ) {
$image = $this->getFeaturedImage();
}
if ( ! $image ) {
$image = $this->getFirstAttachedImage();
}
if ( ! $image ) {
$image = $this->getFirstImageInContent();
}
if ( ! $image && 'twitter' === strtolower( $this->type ) ) {
$image = aioseo()->options->social->twitter->homePage->image;
}
// Enable the cache.
$this->useCache = true;
return $image ? $image : aioseo()->options->social->facebook->homePage->image;
}
/**
* Returns the image from a custom field.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getCustomFieldImage() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
$prefix = 'facebook' === strtolower( $this->type ) ? 'og_' : 'twitter_';
$aioseoPost = Models\Post::getPost( $this->post->ID );
$customFields = ! empty( $aioseoPost->{ $prefix . 'image_custom_fields' } )
? $aioseoPost->{ $prefix . 'image_custom_fields' }
: aioseo()->options->social->{$this->type}->general->customFieldImagePosts;
if ( ! $customFields ) {
return '';
}
$customFields = explode( ',', $customFields );
foreach ( $customFields as $customField ) {
$image = get_post_meta( $this->post->ID, $customField, true );
if ( ! empty( $image ) ) {
$image = is_array( $image ) ? $image[0] : $image;
return is_numeric( $image )
? wp_get_attachment_image_src( $image, $this->thumbnailSize )
: $image;
}
}
return '';
}
/**
* Returns the cached image if there is one.
*
* @since 4.1.6.2
*
* @param \WP_Term $object The object for which we need to get the cached image.
* @return string|array The image URL or data.
*/
protected function getCachedImage( $object = null ) {
if ( null === $object ) {
// This isn't null if we call it from the Pro class.
$object = $this->post;
}
$metaData = aioseo()->meta->metaData->getMetaData( $object );
switch ( $this->type ) {
case 'facebook':
if ( ! empty( $metaData->og_image_url ) && $this->useCache ) {
return aioseo()->meta->metaData->getCachedOgImage( $metaData );
}
break;
case 'twitter':
if ( ! empty( $metaData->twitter_image_url ) && $this->useCache ) {
return $metaData->twitter_image_url;
}
break;
default:
break;
}
return '';
}
} home/xbodynamge/dev/wp-content/plugins/all-in-one-seo-pack/app/Common/Sitemap/Image/Image.php 0000644 00000022536 15114173417 0026024 0 ustar 00 <?php
namespace AIOSEO\Plugin\Common\Sitemap\Image;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Determines which images are included in a post/term.
*
* @since 4.0.0
*/
class Image {
/**
* The image scan action name.
*
* @since 4.0.13
*
* @var string
*/
private $imageScanAction = 'aioseo_image_sitemap_scan';
/**
* The supported image extensions.
*
* @since 4.2.2
*
* @var array[string]
*/
public $supportedExtensions = [
'gif',
'heic',
'jpeg',
'jpg',
'png',
'svg',
'webp',
'ico'
];
/**
* The post object.
*
* @since 4.2.7
*
* @var \WP_Post
*/
private $post = null;
/**
* Class constructor.
*
* @since 4.0.5
*/
public function __construct() {
// Column may not have been created yet.
if ( ! aioseo()->core->db->columnExists( 'aioseo_posts', 'image_scan_date' ) ) {
return;
}
// NOTE: This needs to go above the is_admin check in order for it to run at all.
add_action( $this->imageScanAction, [ $this, 'scanPosts' ] );
// Don't schedule a scan if we are not in the admin.
if ( ! is_admin() ) {
return;
}
if ( wp_doing_ajax() || wp_doing_cron() ) {
return;
}
// Don't schedule a scan if an importer or the V3 migration is running.
// We'll do our scans there.
if (
aioseo()->importExport->isImportRunning() ||
aioseo()->migration->isMigrationRunning()
) {
return;
}
// Action Scheduler hooks.
add_action( 'init', [ $this, 'scheduleScan' ], 3001 );
}
/**
* Schedules the image sitemap scan.
*
* @since 4.0.5
*
* @return void
*/
public function scheduleScan() {
if (
! aioseo()->options->sitemap->general->enable ||
aioseo()->sitemap->helpers->excludeImages()
) {
return;
}
aioseo()->actionScheduler->scheduleSingle( $this->imageScanAction, 10 );
}
/**
* Scans posts for images.
*
* @since 4.0.5
*
* @return void
*/
public function scanPosts() {
if (
! aioseo()->options->sitemap->general->enable ||
aioseo()->sitemap->helpers->excludeImages()
) {
return;
}
$postsPerScan = apply_filters( 'aioseo_image_sitemap_posts_per_scan', 10 );
$postTypes = implode( "', '", aioseo()->helpers->getPublicPostTypes( true ) );
$posts = aioseo()->core->db
->start( aioseo()->core->db->db->posts . ' as p', true )
->select( '`p`.`ID`, `p`.`post_type`, `p`.`post_content`, `p`.`post_excerpt`, `p`.`post_modified_gmt`' )
->leftJoin( 'aioseo_posts as ap', '`ap`.`post_id` = `p`.`ID`' )
->whereRaw( '( `ap`.`id` IS NULL OR `p`.`post_modified_gmt` > `ap`.`image_scan_date` OR `ap`.`image_scan_date` IS NULL )' )
->whereRaw( "`p`.`post_status` IN ( 'publish', 'inherit' )" )
->whereRaw( "`p`.`post_type` IN ( '$postTypes' )" )
->limit( $postsPerScan )
->run()
->result();
if ( ! $posts ) {
aioseo()->actionScheduler->scheduleSingle( $this->imageScanAction, 15 * MINUTE_IN_SECONDS, [], true );
return;
}
foreach ( $posts as $post ) {
$this->scanPost( $post );
}
aioseo()->actionScheduler->scheduleSingle( $this->imageScanAction, 30, [], true );
}
/**
* Returns the image entries for a given post.
*
* @since 4.0.0
*
* @param \WP_Post|int $post The post object or ID.
* @return void
*/
public function scanPost( $post ) {
if ( is_numeric( $post ) ) {
$post = get_post( $post );
}
$this->post = $post;
if ( ! empty( $post->post_password ) ) {
$this->updatePost( $post->ID );
return;
}
if ( 'attachment' === $post->post_type ) {
if ( ! wp_attachment_is( 'image', $post->ID ) ) {
$this->updatePost( $post->ID );
return;
}
$image = $this->buildEntries( [ $post->ID ] );
$this->updatePost( $post->ID, $image );
return;
}
$images = $this->extract();
$images = $this->removeImageDimensions( $images );
$images = apply_filters( 'aioseo_sitemap_images', $images, $post );
// Limit to a 1,000 URLs, in accordance to Google's specifications.
$images = array_slice( $images, 0, 1000 );
$this->updatePost( $post->ID, $this->buildEntries( $images ) );
}
/**
* Returns the image entries for a given term.
*
* @since 4.0.0
*
* @param \WP_Term $term The term object.
* @return array The image entries.
*/
public function term( $term ) {
if ( aioseo()->sitemap->helpers->excludeImages() ) {
return [];
}
$id = get_term_meta( $term->term_id, 'thumbnail_id', true );
if ( ! $id ) {
return [];
}
return $this->buildEntries( [ $id ] );
}
/**
* Builds the image entries.
*
* @since 4.0.0
*
* @param array $images The images, consisting of attachment IDs or external URLs.
* @return array The image entries.
*/
private function buildEntries( $images ) {
$entries = [];
foreach ( $images as $image ) {
$idOrUrl = $this->getImageIdOrUrl( $image );
$imageUrl = is_numeric( $idOrUrl ) ? wp_get_attachment_url( $idOrUrl ) : $idOrUrl;
$imageUrl = aioseo()->sitemap->helpers->formatUrl( $imageUrl );
if ( ! $imageUrl || ! preg_match( $this->getImageExtensionRegexPattern(), (string) $imageUrl ) ) {
continue;
}
// If the image URL is not external, make it relative.
// This is important for users who scan their sites in a local/staging environment and then
// push the data to production.
if ( ! aioseo()->helpers->isExternalUrl( $imageUrl ) ) {
$imageUrl = aioseo()->helpers->makeUrlRelative( $imageUrl );
}
$entries[ $idOrUrl ] = [ 'image:loc' => $imageUrl ];
}
return array_values( $entries );
}
/**
* Returns the ID of the image if it's hosted on the site. Otherwise it returns the external URL.
*
* @since 4.1.3
*
* @param int|string $image The attachment ID or URL.
* @return int|string The attachment ID or URL.
*/
private function getImageIdOrUrl( $image ) {
if ( is_numeric( $image ) ) {
return $image;
}
$attachmentId = false;
if ( aioseo()->helpers->isValidAttachment( $image ) ) {
$attachmentId = aioseo()->helpers->attachmentUrlToPostId( $image );
}
return $attachmentId ? $attachmentId : $image;
}
/**
* Extracts all image URls and IDs from the post.
*
* @since 4.0.0
*
* @return array The image URLs and IDs.
*/
private function extract() {
$images = [];
if ( has_post_thumbnail( $this->post ) ) {
$images[] = get_the_post_thumbnail_url( $this->post );
}
// Get the galleries here before doShortcodes() runs below to prevent buggy behaviour.
// WordPress is supposed to only return the attached images but returns a different result if the shortcode has no valid attributes, so we need to grab them manually.
$images = array_merge( $images, $this->getPostGalleryImages() );
// Now, get the remaining images from image tags in the post content.
$parsedPostContent = do_blocks( $this->post->post_content );
$parsedPostContent = aioseo()->helpers->doShortcodes( $parsedPostContent, true, $this->post->ID );
$parsedPostContent = preg_replace( '/\s\s+/u', ' ', (string) trim( $parsedPostContent ) ); // Trim both internal and external whitespace.
// Get the images from any third-party plugins/themes that are active.
$thirdParty = new ThirdParty( $this->post, $parsedPostContent );
$images = array_merge( $images, $thirdParty->extract() );
preg_match_all( '#<(amp-)?img[^>]+src="([^">]+)"#', (string) $parsedPostContent, $matches );
foreach ( $matches[2] as $url ) {
$images[] = aioseo()->helpers->makeUrlAbsolute( $url );
}
return array_unique( $images );
}
/**
* Returns all images from WP Core post galleries.
*
* @since 4.2.2
*
* @return array[string] The image URLs.
*/
private function getPostGalleryImages() {
$images = [];
$galleries = get_post_galleries( $this->post, false );
foreach ( $galleries as $gallery ) {
foreach ( $gallery['src'] as $imageUrl ) {
$images[] = $imageUrl;
}
}
// Now, get rid of them so that we don't process the shortcodes again.
$regex = get_shortcode_regex( [ 'gallery' ] );
$this->post->post_content = preg_replace( "/$regex/i", '', (string) $this->post->post_content );
return $images;
}
/**
* Removes image dimensions from the slug.
*
* @since 4.0.0
*
* @param array $urls The image URLs.
* @return array $preparedUrls The formatted image URLs.
*/
private function removeImageDimensions( $urls ) {
$preparedUrls = [];
foreach ( $urls as $url ) {
$preparedUrls[] = aioseo()->helpers->removeImageDimensions( $url );
}
return array_unique( array_filter( $preparedUrls ) );
}
/**
* Stores the image data for a given post in our DB table.
*
* @since 4.0.5
*
* @param int $postId The post ID.
* @param array $images The images.
* @return void
*/
private function updatePost( $postId, $images = [] ) {
$post = \AIOSEO\Plugin\Common\Models\Post::getPost( $postId );
$meta = $post->exists() ? [] : aioseo()->migration->meta->getMigratedPostMeta( $postId );
$meta['post_id'] = $postId;
$meta['images'] = ! empty( $images ) ? $images : null;
$meta['image_scan_date'] = gmdate( 'Y-m-d H:i:s' );
$post->set( $meta );
$post->save();
}
/**
* Returns the image extension regex pattern.
*
* @since 4.2.2
*
* @return string
*/
public function getImageExtensionRegexPattern() {
static $pattern;
if ( null !== $pattern ) {
return $pattern;
}
$pattern = '/http.*\.(' . implode( '|', $this->supportedExtensions ) . ')$/i';
return $pattern;
}
} home/xbodynamge/dev/wp-content/plugins/all-in-one-seo-pack/app/Common/Schema/Graphs/Traits/Image.php0000644 00000005462 15114327560 0027271 0 ustar 00 <?php
namespace AIOSEO\Plugin\Common\Schema\Graphs\Traits;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Trait that handles images for the graphs.
*
* @since 4.2.5
*/
trait Image {
/**
* Builds the graph data for a given image with a given schema ID.
*
* @since 4.0.0
*
* @param int $imageId The image ID.
* @param string $graphId The graph ID (optional).
* @return array $data The image graph data.
*/
protected function image( $imageId, $graphId = '' ) {
$attachmentId = is_string( $imageId ) && ! is_numeric( $imageId ) ? aioseo()->helpers->attachmentUrlToPostId( $imageId ) : $imageId;
$imageUrl = wp_get_attachment_image_url( $attachmentId, 'full' );
$data = [
'@type' => 'ImageObject',
'url' => $imageUrl ? $imageUrl : $imageId,
];
if ( $graphId ) {
$baseUrl = aioseo()->schema->context['url'] ?? aioseo()->helpers->getUrl();
$data['@id'] = trailingslashit( $baseUrl ) . '#' . $graphId;
}
if ( ! $attachmentId ) {
return $data;
}
$metaData = wp_get_attachment_metadata( $attachmentId );
if ( $metaData && ! empty( $metaData['width'] ) && ! empty( $metaData['height'] ) ) {
$data['width'] = (int) $metaData['width'];
$data['height'] = (int) $metaData['height'];
}
$caption = $this->getImageCaption( $attachmentId );
if ( ! empty( $caption ) ) {
$data['caption'] = $caption;
}
return $data;
}
/**
* Get the image caption.
*
* @since 4.1.4
*
* @param int $attachmentId The attachment ID.
* @return string The caption.
*/
private function getImageCaption( $attachmentId ) {
$caption = wp_get_attachment_caption( $attachmentId );
if ( ! empty( $caption ) ) {
return $caption;
}
return get_post_meta( $attachmentId, '_wp_attachment_image_alt', true );
}
/**
* Returns the graph data for the avatar of a given user.
*
* @since 4.0.0
*
* @param int $userId The user ID.
* @param string $graphId The graph ID.
* @return array The graph data.
*/
protected function avatar( $userId, $graphId ) {
if ( ! get_option( 'show_avatars' ) ) {
return [];
}
$avatar = get_avatar_data( $userId );
if ( ! $avatar['found_avatar'] ) {
return [];
}
return array_filter( [
'@type' => 'ImageObject',
'@id' => aioseo()->schema->context['url'] . "#$graphId",
'url' => $avatar['url'],
'width' => $avatar['width'],
'height' => $avatar['height'],
'caption' => get_the_author_meta( 'display_name', $userId )
] );
}
/**
* Returns the graph data for the post's featured image.
*
* @since 4.2.5
*
* @return string The featured image URL.
*/
protected function getFeaturedImage() {
$post = aioseo()->helpers->getPost();
return has_post_thumbnail( $post ) ? $this->image( get_post_thumbnail_id() ) : '';
}
} home/xbodynamge/namtation/wp-content/plugins/all-in-one-seo-pack/app/Common/Sitemap/Image/Image.php 0000644 00000022536 15114367017 0027241 0 ustar 00 <?php
namespace AIOSEO\Plugin\Common\Sitemap\Image;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Determines which images are included in a post/term.
*
* @since 4.0.0
*/
class Image {
/**
* The image scan action name.
*
* @since 4.0.13
*
* @var string
*/
private $imageScanAction = 'aioseo_image_sitemap_scan';
/**
* The supported image extensions.
*
* @since 4.2.2
*
* @var array[string]
*/
public $supportedExtensions = [
'gif',
'heic',
'jpeg',
'jpg',
'png',
'svg',
'webp',
'ico'
];
/**
* The post object.
*
* @since 4.2.7
*
* @var \WP_Post
*/
private $post = null;
/**
* Class constructor.
*
* @since 4.0.5
*/
public function __construct() {
// Column may not have been created yet.
if ( ! aioseo()->core->db->columnExists( 'aioseo_posts', 'image_scan_date' ) ) {
return;
}
// NOTE: This needs to go above the is_admin check in order for it to run at all.
add_action( $this->imageScanAction, [ $this, 'scanPosts' ] );
// Don't schedule a scan if we are not in the admin.
if ( ! is_admin() ) {
return;
}
if ( wp_doing_ajax() || wp_doing_cron() ) {
return;
}
// Don't schedule a scan if an importer or the V3 migration is running.
// We'll do our scans there.
if (
aioseo()->importExport->isImportRunning() ||
aioseo()->migration->isMigrationRunning()
) {
return;
}
// Action Scheduler hooks.
add_action( 'init', [ $this, 'scheduleScan' ], 3001 );
}
/**
* Schedules the image sitemap scan.
*
* @since 4.0.5
*
* @return void
*/
public function scheduleScan() {
if (
! aioseo()->options->sitemap->general->enable ||
aioseo()->sitemap->helpers->excludeImages()
) {
return;
}
aioseo()->actionScheduler->scheduleSingle( $this->imageScanAction, 10 );
}
/**
* Scans posts for images.
*
* @since 4.0.5
*
* @return void
*/
public function scanPosts() {
if (
! aioseo()->options->sitemap->general->enable ||
aioseo()->sitemap->helpers->excludeImages()
) {
return;
}
$postsPerScan = apply_filters( 'aioseo_image_sitemap_posts_per_scan', 10 );
$postTypes = implode( "', '", aioseo()->helpers->getPublicPostTypes( true ) );
$posts = aioseo()->core->db
->start( aioseo()->core->db->db->posts . ' as p', true )
->select( '`p`.`ID`, `p`.`post_type`, `p`.`post_content`, `p`.`post_excerpt`, `p`.`post_modified_gmt`' )
->leftJoin( 'aioseo_posts as ap', '`ap`.`post_id` = `p`.`ID`' )
->whereRaw( '( `ap`.`id` IS NULL OR `p`.`post_modified_gmt` > `ap`.`image_scan_date` OR `ap`.`image_scan_date` IS NULL )' )
->whereRaw( "`p`.`post_status` IN ( 'publish', 'inherit' )" )
->whereRaw( "`p`.`post_type` IN ( '$postTypes' )" )
->limit( $postsPerScan )
->run()
->result();
if ( ! $posts ) {
aioseo()->actionScheduler->scheduleSingle( $this->imageScanAction, 15 * MINUTE_IN_SECONDS, [], true );
return;
}
foreach ( $posts as $post ) {
$this->scanPost( $post );
}
aioseo()->actionScheduler->scheduleSingle( $this->imageScanAction, 30, [], true );
}
/**
* Returns the image entries for a given post.
*
* @since 4.0.0
*
* @param \WP_Post|int $post The post object or ID.
* @return void
*/
public function scanPost( $post ) {
if ( is_numeric( $post ) ) {
$post = get_post( $post );
}
$this->post = $post;
if ( ! empty( $post->post_password ) ) {
$this->updatePost( $post->ID );
return;
}
if ( 'attachment' === $post->post_type ) {
if ( ! wp_attachment_is( 'image', $post->ID ) ) {
$this->updatePost( $post->ID );
return;
}
$image = $this->buildEntries( [ $post->ID ] );
$this->updatePost( $post->ID, $image );
return;
}
$images = $this->extract();
$images = $this->removeImageDimensions( $images );
$images = apply_filters( 'aioseo_sitemap_images', $images, $post );
// Limit to a 1,000 URLs, in accordance to Google's specifications.
$images = array_slice( $images, 0, 1000 );
$this->updatePost( $post->ID, $this->buildEntries( $images ) );
}
/**
* Returns the image entries for a given term.
*
* @since 4.0.0
*
* @param \WP_Term $term The term object.
* @return array The image entries.
*/
public function term( $term ) {
if ( aioseo()->sitemap->helpers->excludeImages() ) {
return [];
}
$id = get_term_meta( $term->term_id, 'thumbnail_id', true );
if ( ! $id ) {
return [];
}
return $this->buildEntries( [ $id ] );
}
/**
* Builds the image entries.
*
* @since 4.0.0
*
* @param array $images The images, consisting of attachment IDs or external URLs.
* @return array The image entries.
*/
private function buildEntries( $images ) {
$entries = [];
foreach ( $images as $image ) {
$idOrUrl = $this->getImageIdOrUrl( $image );
$imageUrl = is_numeric( $idOrUrl ) ? wp_get_attachment_url( $idOrUrl ) : $idOrUrl;
$imageUrl = aioseo()->sitemap->helpers->formatUrl( $imageUrl );
if ( ! $imageUrl || ! preg_match( $this->getImageExtensionRegexPattern(), (string) $imageUrl ) ) {
continue;
}
// If the image URL is not external, make it relative.
// This is important for users who scan their sites in a local/staging environment and then
// push the data to production.
if ( ! aioseo()->helpers->isExternalUrl( $imageUrl ) ) {
$imageUrl = aioseo()->helpers->makeUrlRelative( $imageUrl );
}
$entries[ $idOrUrl ] = [ 'image:loc' => $imageUrl ];
}
return array_values( $entries );
}
/**
* Returns the ID of the image if it's hosted on the site. Otherwise it returns the external URL.
*
* @since 4.1.3
*
* @param int|string $image The attachment ID or URL.
* @return int|string The attachment ID or URL.
*/
private function getImageIdOrUrl( $image ) {
if ( is_numeric( $image ) ) {
return $image;
}
$attachmentId = false;
if ( aioseo()->helpers->isValidAttachment( $image ) ) {
$attachmentId = aioseo()->helpers->attachmentUrlToPostId( $image );
}
return $attachmentId ? $attachmentId : $image;
}
/**
* Extracts all image URls and IDs from the post.
*
* @since 4.0.0
*
* @return array The image URLs and IDs.
*/
private function extract() {
$images = [];
if ( has_post_thumbnail( $this->post ) ) {
$images[] = get_the_post_thumbnail_url( $this->post );
}
// Get the galleries here before doShortcodes() runs below to prevent buggy behaviour.
// WordPress is supposed to only return the attached images but returns a different result if the shortcode has no valid attributes, so we need to grab them manually.
$images = array_merge( $images, $this->getPostGalleryImages() );
// Now, get the remaining images from image tags in the post content.
$parsedPostContent = do_blocks( $this->post->post_content );
$parsedPostContent = aioseo()->helpers->doShortcodes( $parsedPostContent, true, $this->post->ID );
$parsedPostContent = preg_replace( '/\s\s+/u', ' ', (string) trim( $parsedPostContent ) ); // Trim both internal and external whitespace.
// Get the images from any third-party plugins/themes that are active.
$thirdParty = new ThirdParty( $this->post, $parsedPostContent );
$images = array_merge( $images, $thirdParty->extract() );
preg_match_all( '#<(amp-)?img[^>]+src="([^">]+)"#', (string) $parsedPostContent, $matches );
foreach ( $matches[2] as $url ) {
$images[] = aioseo()->helpers->makeUrlAbsolute( $url );
}
return array_unique( $images );
}
/**
* Returns all images from WP Core post galleries.
*
* @since 4.2.2
*
* @return array[string] The image URLs.
*/
private function getPostGalleryImages() {
$images = [];
$galleries = get_post_galleries( $this->post, false );
foreach ( $galleries as $gallery ) {
foreach ( $gallery['src'] as $imageUrl ) {
$images[] = $imageUrl;
}
}
// Now, get rid of them so that we don't process the shortcodes again.
$regex = get_shortcode_regex( [ 'gallery' ] );
$this->post->post_content = preg_replace( "/$regex/i", '', (string) $this->post->post_content );
return $images;
}
/**
* Removes image dimensions from the slug.
*
* @since 4.0.0
*
* @param array $urls The image URLs.
* @return array $preparedUrls The formatted image URLs.
*/
private function removeImageDimensions( $urls ) {
$preparedUrls = [];
foreach ( $urls as $url ) {
$preparedUrls[] = aioseo()->helpers->removeImageDimensions( $url );
}
return array_unique( array_filter( $preparedUrls ) );
}
/**
* Stores the image data for a given post in our DB table.
*
* @since 4.0.5
*
* @param int $postId The post ID.
* @param array $images The images.
* @return void
*/
private function updatePost( $postId, $images = [] ) {
$post = \AIOSEO\Plugin\Common\Models\Post::getPost( $postId );
$meta = $post->exists() ? [] : aioseo()->migration->meta->getMigratedPostMeta( $postId );
$meta['post_id'] = $postId;
$meta['images'] = ! empty( $images ) ? $images : null;
$meta['image_scan_date'] = gmdate( 'Y-m-d H:i:s' );
$post->set( $meta );
$post->save();
}
/**
* Returns the image extension regex pattern.
*
* @since 4.2.2
*
* @return string
*/
public function getImageExtensionRegexPattern() {
static $pattern;
if ( null !== $pattern ) {
return $pattern;
}
$pattern = '/http.*\.(' . implode( '|', $this->supportedExtensions ) . ')$/i';
return $pattern;
}
} home/xbodynamge/dev/wp-content/plugins/all-in-one-seo-pack/app/Common/Social/Image.php 0000644 00000017435 15114410062 0024602 0 ustar 00 <?php
namespace AIOSEO\Plugin\Common\Social;
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
use AIOSEO\Plugin\Common\Models;
/**
* Handles the Open Graph and Twitter Image.
*
* @since 4.0.0
*/
class Image {
/**
* The type of image ("facebook" or "twitter").
*
* @since 4.1.6.2
*
* @var string
*/
protected $type;
/**
* The post object.
*
* @since 4.1.6.2
*
* @var \WP_Post
*/
private $post;
/**
* The default thumbnail size.
*
* @since 4.0.0
*
* @var string
*/
protected $thumbnailSize;
/**
* Whether or not to use the cached images.
*
* @since 4.1.6
*
* @var boolean
*/
public $useCache = true;
/**
* Returns the Facebook or Twitter image.
*
* @since 4.0.0
*
* @param string $type The type ("Facebook" or "Twitter").
* @param string $imageSource The image source.
* @param \WP_Post|null $post The post object.
* @return string|array The image data.
*/
public function getImage( $type, $imageSource, $post = null ) {
$this->type = $type;
$this->post = $post;
$this->thumbnailSize = apply_filters( 'aioseo_thumbnail_size', 'fullsize' );
$hash = md5( wp_json_encode( [ $type, $imageSource, $post ] ) );
static $images = [];
if ( isset( $images[ $hash ] ) ) {
return $images[ $hash ];
}
if ( 'auto' === $imageSource && aioseo()->helpers->getPostPageBuilderName( $post->ID ) ) {
$imageSource = 'default';
}
if ( is_a( $this->post, 'WP_Post' ) ) {
switch ( $imageSource ) {
case 'featured':
$image = $this->getFeaturedImage();
break;
case 'attach':
$image = $this->getFirstAttachedImage();
break;
case 'content':
$image = $this->getFirstImageInContent();
break;
case 'author':
$image = $this->getAuthorAvatar();
break;
case 'auto':
$image = $this->getFirstAvailableImage();
break;
case 'custom':
$image = $this->getCustomFieldImage();
break;
case 'custom_image':
$metaData = aioseo()->meta->metaData->getMetaData( $post );
if ( empty( $metaData ) ) {
break;
}
$image = 'facebook' === strtolower( $this->type )
? $metaData->og_image_custom_url
: $metaData->twitter_image_custom_url;
break;
case 'default':
default:
$image = aioseo()->options->social->{$this->type}->general->defaultImagePosts;
}
}
if ( empty( $image ) ) {
$image = aioseo()->options->social->{$this->type}->general->defaultImagePosts;
}
if ( is_array( $image ) ) {
$images[ $hash ] = $image;
return $images[ $hash ];
}
$imageWithoutDimensions = aioseo()->helpers->removeImageDimensions( $image );
$attachmentId = aioseo()->helpers->attachmentUrlToPostId( $imageWithoutDimensions );
$images[ $hash ] = $attachmentId ? wp_get_attachment_image_src( $attachmentId, $this->thumbnailSize ) : $image;
return $images[ $hash ];
}
/**
* Returns the Featured Image for the post.
*
* @since 4.0.0
*
* @return array The image data.
*/
private function getFeaturedImage() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
$imageId = get_post_thumbnail_id( $this->post->ID );
return $imageId ? wp_get_attachment_image_src( $imageId, $this->thumbnailSize ) : '';
}
/**
* Returns the first attached image.
*
* @since 4.0.0
*
* @return string The image data.
*/
private function getFirstAttachedImage() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
if ( 'attachment' === get_post_type( $this->post->ID ) ) {
return wp_get_attachment_image_src( $this->post->ID, $this->thumbnailSize );
}
$attachments = get_children(
[
'post_parent' => $this->post->ID,
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => 'image',
]
);
return $attachments && count( $attachments ) ? wp_get_attachment_image_src( array_values( $attachments )[0]->ID, $this->thumbnailSize ) : '';
}
/**
* Returns the first image found in the post content.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getFirstImageInContent() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
$postContent = aioseo()->helpers->getPostContent( $this->post );
preg_match_all( '|<img.*?src=[\'"](.*?)[\'"].*?>|i', (string) $postContent, $matches ); // phpcs:ignore PluginCheck.CodeAnalysis.ImageFunctions.NonEnqueuedImage
// Ignore cover block background image - WP >= 5.7.
if ( ! empty( $matches[0] ) && apply_filters( 'aioseo_social_image_ignore_cover_block', true, $this->post, $matches ) ) {
foreach ( $matches[0] as $key => $match ) {
if ( false !== stripos( $match, 'wp-block-cover__image-background' ) ) {
unset( $matches[1][ $key ] );
}
}
}
return ! empty( $matches[1] ) ? current( $matches[1] ) : '';
}
/**
* Returns the author avatar.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getAuthorAvatar() {
$avatar = get_avatar( $this->post->post_author, 300 );
preg_match( "/src='(.*?)'/i", (string) $avatar, $matches );
return ! empty( $matches[1] ) ? $matches[1] : '';
}
/**
* Returns the first available image.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getFirstAvailableImage() {
// Disable the cache.
$this->useCache = false;
$image = $this->getCustomFieldImage();
if ( ! $image ) {
$image = $this->getFeaturedImage();
}
if ( ! $image ) {
$image = $this->getFirstAttachedImage();
}
if ( ! $image ) {
$image = $this->getFirstImageInContent();
}
if ( ! $image && 'twitter' === strtolower( $this->type ) ) {
$image = aioseo()->options->social->twitter->homePage->image;
}
// Enable the cache.
$this->useCache = true;
return $image ? $image : aioseo()->options->social->facebook->homePage->image;
}
/**
* Returns the image from a custom field.
*
* @since 4.0.0
*
* @return string The image URL.
*/
private function getCustomFieldImage() {
$cachedImage = $this->getCachedImage();
if ( $cachedImage ) {
return $cachedImage;
}
$prefix = 'facebook' === strtolower( $this->type ) ? 'og_' : 'twitter_';
$aioseoPost = Models\Post::getPost( $this->post->ID );
$customFields = ! empty( $aioseoPost->{ $prefix . 'image_custom_fields' } )
? $aioseoPost->{ $prefix . 'image_custom_fields' }
: aioseo()->options->social->{$this->type}->general->customFieldImagePosts;
if ( ! $customFields ) {
return '';
}
$customFields = explode( ',', $customFields );
foreach ( $customFields as $customField ) {
$image = get_post_meta( $this->post->ID, $customField, true );
if ( ! empty( $image ) ) {
$image = is_array( $image ) ? $image[0] : $image;
return is_numeric( $image )
? wp_get_attachment_image_src( $image, $this->thumbnailSize )
: $image;
}
}
return '';
}
/**
* Returns the cached image if there is one.
*
* @since 4.1.6.2
*
* @param \WP_Term $object The object for which we need to get the cached image.
* @return string|array The image URL or data.
*/
protected function getCachedImage( $object = null ) {
if ( null === $object ) {
// This isn't null if we call it from the Pro class.
$object = $this->post;
}
$metaData = aioseo()->meta->metaData->getMetaData( $object );
switch ( $this->type ) {
case 'facebook':
if ( ! empty( $metaData->og_image_url ) && $this->useCache ) {
return aioseo()->meta->metaData->getCachedOgImage( $metaData );
}
break;
case 'twitter':
if ( ! empty( $metaData->twitter_image_url ) && $this->useCache ) {
return $metaData->twitter_image_url;
}
break;
default:
break;
}
return '';
}
}