// Doesn't seem to be a valid IP. return false; } /** * Convert bytes to readable format. * * @since 4.0.0 * * @param integer $bytes The size of the file. * @return array The original and readable file size. */ public function convertFileSize( $bytes ) { if ( empty( $bytes ) ) { return [ 'original' => 0, 'readable' => '0 B' ]; } $i = floor( log( $bytes ) / log( 1024 ) ); $sizes = [ 'B', 'KB', 'MB', 'GB', 'TB' ]; return [ 'original' => $bytes, 'readable' => sprintf( '%.02F', $bytes / pow( 1024, $i ) ) * 1 . ' ' . $sizes[ $i ] ]; } /** * Sanitizes a given option value before we store it in the DB. * * Used by the migration and importer classes. * * @since 4.0.0 * * @param mixed $value The value. * @return mixed $value The sanitized value. */ public function sanitizeOption( $value ) { switch ( gettype( $value ) ) { case 'boolean': return (bool) $value; case 'string': $value = aioseo()->helpers->decodeHtmlEntities( $value ); return aioseo()->helpers->encodeOutputHtml( wp_strip_all_tags( wp_check_invalid_utf8( trim( $value ) ) ) ); case 'integer': return intval( $value ); case 'double': return floatval( $value ); case 'array': $sanitized = []; foreach ( (array) $value as $child ) { $sanitized[] = aioseo()->helpers->sanitizeOption( $child ); } return $sanitized; default: return false; } } /** * Checks if the given string is serialized, and if so, unserializes it. * If the serialized string contains an object, we abort to prevent PHP object injection. * * @since 4.1.0.2 * * @param string $string The string. * @param array|boolean $allowedClasses The allowed classes for unserialize. * @return string|array The string or unserialized data. */ public function maybeUnserialize( $string, $allowedClasses = false ) { if ( ! is_string( $string ) ) { return $string; } $string = trim( $string ); if ( is_serialized( $string ) ) { return @unserialize( $string, [ 'allowed_classes' => $allowedClasses ] ); // phpcs:disable PHPCompatibility.FunctionUse.NewFunctionParameters.unserialize_optionsFound } return $string; } /** * Returns a deep clone of the given object. * The built-in PHP clone KW provides a shallow clone. This method returns a deep clone that also clones nested object properties. * You can use this method to sever the reference to nested objects. * * @since 4.4.7 * * @return object The cloned object. */ public function deepClone( $object ) { return unserialize( serialize( $object ) ); } /** * Sanitizes a given variable * * @since 4.5.6 * * @param mixed $variable The variable. * @param bool $preserveHtml Whether or not to preserve HTML for ALL fields. * @param array $fieldsToPreserveHtml Specific fields to preserve HTML for. * @param string $fieldName The name of the current field (when looping over a list). * @return mixed The sanitized variable. */ public function sanitize( $variable, $preserveHtml = false, $fieldsToPreserveHtml = [], $fieldName = '' ) { $type = gettype( $variable ); switch ( $type ) { case 'boolean': return (bool) $variable; case 'string': if ( $preserveHtml || in_array( $fieldName, $fieldsToPreserveHtml, true ) ) { return aioseo()->helpers->decodeHtmlEntities( sanitize_text_field( htmlspecialchars( $variable, ENT_NOQUOTES, 'UTF-8' ) ) ); } return sanitize_text_field( $variable ); case 'integer': return intval( $variable ); case 'float': case 'double': return floatval( $variable ); case 'array': $array = []; foreach ( (array) $variable as $k => $v ) { $array[ $k ] = $this->sanitize( $v, $preserveHtml, $fieldsToPreserveHtml, $k ); } return $array; default: return false; } } /** * Return the version number with a filter to enable users to hide the version. * * @since 4.3.7 * * @return string The current version or empty if the filter is active. Using ?aioseo-dev will override the filter. */ public function getAioseoVersion() { $version = aioseo()->version; if ( ! $this->isDev() && apply_filters( 'aioseo_hide_version_number', false ) ) { $version = ''; } return $version; } /** * Retrieves the marketing site articles. * * @since 4.7.2 * * @param bool $fetchImage Whether to fetch the article image. * @return array The articles or an empty array on failure. */ public function fetchAioseoArticles( $fetchImage = false ) { $items = aioseo()->core->networkCache->get( 'rss_feed' ); if ( null !== $items ) { return $items; } $options = [ 'timeout' => 10, 'sslverify' => false, ]; $response = wp_remote_get( 'https://aioseo.com/wp-json/wp/v2/posts?per_page=4', $options ); $body = wp_remote_retrieve_body( $response ); if ( ! $body ) { return []; } $cached = []; $items = json_decode( $body, true ); foreach ( $items as $k => $item ) { $cached[ $k ] = [ 'url' => $item['link'], 'title' => $item['title']['rendered'], 'date' => date( get_option( 'date_format' ), strtotime( $item['date'] ) ), 'content' => wp_html_excerpt( $item['content']['rendered'], 128, '…' ), ]; if ( $fetchImage ) { $response = wp_remote_get( $item['_links']['wp:featuredmedia'][0]['href'] ?? '', $options ); $body = wp_remote_retrieve_body( $response ); if ( ! $body ) { continue; } $image = json_decode( $body, true ); $cached[ $k ]['image'] = [ 'url' => $image['source_url'] ?? '', 'alt' => $image['alt_text'] ?? '', 'sizes' => $image['media_details']['sizes'] ?? '' ]; } } aioseo()->core->networkCache->update( 'rss_feed', $cached, 24 * HOUR_IN_SECONDS ); return $cached; } }