PDF rausgenommen

This commit is contained in:
aschwarz
2023-01-23 11:03:31 +01:00
parent 82d562a322
commit a6523903eb
28078 changed files with 4247552 additions and 2 deletions

View File

@@ -0,0 +1,130 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Indexable.
*/
abstract class WPSEO_Indexable {
/**
* The updateable fields.
*
* @var array
*/
protected $updateable_fields = array();
/**
* The indexable's data.
*
* @var array
*/
protected $data;
/**
* The available validators to run.
*
* @var array
*/
protected $validators = array(
'WPSEO_Object_Type_Validator',
'WPSEO_Link_Validator',
'WPSEO_Keyword_Validator',
'WPSEO_Meta_Values_Validator',
'WPSEO_OpenGraph_Validator',
'WPSEO_Robots_Validator',
'WPSEO_Twitter_Validator',
);
/**
* Indexable constructor.
*
* @param array $data The data to use to construct the indexable.
*/
public function __construct( $data ) {
$this->validate_data( $data );
$this->data = $data;
}
/**
* Converts the meta value to a boolean value.
*
* @param string $value The value to convert.
*
* @return bool|null The converted value.
*/
protected static function get_robots_noindex_value( $value ) {
if ( $value === '1' ) {
return true;
}
if ( $value === '2' ) {
return false;
}
return null;
}
/**
* Determines whether the advanced robot metas value contains the passed value.
*
* @param int $object_id The ID of the object to check.
* @param string $value The name of the advanced robots meta value to look for.
*
* @return bool Whether or not the advanced robots meta values contains the passed string.
*/
protected static function has_advanced_meta_value( $object_id, $value ) {
return strpos( WPSEO_Meta::get_value( 'meta-robots-adv', $object_id ), $value ) !== false;
}
/**
* Validates the data.
*
* @param array $data The data to validate.
*
* @return bool True if all validators have successfully validated.
*/
protected function validate_data( $data ) {
foreach ( $this->validators as $validator ) {
// This is necessary to run under PHP 5.2.
$validator_instance = new $validator();
$validator_instance->validate( $data );
}
return true;
}
/**
* Updates the data and returns a new instance.
*
* @param array $data The data to update into a new instance.
*
* @return WPSEO_Indexable A new instance with the updated data.
*/
abstract public function update( $data );
/**
* Filters out data that isn't considered updateable and returns a valid dataset.
*
* @param array $data The dataset to filter.
*
* @return array The updateable dataset.
*/
public function filter_updateable_data( $data ) {
return array_intersect_key( $data, array_flip( $this->updateable_fields ) );
}
/**
* Returns the data as an array.
*
* @return array The data as an array.
*/
public function to_array() {
return $this->data;
}
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Post_Indexable.
*/
abstract class WPSEO_Object_Type {
/**
* The ID of the object.
*
* @var int
*/
protected $id;
/**
* The type of the object.
*
* @var string
*/
protected $type;
/**
* The subtype of the object.
*
* @var string
*/
protected $sub_type;
/**
* The permalink of the object.
*
* @var string
*/
protected $permalink;
/**
* WPSEO_Object_Type constructor.
*
* @param int $id The ID of the object.
* @param string $type The type of object.
* @param string $subtype The subtype of the object.
* @param string $permalink The permalink of the object.
*/
public function __construct( $id, $type, $subtype, $permalink ) {
$this->id = (int) $id;
$this->type = $type;
$this->sub_type = $subtype;
$this->permalink = $permalink;
}
/**
* Gets the ID.
*
* @return int The ID.
*/
public function get_id() {
return $this->id;
}
/**
* Gets the type.
*
* @return string The type.
*/
public function get_type() {
return $this->type;
}
/**
* Gets the subtype.
*
* @return string The subtype.
*/
public function get_subtype() {
return $this->sub_type;
}
/**
* Gets the permalink.
*
* @return string The permalink.
*/
public function get_permalink() {
return $this->permalink;
}
/**
* Determines whether the passed type is equal to the object's type.
*
* @param string $type The type to check.
*
* @return bool Whether or not the passed type is equal.
*/
public function is_type( $type ) {
return $this->type === $type;
}
/**
* Determines whether the passed subtype is equal to the object's subtype.
*
* @param string $sub_type The subtype to check.
*
* @return bool Whether or not the passed subtype is equal.
*/
public function is_subtype( $sub_type ) {
return $this->sub_type === $sub_type;
}
}

View File

@@ -0,0 +1,103 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Post_Indexable.
*/
class WPSEO_Post_Indexable extends WPSEO_Indexable {
/**
* The updateable fields.
*
* @var array
*/
protected $updateable_fields = array(
'canonical',
'title',
'description',
'breadcrumb_title',
'og_title',
'og_description',
'og_image',
'twitter_title',
'twitter_description',
'twitter_image',
'is_robots_noindex',
'is_robots_nofollow',
'is_robots_noarchive',
'is_robots_noimageindex',
'is_robots_nosnippet',
'primary_focus_keyword',
'primary_focus_keyword',
'primary_focus_keyword_score',
'readability_score',
'is_cornerstone',
);
/**
* Creates a new Indexable from a passed object.
*
* @param int $object_id The object ID to create the object for.
*
* @return WPSEO_Indexable The indexable.
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the passed ID is not for an object of type 'post'.
*/
public static function from_object( $object_id ) {
$post = WPSEO_Post_Object_Type::from_object( $object_id );
$link_count = new WPSEO_Link_Column_Count();
$link_count->set( array( $object_id ) );
$post_object_id = $post->get_id();
return new self(
array(
'object_id' => $post_object_id,
'object_type' => $post->get_type(),
'object_subtype' => $post->get_subtype(),
'permalink' => $post->get_permalink(),
'canonical' => WPSEO_Meta::get_value( 'canonical', $post_object_id ),
'title' => WPSEO_Meta::get_value( 'title', $post_object_id ),
'description' => WPSEO_Meta::get_value( 'metadesc', $post_object_id ),
'breadcrumb_title' => WPSEO_Meta::get_value( 'bctitle', $post_object_id ),
'og_title' => WPSEO_Meta::get_value( 'opengraph-title', $post_object_id ),
'og_description' => WPSEO_Meta::get_value( 'opengraph-description', $post_object_id ),
'og_image' => WPSEO_Meta::get_value( 'opengraph-image', $post_object_id ),
'twitter_title' => WPSEO_Meta::get_value( 'twitter-title', $post_object_id ),
'twitter_description' => WPSEO_Meta::get_value( 'twitter-description', $post_object_id ),
'twitter_image' => WPSEO_Meta::get_value( 'twitter-image', $post_object_id ),
'is_robots_noindex' => self::get_robots_noindex_value( WPSEO_Meta::get_value( 'meta-robots-noindex', $post_object_id ) ),
'is_robots_nofollow' => WPSEO_Meta::get_value( 'meta-robots-nofollow', $post_object_id ) === '1',
'is_robots_noarchive' => self::has_advanced_meta_value( $post_object_id, 'noarchive' ),
'is_robots_noimageindex' => self::has_advanced_meta_value( $post_object_id, 'noimageindex' ),
'is_robots_nosnippet' => self::has_advanced_meta_value( $post_object_id, 'nosnippet' ),
'primary_focus_keyword' => WPSEO_Meta::get_value( 'focuskw', $post_object_id ),
'primary_focus_keyword_score' => (int) WPSEO_Meta::get_value( 'linkdex', $post_object_id ),
'readability_score' => (int) WPSEO_Meta::get_value( 'content_score', $post_object_id ),
'is_cornerstone' => WPSEO_Meta::get_value( 'is_cornerstone', $post_object_id ) === '1',
'link_count' => (int) $link_count->get( $post_object_id ),
'incoming_link_count' => (int) $link_count->get( $post_object_id, 'incoming_link_count' ),
'created_at' => null,
'updated_at' => null,
)
);
}
/**
* Updates the data and returns a new instance.
*
* @param array $data The data to update into a new instance.
*
* @return WPSEO_Indexable A new instance with the updated data.
*/
public function update( $data ) {
$data = array_merge( $this->data, $this->filter_updateable_data( $data ) );
return new self( $data );
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Post_Object_Type.
*/
class WPSEO_Post_Object_Type extends WPSEO_Object_Type {
/**
* Creates a new instance based on the passed object ID.
*
* @param int $object_id The object ID to base the object on.
*
* @return WPSEO_Post_Object_Type The class instance.
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the post is null.
*/
public static function from_object( $object_id ) {
$post = get_post( $object_id );
if ( $post === null ) {
throw WPSEO_Invalid_Argument_Exception::unknown_object( $object_id, 'post' );
}
return new self( $object_id, 'post', get_post_type( $object_id ), get_permalink( $object_id ) );
}
}

View File

@@ -0,0 +1,126 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Term_Indexable.
*/
class WPSEO_Term_Indexable extends WPSEO_Indexable {
/**
* The updateable fields.
*
* @var array
*/
protected $updateable_fields = array(
'canonical',
'title',
'description',
'breadcrumb_title',
'og_title',
'og_description',
'og_image',
'twitter_title',
'twitter_description',
'twitter_image',
'is_robots_noindex',
'primary_focus_keyword',
'primary_focus_keyword',
'primary_focus_keyword_score',
'readability_score',
);
/**
* Creates a new Indexable from a passed object.
*
* @param int $object_id The object ID to create the object for.
*
* @return WPSEO_Indexable The indexable.
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the passed ID is not for an object of type 'term'.
*/
public static function from_object( $object_id ) {
$term = WPSEO_Term_Object_Type::from_object( $object_id );
$term_object_id = $term->get_id();
return new self(
array(
'object_id' => $term_object_id,
'object_type' => $term->get_type(),
'object_subtype' => $term->get_subtype(),
'permalink' => $term->get_permalink(),
'canonical' => self::get_meta_value( 'canonical', $term ),
'title' => self::get_meta_value( 'title', $term ),
'description' => self::get_meta_value( 'desc', $term ),
'breadcrumb_title' => self::get_meta_value( 'bctitle', $term ),
'og_title' => self::get_meta_value( 'opengraph-title', $term ),
'og_description' => self::get_meta_value( 'opengraph-description', $term ),
'og_image' => self::get_meta_value( 'opengraph-image', $term ),
'twitter_title' => self::get_meta_value( 'twitter-title', $term ),
'twitter_description' => self::get_meta_value( 'twitter-description', $term ),
'twitter_image' => self::get_meta_value( 'twitter-image', $term ),
'is_robots_noindex' => self::get_robots_noindex_value( self::get_meta_value( 'noindex', $term ) ),
'is_robots_nofollow' => null,
'is_robots_noarchive' => null,
'is_robots_noimageindex' => null,
'is_robots_nosnippet' => null,
'primary_focus_keyword' => self::get_meta_value( 'focuskw', $term ),
'primary_focus_keyword_score' => (int) self::get_meta_value( 'linkdex', $term ),
'readability_score' => (int) self::get_meta_value( 'content_score', $term ),
'is_cornerstone' => false,
'link_count' => null,
'incoming_link_count' => null,
'created_at' => null,
'updated_at' => null,
)
);
}
/**
* Updates the data and returns a new instance.
*
* @param array $data The data to update into a new instance.
*
* @return WPSEO_Indexable A new instance with the updated data.
*/
public function update( $data ) {
$data = array_merge( $this->data, $this->filter_updateable_data( $data ) );
return new self( $data );
}
/**
* Returns the needed term meta field.
*
* @param string $field The requested field.
* @param WPSEO_Term_Object_Type $term The term object.
*
* @return bool|mixed The value of the requested field.
*/
protected static function get_meta_value( $field, $term ) {
return WPSEO_Taxonomy_Meta::get_term_meta( $term->get_id(), $term->get_subtype(), $field );
}
/**
* Converts the meta value to a boolean value.
*
* @param string $value The value to convert.
*
* @return bool|null The converted value.
*/
protected static function get_robots_noindex_value( $value ) {
if ( $value === 'noindex' ) {
return true;
}
if ( $value === 'index' ) {
return false;
}
return null;
}
}

View File

@@ -0,0 +1,31 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Term_Object_Type.
*/
class WPSEO_Term_Object_Type extends WPSEO_Object_Type {
/**
* Creates a new instance based on the passed object ID.
*
* @param int $object_id The object ID to base the object on.
*
* @return WPSEO_Term_Object_Type The class instance.
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the term is null or if a WordPress error is thrown.
*/
public static function from_object( $object_id ) {
$term = get_term( $object_id );
if ( $term === null || is_wp_error( $term ) ) {
throw WPSEO_Invalid_Argument_Exception::unknown_object( $object_id, 'term' );
}
return new self( $object_id, 'term', $term->taxonomy, get_term_link( $term ) );
}
}

View File

@@ -0,0 +1,21 @@
<?php
/**
* WPSEO interface file.
*
* @package WPSEO\Indexables
*/
/**
* Interface WPSEO_Endpoint_Validator.
*/
interface WPSEO_Endpoint_Validator {
/**
* Validates the passed request data.
*
* @param array $request_data The request data to validate.
*
* @return void
*/
public function validate( $request_data );
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Keyword_Validator.
*/
class WPSEO_Keyword_Validator implements WPSEO_Endpoint_Validator {
/**
* Validates the keyword-related data.
*
* @param array $request_data The request data to validate.
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the keyword or the score is of an invalid value type.
*/
public function validate( $request_data ) {
if ( WPSEO_Validator::key_exists( $request_data, 'keyword' ) && ! WPSEO_Validator::is_string( $request_data['keyword'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['keyword'], 'keyword' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'score' ) && ! WPSEO_Validator::is_integer( $request_data['score'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_integer_parameter( $request_data['score'], 'score' );
}
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Link_Validator.
*/
class WPSEO_Link_Validator implements WPSEO_Endpoint_Validator {
/**
* Validates the link-related data.
*
* @param array $request_data The request data to validate.
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the link-data count or incoming count is of an invalid value type.
*/
public function validate( $request_data ) {
if ( WPSEO_Validator::key_exists( $request_data, 'count' ) && ! WPSEO_Validator::is_integer( $request_data['count'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_integer_parameter( $request_data['count'], 'count' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'incoming_count' ) && ! WPSEO_Validator::is_integer( $request_data['incoming_count'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_integer_parameter( $request_data['incoming_count'], 'incoming_count' );
}
}
}

View File

@@ -0,0 +1,51 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Meta_Values_Validator.
*/
class WPSEO_Meta_Values_Validator implements WPSEO_Endpoint_Validator {
/**
* Validates the meta values data.
*
* @param array $request_data The request data to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if a field from the request data is of an invalid value type.
*/
public function validate( $request_data ) {
if ( WPSEO_Validator::key_exists( $request_data, 'title' ) && ! WPSEO_Validator::is_string( $request_data['title'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['title'], 'title' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'metadesc' ) && ! WPSEO_Validator::is_string( $request_data['metadesc'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['metadesc'], 'metadesc' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'permalink' ) && ! WPSEO_Validator::is_string( $request_data['permalink'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['permalink'], 'permalink' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'readability_score' ) && ! WPSEO_Validator::is_integer( $request_data['readability_score'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_integer_parameter( $request_data['readability_score'], 'readability_score' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'is_cornerstone' ) && ! WPSEO_Validator::is_boolean( $request_data['is_cornerstone'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_boolean_parameter( $request_data['is_cornerstone'], 'is_cornerstone' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'canonical' ) && ! WPSEO_Validator::is_string( $request_data['canonical'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['canonical'], 'canonical' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'breadcrumb_title' ) && ! WPSEO_Validator::is_string( $request_data['breadcrumb_title'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['breadcrumb_title'], 'breadcrumb_title' );
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Object_Type_Validator.
*/
class WPSEO_Object_Type_Validator implements WPSEO_Endpoint_Validator {
/**
* Validates the object_type parameter.
*
* @param string $object_type The object type to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown is the object type is invalid.
*/
private static function validate_type( $object_type ) {
if ( ! in_array( $object_type, array( 'post', 'term' ), true ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_type( $object_type );
}
}
/**
* Validates whether the passed subtype is valid or not.
*
* @param string $type The type to validate.
* @param string $subtype The subtype to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the subtype doesn't exist for the given type.
*/
private static function validate_subtype( $type, $subtype ) {
if ( $type === 'post' && ! post_type_exists( $subtype ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_subtype( $subtype, $type );
}
if ( $type === 'term' && ! taxonomy_exists( $subtype ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_subtype( $subtype, $type );
}
}
/**
* Validates the object type-related data.
*
* @param array $request_data The request data to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the type or subtype are invalid.
*/
public function validate( $request_data ) {
if ( WPSEO_Validator::key_exists( $request_data, 'object_type' ) ) {
self::validate_type( $request_data['object_type'] );
}
if ( WPSEO_Validator::key_exists( $request_data, 'object_subtype' ) ) {
self::validate_subtype( $request_data['object_type'], $request_data['object_subtype'] );
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_OpenGraph_Validator.
*/
class WPSEO_OpenGraph_Validator implements WPSEO_Endpoint_Validator {
/**
* Validates the OpenGraph-related data.
*
* @param array $request_data The request data to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if one of the OpenGraph properties is of an invalid value type.
*/
public function validate( $request_data ) {
if ( WPSEO_Validator::key_exists( $request_data, 'og_title' ) && ! WPSEO_Validator::is_string( $request_data['og_title'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['og_title'], 'og_title' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'og_description' ) && ! WPSEO_Validator::is_string( $request_data['og_description'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['og_description'], 'og_description' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'og_image' ) && ! WPSEO_Validator::is_string( $request_data['og_image'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['og_image'], 'og_image' );
}
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Robots_Validator.
*/
class WPSEO_Robots_Validator implements WPSEO_Endpoint_Validator {
/**
* The robots keys to validate.
*
* @var array
*/
private $robots_to_validate = array(
'is_robots_nofollow',
'is_robots_noarchive',
'is_robots_noimageindex',
'is_robots_nosnippet',
'is_robots_noindex',
);
/**
* Validates the passed request data.
*
* @param array $request_data The request data to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if the robots values are not a boolean type.
*/
public function validate( $request_data ) {
foreach ( $this->robots_to_validate as $item ) {
if ( ! WPSEO_Validator::key_exists( $request_data, $item ) ) {
continue;
}
if ( ! is_null( $request_data[ $item ] ) && ! WPSEO_Validator::is_boolean( $request_data[ $item ] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_boolean_parameter( $request_data[ $item ], $item );
}
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
/**
* WPSEO plugin file.
*
* @package WPSEO\Indexables
*/
/**
* Class WPSEO_Twitter_Validator.
*/
class WPSEO_Twitter_Validator implements WPSEO_Endpoint_Validator {
/**
* Validates the Twitter-related data.
*
* @param array $request_data The request data to validate.
*
* @return void
*
* @throws WPSEO_Invalid_Argument_Exception Thrown if one of the Twitter properties is of an invalid value type.
*/
public function validate( $request_data ) {
if ( WPSEO_Validator::key_exists( $request_data, 'twitter_title' ) && ! WPSEO_Validator::is_string( $request_data['twitter_title'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['twitter_title'], 'twitter_title' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'twitter_description' ) && ! WPSEO_Validator::is_string( $request_data['twitter_description'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['twitter_description'], 'twitter_description' );
}
if ( WPSEO_Validator::key_exists( $request_data, 'twitter_image' ) && ! WPSEO_Validator::is_string( $request_data['twitter_image'] ) ) {
throw WPSEO_Invalid_Argument_Exception::invalid_string_parameter( $request_data['twitter_image'], 'twitter_image' );
}
}
}