Empty when none were sent. * * @throws InvalidArgumentException With a message fit to show the user. */ public static function validate( $rules ): array { if ( null === $rules || [] === $rules ) { return []; } if ( ! is_array( $rules ) || ! array_is_list( $rules ) ) { throw new InvalidArgumentException( __( 'Custom find and replace rules must be a list.', 'shiftora' ) ); } if ( count( $rules ) > self::MAX_RULES ) { throw new InvalidArgumentException( /* translators: %d: the most rules one migration accepts. */ sprintf( __( 'A migration accepts at most %d custom find and replace rules.', 'shiftora' ), self::MAX_RULES ) ); } $clean = []; foreach ( $rules as $index => $rule ) { $number = $index + 1; $find = is_array( $rule ) && is_string( $rule['find'] ?? null ) ? $rule['find'] : null; $to = is_array( $rule ) && is_string( $rule['replace'] ?? null ) ? $rule['replace'] : null; if ( null === $find || null === $to || '' === trim( $find ) ) { throw new InvalidArgumentException( /* translators: %d: rule number, counted from 1. */ sprintf( __( 'Custom rule %d needs something in From.', 'shiftora' ), $number ) ); } if ( strlen( $find ) > self::MAX_LENGTH || strlen( $to ) > self::MAX_LENGTH ) { throw new InvalidArgumentException( /* translators: 1: rule number, 2: the longest From or To in characters. */ sprintf( __( 'Custom rule %1$d is too long. From and To can each hold %2$d characters.', 'shiftora' ), $number, self::MAX_LENGTH ) ); } if ( 1 === preg_match( '/[\x00-\x1F\x7F]/', $find . $to ) ) { throw new InvalidArgumentException( /* translators: %d: rule number, counted from 1. */ sprintf( __( 'Custom rule %d contains a control character.', 'shiftora' ), $number ) ); } if ( $find === $to ) { throw new InvalidArgumentException( /* translators: %d: rule number, counted from 1. */ sprintf( __( 'Custom rule %d has the same From and To.', 'shiftora' ), $number ) ); } // Not a generated URL rule: those run as one pass with host boundaries, and // a typed rule gets the plain left-to-right behavior it asked for. $clean[] = [ 'find' => $find, 'replace' => $to, 'generated' => false ]; } return $clean; } }