l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } l ) { return ''; } return $image_url; } /** * Gets the first image url of a gallery. * * @param int $post_id Post ID to use. * * @return string The image url or an empty string when not found. */ public function get_gallery_image( $post_id ) { $post = \get_post( $post_id ); if ( \strpos( $post->post_content, '[gallery' ) === false ) { return ''; } $images = \get_post_gallery_images( $post ); if ( empty( $images ) ) { return ''; } return \reset( $images ); } /** * Gets the image url from the term content. * * @param int $term_id The term id to extract the images from. * * @return string The image url or an empty string when not found. */ public function get_term_content_image( $term_id ) { $image_url = $this->get_first_content_image_for_term( $term_id ); if ( $image_url === null ) { return ''; } return $image_url; } /** * Retrieves the caption for an attachment. * * @param int $attachment_id Attachment ID. * * @return string The caption when found, empty string when no caption is found. */ public function get_caption( $attachment_id ) { $caption = \wp_get_attachment_caption( $attachment_id ); if ( ! empty( $caption ) ) { return $caption; } $caption = \get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ); if ( ! empty( $caption ) ) { return $caption; } return ''; } /** * Retrieves the attachment metadata. * * @param int $attachment_id Attachment ID. * * @return array The metadata, empty array when no metadata is found. */ public function get_metadata( $attachment_id ) { $metadata = \wp_get_attachment_metadata( $attachment_id ); if ( ! $metadata || ! \is_array( $metadata ) ) { return []; } return $metadata; } /** * Retrieves the attachment image url. * * @param int $attachment_id Attachment ID. * @param string $size The size to get. * * @return string The url when found, empty string otherwise. */ public function get_attachment_image_url( $attachment_id, $size ) { $url = \wp_get_attachment_image_url( $attachment_id, $size ); if ( ! $url ) { return ''; } return $url; } /** * Find the right version of an image based on size. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id Attachment ID. * @param string $size Size name. * * @return array|false Returns an array with image data on success, false on failure. */ public function get_image( $attachment_id, $size ) { return WPSEO_Image_Utils::get_image( $attachment_id, $size ); } /** * Retrieves the best attachment variation for the given attachment. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $attachment_id The attachment id. * * @return bool|string The attachment url or false when no variations found. */ public function get_best_attachment_variation( $attachment_id ) { $variations = WPSEO_Image_Utils::get_variations( $attachment_id ); $variations = WPSEO_Image_Utils::filter_usable_file_size( $variations ); // If we are left without variations, there is no valid variation for this attachment. if ( empty( $variations ) ) { return false; } // The variations are ordered so the first variations is by definition the best one. return \reset( $variations ); } /** * Find an attachment ID for a given URL. * * @param string $url The URL to find the attachment for. * @param bool $use_link_table Whether the SEO Links table will be used to retrieve the id. * * @return int The found attachment ID, or 0 if none was found. */ public function get_attachment_by_url( $url, $use_link_table = true ) { // Don't try to do this for external URLs. $parsed_url = \wp_parse_url( $url ); if ( $this->url_helper->get_link_type( $parsed_url ) === SEO_Links::TYPE_EXTERNAL ) { return 0; } /** The `wpseo_force_creating_and_using_attachment_indexables` filter is documented in indexable-link-builder.php */ if ( ! $this->options_helper->get( 'disable-attachment' ) || \apply_filters( 'wpseo_force_creating_and_using_attachment_indexables', false ) ) { // Strip out the size part of an image URL. $url = \preg_replace( '/(.*)-\d+x\d+\.(jpeg|jpg|png|gif)$/', '$1.$2', $url ); $indexable = $this->indexable_repository->find_by_permalink( $url ); if ( $indexable && $indexable->object_type === 'post' && $indexable->object_sub_type === 'attachment' ) { return $indexable->object_id; } $post_id = WPSEO_Image_Utils::get_attachment_by_url( $url ); if ( $post_id !== 0 ) { // Find the indexable, this triggers creating it so it can be found next time. $this->indexable_repository->find_by_id_and_type( $post_id, 'post' ); } return $post_id; } if ( ! $use_link_table ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } $cache_key = 'attachment_seo_link_object_' . \md5( $url ); $found = false; $link = \wp_cache_get( $cache_key, 'yoast-seo-attachment-link', false, $found ); if ( $found === false ) { $link = $this->seo_links_repository->find_one_by_url( $url ); \wp_cache_set( $cache_key, $link, 'yoast-seo-attachment-link', \MINUTE_IN_SECONDS ); } if ( ! \is_a( $link, SEO_Links::class ) ) { return WPSEO_Image_Utils::get_attachment_by_url( $url ); } return $link->target_post_id; } /** * Retrieves an attachment ID for an image uploaded in the settings. * * Due to self::get_attachment_by_url returning 0 instead of false. * 0 is also a possibility when no ID is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param string $setting The setting the image is stored in. * * @return int|bool The attachment id, or false or 0 if no ID is available. */ public function get_attachment_id_from_settings( $setting ) { return WPSEO_Image_Utils::get_attachment_id_from_settings( $setting ); } /** * Based on and image ID return array with the best variation of that image. If it's not saved to the DB, save it * to an option. * * @param string $setting The setting name. Should be company or person. * * @return array|bool Array with image details when the image is found, boolean when it's not found. */ public function get_attachment_meta_from_settings( $setting ) { $image_meta = $this->options_helper->get( $setting . '_meta', false ); if ( ! $image_meta ) { $image_id = $this->options_helper->get( $setting . '_id', false ); if ( $image_id ) { // There is not an option to put a URL in an image field in the settings anymore, only to upload it through the media manager. // This means an attachment always exists, so doing this is only needed once. $image_meta = $this->get_best_attachment_variation( $image_id ); if ( $image_meta ) { $this->options_helper->set( $setting . '_meta', $image_meta ); } } } return $image_meta; } /** * Retrieves the first usable content image for a post. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $post_id The post id to extract the images from. * * @return string|null */ protected function get_first_usable_content_image_for_post( $post_id ) { return WPSEO_Image_Utils::get_first_usable_content_image_for_post( $post_id ); } /** * Gets the term's first usable content image. Null if none is available. * * @codeCoverageIgnore - We have to write test when this method contains own code. * * @param int $term_id The term id. * * @return string|null The image URL. */ protected function get_first_content_image_for_term( $term_id ) { return WPSEO_Image_Utils::get_first_content_image_for_term( $term_id ); } } Config::get_hook_prefix() . 'show_optin_option_name', $option_name, $stellar_slug ); } /** * Helper function to determine if the modal should be rendered. * * @since 1.0.0 * @since 2.0.0 - update to handle passed in stellar_slug. * * @param string $stellar_slug The stellar slug to get the option name for. * * @return boolean */ public function should_render( string $stellar_slug ) { return (bool) get_option( $this->get_option_name( $stellar_slug ), false ); } /** * Renders the modal if it should be rendered. * * @since 1.0.0 * @since 2.0.0 - Add ability to render multiple modals. * * @param string $stellar_slug The stellar slug for which the modal should be rendered. * * @return void */ public function maybe_render( string $stellar_slug ) { if ( $this->should_render( $stellar_slug ) ) { $this->render( $stellar_slug ); } } /** * Gets an array of opted-in plugin names. * * @since 1.0.0 * * @return string[] */ public function get_opted_in_plugin_names() { $option = Config::get_container()->get( Status::class )->get_option(); $site_plugins_dir = Config::get_container()->get( Core::SITE_PLUGIN_DIR ); $opted_in_plugins = []; foreach ( $option['plugins'] as $plugin ) { if ( true !== $plugin['optin'] ) { continue; } $plugin_path = trailingslashit( $site_plugins_dir ) . $plugin['wp_slug']; if ( ! file_exists( $plugin_path ) ) { continue; } $plugin_data = get_plugin_data( $plugin_path ); if ( empty( $plugin_data['Name'] ) ) { continue; } $opted_in_plugins[] = $plugin_data['Name']; } return $opted_in_plugins; } /** * Gets the primary message displayed on the opt-in modal. * * @param string $user_name The display name of the user. * @param string $plugin_name The name of the plugin. * * @return string */ public function get_intro( $user_name, $plugin_name ) { return sprintf( // Translators: The user name and the plugin name. esc_html__( 'Hi, %1$s! This is an invitation to help our StellarWP community. If you opt-in, some data about your usage of %2$s and future StellarWP Products will be shared with our teams (so they can work their butts off to improve). We will also share some helpful info on WordPress, and our products from time to time. And if you skip this, that’s okay! Our products still work just fine.', 'stellarwp-telemetry' ), $user_name, $plugin_name ); } }
Fatal error: Uncaught Error: Class "iThemesSecurity\Strauss\StellarWP\Telemetry\Opt_In\Opt_In_Template" not found in /htdocs/wp-content/plugins/better-wp-security/vendor-prod/stellarwp/telemetry/src/Telemetry/Core.php:153 Stack trace: #0 /htdocs/wp-content/plugins/better-wp-security/core/lib/Stellar_Container.php(38): iThemesSecurity\Strauss\StellarWP\Telemetry\Core::iThemesSecurity\Strauss\StellarWP\Telemetry\{closure}() #1 /htdocs/wp-content/plugins/better-wp-security/vendor-prod/pimple/pimple/src/Pimple/Container.php(121): iThemesSecurity\Lib\Stellar_Container::iThemesSecurity\Lib\{closure}(Object(iThemesSecurity\Strauss\Pimple\Container)) #2 /htdocs/wp-content/plugins/better-wp-security/core/lib/Stellar_Container.php(20): iThemesSecurity\Strauss\Pimple\Container->offsetGet('iThemesSecurity...') #3 /htdocs/wp-content/plugins/better-wp-security/vendor-prod/stellarwp/telemetry/src/Telemetry/Opt_In/Opt_In_Subscriber.php(128): iThemesSecurity\Lib\Stellar_Container->get('iThemesSecurity...') #4 /htdocs/wp-includes/class-wp-hook.php(324): iThemesSecurity\Strauss\StellarWP\Telemetry\Opt_In\Opt_In_Subscriber->initialize_optin_option('') #5 /htdocs/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters(NULL, Array) #6 /htdocs/wp-includes/plugin.php(517): WP_Hook->do_action(Array) #7 /htdocs/wp-settings.php(704): do_action('init') #8 /htdocs/wp-config.php(98): require_once('/htdocs/wp-sett...') #9 /htdocs/wp-load.php(50): require_once('/htdocs/wp-conf...') #10 /htdocs/wp-blog-header.php(13): require_once('/htdocs/wp-load...') #11 /htdocs/index.php(17): require('/htdocs/wp-blog...') #12 {main} thrown in /htdocs/wp-content/plugins/better-wp-security/vendor-prod/stellarwp/telemetry/src/Telemetry/Core.php on line 153