| @@ -21,8 +21,11 @@ | ||
| 21 | 21 | * The Stats API Posts endpoint. |
| 22 | 22 | * |
| 23 | 23 | * Provides an endpoint for retrieving posts. |
| 24 | 24 | * |
| 25 | + * It returns site-wide analytics, so it's available to any user with the | |
| 26 | + * default `publish_posts` capability, whoever authored the posts. | |
| 27 | + * | |
| 25 | 28 | * @since 3.17.0 |
| 26 | 29 | */ |
| 27 | 30 | class Endpoint_Posts extends Base_Endpoint { |
| 28 | 31 | use Post_Data_Trait; |
| @@ -28,8 +31,9 @@ | ||
| 28 | 31 | use Post_Data_Trait; |
| 29 | 32 | |
| 30 | 33 | public const TOP_POSTS_DEFAULT_LIMIT = 5; |
| 31 | 34 | public const SORT_DEFAULT = 'views'; |
| 35 | + public const MAX_URLS = 500; | |
| 32 | 36 | |
| 33 | 37 | /** |
| 34 | 38 | * The metrics that can be sorted by. |
| 35 | 39 | * |
| @@ -178,8 +182,10 @@ | ||
| 178 | 182 | ), |
| 179 | 183 | 'urls' => array( |
| 180 | 184 | 'description' => 'The URLs to fetch data for.', |
| 181 | 185 | 'type' => 'array', |
| 186 | + 'items' => array( 'type' => 'string' ), | |
| 187 | + 'maxItems' => self::MAX_URLS, | |
| 182 | 188 | 'sanitize_callback' => array( $this, 'sanitize_urls' ), |
| 183 | 189 | 'validate_callback' => array( $this, 'validate_urls' ), |
| 184 | 190 | 'required' => false, |
| 185 | 191 | ), |
| @@ -246,13 +252,29 @@ | ||
| 246 | 252 | /** |
| 247 | 253 | * Validates if the provided array is a list of URLs. |
| 248 | 254 | * |
| 249 | 255 | * @since 3.19.0 |
| 256 | + * @since 3.24.2 Rejects non-arrays and more than `MAX_URLS` items. | |
| 250 | 257 | * |
| 251 | - * @param array<string> $urls The array to validate. | |
| 258 | + * @param mixed $urls The raw parameter value, as validation runs before type checks. | |
| 252 | 259 | * @return true|WP_Error |
| 253 | 260 | */ |
| 254 | - public function validate_urls( array $urls ) { | |
| 261 | + public function validate_urls( $urls ) { | |
| 262 | + if ( ! is_array( $urls ) ) { | |
| 263 | + return new WP_Error( 'invalid_param', __( 'The parameter must be a list of URLs.', 'wp-parsely' ) ); | |
| 264 | + } | |
| 265 | + | |
| 266 | + if ( count( $urls ) > self::MAX_URLS ) { | |
| 267 | + return new WP_Error( | |
| 268 | + 'invalid_param', | |
| 269 | + sprintf( | |
| 270 | + /* translators: %d: The maximum number of items. */ | |
| 271 | + __( 'The parameter must have at most %d items.', 'wp-parsely' ), | |
| 272 | + self::MAX_URLS | |
| 273 | + ) | |
| 274 | + ); | |
| 275 | + } | |
| 276 | + | |
| 255 | 277 | foreach ( $urls as $url ) { |
| 256 | 278 | if ( false === filter_var( $url, FILTER_VALIDATE_URL ) ) { |
| 257 | 279 | return new WP_Error( 'invalid_param', __( 'The parameter must be a list of URLs.', 'wp-parsely' ) ); |
| 258 | 280 | } |