200 ) { return false; } if ( 1 !== preg_match( '#^(https?://[^\s"\'<>&\\\\\x00-\x1F\x7F]+|urn:[A-Za-z0-9][A-Za-z0-9-]*:[^\s"\'<>&\\\\\x00-\x1F\x7F]+)$#D', $uri ) ) { return false; } return ! in_array( rtrim( $uri, '/' ), array_map( static function ( $reserved ) { return rtrim( $reserved, '/' ); }, self::RESERVED_URIS ), true ); } /** * Validates a list of declarations. * * @param array $namespaces List of array{prefix:string,uri:string}. * @return string[] Messages that name the affected row; empty when valid. */ public static function validate( array $namespaces ): array { $errors = array(); if ( count( $namespaces ) > self::MAX ) { /* translators: %d: maximum number of namespaces. */ return array( sprintf( __( 'Declare at most %d XML namespaces.', 'feedweaver' ), self::MAX ) ); } $seen_prefix = array(); $seen_uri = array(); foreach ( array_values( $namespaces ) as $i => $row ) { $n = $i + 1; $prefix = isset( $row['prefix'] ) ? $row['prefix'] : ''; $uri = isset( $row['uri'] ) ? $row['uri'] : ''; if ( ! Path_Validator::is_valid_prefix( $prefix ) ) { /* translators: %d: namespace row number. */ $errors[] = sprintf( __( 'Namespace %d: the prefix must be letters, numbers, hyphens or underscores, start with a letter or underscore, and not start with "xml".', 'feedweaver' ), $n ); } elseif ( isset( $seen_prefix[ $prefix ] ) ) { /* translators: 1: namespace row number, 2: prefix. */ $errors[] = sprintf( __( 'Namespace %1$d: the prefix "%2$s" is already used.', 'feedweaver' ), $n, $prefix ); } else { $seen_prefix[ $prefix ] = true; } if ( ! self::is_valid_uri( $uri ) ) { /* translators: %d: namespace row number. */ $errors[] = sprintf( __( 'Namespace %d: the address must start with http://, https:// or urn: and contain no spaces or quotes (and cannot be an address reserved by XML).', 'feedweaver' ), $n ); } elseif ( isset( $seen_uri[ $uri ] ) ) { /* translators: %d: namespace row number. */ $errors[] = sprintf( __( 'Namespace %d: this address is already declared with another prefix.', 'feedweaver' ), $n ); } else { $seen_uri[ $uri ] = true; } }//end foreach return $errors; } /** * The declared prefixes. * * @param array $namespaces Declarations. * @return string[] */ public static function prefixes( array $namespaces ): array { $out = array(); foreach ( $namespaces as $row ) { if ( isset( $row['prefix'] ) && is_string( $row['prefix'] ) ) { $out[] = $row['prefix']; } } return $out; } /** * Prefix => URI map. * * @param array $namespaces Declarations. * @return array */ public static function map( array $namespaces ): array { $out = array(); foreach ( $namespaces as $row ) { if ( isset( $row['prefix'], $row['uri'] ) && is_string( $row['prefix'] ) && is_string( $row['uri'] ) ) { $out[ $row['prefix'] ] = $row['uri']; } } return $out; } }