/home/arranoyd/otours/wp-content/plugins/redirection/models/redirect-sanitizer.php
<?php
class Red_Item_Sanitize {
private function clean_array( $array ) {
foreach ( $array as $name => $value ) {
if ( is_array( $value ) ) {
$array[ $name ] = $this->clean_array( $value );
} elseif ( is_string( $value ) ) {
$value = trim( $value );
$array[ $name ] = $value;
} else {
$array[ $name ] = $value;
}
};
return $array;
}
private function set_server( $url, array $details ) {
$return = [];
$domain = wp_parse_url( $url, PHP_URL_HOST );
// Auto-convert an absolute URL to relative + server match
if ( $domain && $domain !== Redirection_Request::get_server_name() ) {
$return['match_type'] = 'server';
if ( isset( $details['action_data']['url'] ) ) {
$return['action_data'] = [
'server' => $domain,
'url_from' => $details['action_data']['url'],
];
} else {
$return['action_data'] = [ 'server' => $domain ];
}
$url = wp_parse_url( $url, PHP_URL_PATH );
if ( is_wp_error( $url ) || $url === null ) {
$url = '/';
}
}
$return['url'] = $url;
return $return;
}
public function get( array $details ) {
$data = [];
$details = $this->clean_array( $details );
// Set regex
$data['regex'] = isset( $details['regex'] ) && intval( $details['regex'], 10 ) === 1 ? 1 : 0;
// Auto-migrate the regex to the source flags
$data['match_data'] = [ 'source' => [ 'flag_regex' => $data['regex'] === 1 ? true : false ] ];
// Set flags
if ( isset( $details['match_data'] ) && isset( $details['match_data']['source'] ) ) {
$defaults = red_get_options();
// Parse the source flags
$flags = new Red_Source_Flags( $details['match_data']['source'] );
// Remove defaults
$data['match_data']['source'] = $flags->get_json_without_defaults( $defaults );
$data['regex'] = $flags->is_regex() ? 1 : 0;
}
// If match_data is empty then don't save anything
if ( isset( $data['match_data']['source'] ) && count( $data['match_data']['source'] ) === 0 ) {
$data['match_data']['source'] = [];
}
$data['match_data'] = array_filter( $data['match_data'] );
if ( empty( $data['match_data'] ) ) {
$data['match_data'] = null;
}
// Parse URL
$url = empty( $details['url'] ) ? $this->auto_generate() : $details['url'];
if ( strpos( $url, 'http:' ) !== false || strpos( $url, 'https:' ) !== false ) {
$details = array_merge( $details, $this->set_server( $url, $details ) );
}
$data['match_type'] = isset( $details['match_type'] ) ? $details['match_type'] : 'url';
$data['url'] = $this->get_url( $url, $data['regex'] );
if ( ! is_wp_error( $data['url'] ) ) {
$data['match_url'] = new Red_Url_Match( $data['url'] );
$data['match_url'] = $data['match_url']->get_url();
}
$data['title'] = isset( $details['title'] ) ? $details['title'] : null;
$data['group_id'] = $this->get_group( isset( $details['group_id'] ) ? $details['group_id'] : 0 );
$data['position'] = $this->get_position( $details );
// Set match_url to 'regex'
if ( $data['regex'] ) {
$data['match_url'] = 'regex';
}
if ( $data['title'] ) {
$data['title'] = substr( $data['title'], 0, 500 );
}
$matcher = Red_Match::create( isset( $details['match_type'] ) ? $details['match_type'] : false );
if ( ! $matcher ) {
return new WP_Error( 'redirect', 'Invalid redirect matcher' );
}
$action_code = isset( $details['action_code'] ) ? intval( $details['action_code'], 10 ) : 0;
$action = Red_Action::create( isset( $details['action_type'] ) ? $details['action_type'] : false, $action_code );
if ( ! $action ) {
return new WP_Error( 'redirect', 'Invalid redirect action' );
}
$data['action_type'] = $details['action_type'];
$data['action_code'] = $this->get_code( $details['action_type'], $action_code );
if ( isset( $details['action_data'] ) ) {
$match_data = $matcher->save( $details['action_data'] ? $details['action_data'] : array(), ! $this->is_url_type( $data['action_type'] ) );
$data['action_data'] = is_array( $match_data ) ? serialize( $match_data ) : $match_data;
}
// Any errors?
foreach ( $data as $value ) {
if ( is_wp_error( $value ) ) {
return $value;
}
}
return apply_filters( 'redirection_validate_redirect', $data );
}
protected function get_position( $details ) {
if ( isset( $details['position'] ) ) {
return max( 0, intval( $details['position'], 10 ) );
}
return 0;
}
protected function is_url_type( $type ) {
if ( $type === 'url' || $type === 'pass' ) {
return true;
}
return false;
}
public function is_valid_redirect_code( $code ) {
return in_array( $code, array( 301, 302, 303, 304, 307, 308 ), true );
}
public function is_valid_error_code( $code ) {
return in_array( $code, array( 400, 401, 403, 404, 410, 418, 451, 500, 501, 502, 503, 504 ), true );
}
protected function get_code( $action_type, $code ) {
if ( $action_type === 'url' || $action_type === 'random' ) {
if ( $this->is_valid_redirect_code( $code ) ) {
return $code;
}
return 301;
}
if ( $action_type === 'error' ) {
if ( $this->is_valid_error_code( $code ) ) {
return $code;
}
return 404;
}
return 0;
}
protected function get_group( $group_id ) {
$group_id = intval( $group_id, 10 );
if ( ! Red_Group::get( $group_id ) ) {
return new WP_Error( 'redirect', 'Invalid group when creating redirect' );
}
return $group_id;
}
protected function get_url( $url, $regex ) {
$url = self::sanitize_url( $url, $regex );
if ( $url === '' ) {
return new WP_Error( 'redirect', 'Invalid source URL' );
}
return $url;
}
protected function auto_generate() {
$options = red_get_options();
$url = '';
if ( isset( $options['auto_target'] ) && $options['auto_target'] ) {
$id = time();
$url = str_replace( '$dec$', $id, $options['auto_target'] );
$url = str_replace( '$hex$', sprintf( '%x', $id ), $url );
}
return $url;
}
public function sanitize_url( $url, $regex = false ) {
// Make sure that the old URL is relative
$url = preg_replace( '@^https?://(.*?)/@', '/', $url );
$url = preg_replace( '@^https?://(.*?)$@', '/', $url );
// No new lines
$url = preg_replace( "/[\r\n\t].*?$/s", '', $url );
// Clean control codes
$url = preg_replace( '/[^\PC\s]/u', '', $url );
// Ensure a slash at start
if ( substr( $url, 0, 1 ) !== '/' && (bool) $regex === false ) {
$url = '/' . $url;
}
// Ensure we URL decode any i10n characters
$url = rawurldecode( $url );
// Try and remove bad decoding
if ( function_exists( 'iconv' ) ) {
$converted = @iconv( 'UTF-8', 'UTF-8//IGNORE', $url );
if ( $converted !== false ) {
$url = $converted;
}
}
return $url;
}
}