'', 'enabled' => true, 'excluded_roles' => array( 'administrator', 'editor' ), 'excluded_urls' => '', 'consent_mode' => 'off', 'consent_category' => 'statistics', 'identify_users' => false, 'identify_send_name_email' => false, 'woo_events' => false, ); } /** * Saved settings merged with the defaults. * * @return array */ public static function get() { $saved = get_option( self::OPTION, array() ); if ( ! is_array( $saved ) ) { $saved = array(); } return array_merge( self::defaults(), $saved ); } /** * Whether a customer ID is saved. * * @return bool */ public static function is_connected() { $settings = self::get(); return '' !== $settings['customer_id']; } /** * Customer IDs look like `cus_` followed by letters, numbers, `_` or `-`, max 45 chars. * * @param string $customer_id Customer ID. * @return bool */ public static function is_valid_customer_id( $customer_id ) { return 1 === preg_match( '/^cus_[A-Za-z0-9_-]{1,41}$/', $customer_id ); } /** * Sanitize callback for register_setting(). * * @param mixed $input Raw form values. * @return array */ public static function sanitize( $input ) { $current = self::get(); $input = is_array( $input ) ? $input : array(); $clean = self::defaults(); $customer_id = isset( $input['customer_id'] ) ? trim( sanitize_text_field( $input['customer_id'] ) ) : ''; if ( '' === $customer_id || self::is_valid_customer_id( $customer_id ) ) { $clean['customer_id'] = $customer_id; } else { $clean['customer_id'] = $current['customer_id']; add_settings_error( self::OPTION, 'fullsession_invalid_customer_id', __( 'That customer ID doesn\'t look right. It should start with "cus_". Your previous customer ID was kept.', 'fullsession' ) ); } $clean['enabled'] = ! empty( $input['enabled'] ); $valid_roles = array_keys( wp_roles()->get_names() ); $roles = isset( $input['excluded_roles'] ) ? (array) $input['excluded_roles'] : array(); $roles = array_map( 'sanitize_key', $roles ); $clean['excluded_roles'] = array_values( array_intersect( $roles, $valid_roles ) ); $urls = isset( $input['excluded_urls'] ) ? sanitize_textarea_field( $input['excluded_urls'] ) : ''; $clean['excluded_urls'] = implode( "\n", self::parse_url_patterns( $urls ) ); $clean['consent_mode'] = ( isset( $input['consent_mode'] ) && 'wp_consent_api' === $input['consent_mode'] ) ? 'wp_consent_api' : 'off'; $category = isset( $input['consent_category'] ) ? sanitize_key( $input['consent_category'] ) : 'statistics'; $clean['consent_category'] = in_array( $category, self::CONSENT_CATEGORIES, true ) ? $category : 'statistics'; $clean['identify_users'] = ! empty( $input['identify_users'] ); $clean['identify_send_name_email'] = ! empty( $input['identify_send_name_email'] ); $clean['woo_events'] = ! empty( $input['woo_events'] ); return $clean; } /** * Turn the URL patterns textarea into a clean list of paths. * * Full URLs are reduced to their path, and every pattern starts with `/`. * * @param string $text One pattern per line. * @return string[] */ public static function parse_url_patterns( $text ) { $patterns = array(); foreach ( preg_split( '/\r\n|\r|\n/', (string) $text ) as $line ) { $line = trim( $line ); if ( '' === $line ) { continue; } if ( false !== strpos( $line, '://' ) ) { $path = wp_parse_url( $line, PHP_URL_PATH ); $line = $path ? $path : '/'; } if ( '/' !== $line[0] ) { $line = '/' . $line; } $patterns[] = $line; } return array_values( array_unique( $patterns ) ); } /** * Whether a request path matches one of the patterns. `*` matches anything. * * @param string $path Request path, e.g. `/shop/item`. * @param string[] $patterns Patterns from parse_url_patterns(). * @return bool */ public static function path_matches( $path, $patterns ) { $path = self::normalize_path( $path ); foreach ( $patterns as $pattern ) { $regex = '#^' . str_replace( '\*', '.*', preg_quote( self::normalize_path( $pattern ), '#' ) ) . '$#i'; if ( 1 === preg_match( $regex, $path ) ) { return true; } } return false; } /** * Drop the trailing slash so `/about` and `/about/` are treated the same. * * @param string $path Path. * @return string */ private static function normalize_path( $path ) { $path = '/' . ltrim( (string) $path, '/' ); return '/' === $path ? $path : untrailingslashit( $path ); } }