/** * Sanitises various option values based on the nature of the option. * * This is basically a switch statement which will pass $value through a number * of functions depending on the $option. * * @since 0.0.1 * * @global hqdb $hqdb * * @param string $option The name of the option. * @param string $value The unsanitised value. * @return string Sanitized value. */ function sanitize_option($option, $value) { global $hqdb; $original_value = $value; $error = ''; switch ($option) { case 'admin_email': case 'new_admin_email': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { $value = sanitize_email($value); if (!is_email($value)) { $error = __('The email address entered did not appear to be a valid email address. Please enter a valid email address.'); } } break; case 'thumbnail_size_w': case 'thumbnail_size_h': case 'medium_size_w': case 'medium_size_h': case 'large_size_w': case 'large_size_h': case 'mailserver_port': case 'comment_max_links': case 'page_on_front': case 'page_for_posts': case 'rss_excerpt_length': case 'default_category': case 'default_email_category': case 'default_link_category': case 'close_comments_days_old': case 'comments_per_page': case 'thread_comments_depth': case 'users_can_register': case 'start_of_week': case 'site_icon': $value = absint($value); break; case 'posts_per_page': case 'posts_per_rss': $value = (int) $value; if (empty($value)) { $value = 1; } if ($value < -1) { $value = abs($value); } break; case 'default_ping_status': case 'default_comment_status': // Options that if not there have 0 value but need to be something like "closed" if ($value == '0' || $value == '') { $value = 'closed'; } break; case 'blogdescription': case 'blogname': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { $value = hq_kses_post($value); $value = esc_html($value); } break; case 'blog_charset': $value = preg_replace('/[^a-zA-Z0-9_-]/', '', $value); // strips slashes break; case 'blog_public': // This is the value if the settings checkbox is not checked on POST. Don't rely on this. if (null === $value) { $value = 1; } else { $value = intval($value); } break; case 'date_format': case 'time_format': case 'mailserver_url': case 'mailserver_login': case 'mailserver_pass': case 'upload_path': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { $value = strip_tags($value); $value = hq_kses_data($value); } break; case 'ping_sites': $value = explode("\n", $value); $value = array_filter(array_map('trim', $value)); $value = array_filter(array_map('esc_url_raw', $value)); $value = implode("\n", $value); break; case 'gmt_offset': $value = preg_replace('/[^0-9:.-]/', '', $value); // strips slashes break; case 'siteurl': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { if (preg_match('#http(s?)://(.+)#i', $value)) { $value = esc_url_raw($value); } else { $error = __('The HiveQueen address you entered did not appear to be a valid URL. Please enter a valid URL.'); } } break; case 'home': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { if (preg_match('#http(s?)://(.+)#i', $value)) { $value = esc_url_raw($value); } else { $error = __('The Site address you entered did not appear to be a valid URL. Please enter a valid URL.'); } } break; case 'HQLANG': $allowed = get_available_languages(); //TODO: Goyo no multisite //if ( ! is_multisite() && defined( 'HQLANG' ) && '' !== HQLANG && 'en_US' !== HQLANG ) { if (defined('HQLANG') && '' !== HQLANG && 'en_US' !== HQLANG) { $allowed[] = HQLANG; } if (!in_array($value, $allowed) && !empty($value)) { $value = get_option($option); } break; case 'illegal_names': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { if (!is_array($value)) { $value = explode(' ', $value); } $value = array_values(array_filter(array_map('trim', $value))); if (!$value) { $value = ''; } } break; case 'limited_email_domains': case 'banned_email_domains': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { if (!is_array($value)) { $value = explode("\n", $value); } $domains = array_values(array_filter(array_map('trim', $value))); $value = array(); foreach ($domains as $domain) { if (!preg_match('/(--|\\.\\.)/', $domain) && preg_match('|^([a-zA-Z0-9-\\.])+$|', $domain)) { $value[] = $domain; } } if (!$value) { $value = ''; } } break; case 'timezone_string': $allowed_zones = timezone_identifiers_list(); if (!in_array($value, $allowed_zones) && !empty($value)) { $error = __('The timezone you have entered is not valid. Please select a valid timezone.'); } break; case 'permalink_structure': case 'category_base': case 'tag_base': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { $value = esc_url_raw($value); $value = str_replace('http://', '', $value); } break; case 'default_role': if (!get_role($value) && get_role('subscriber')) { $value = 'subscriber'; } break; case 'moderation_keys': case 'blacklist_keys': $value = $hqdb->strip_invalid_text_for_column($hqdb->options, 'option_value', $value); if (is_hq_error($value)) { $error = $value->get_error_message(); } else { $value = explode("\n", $value); $value = array_filter(array_map('trim', $value)); $value = array_unique($value); $value = implode("\n", $value); } break; } if (!empty($error)) { $value = get_option($option); if (function_exists('add_settings_error')) { add_settings_error($option, "invalid_{$option}", $error); } } /** * Filter an option value following sanitization. * * @since 0.0.1 * @since 0.0.1 * * @param string $value The sanitized option value. * @param string $option The option name. * @param string $original_value The original value passed to the function. */ return apply_filters("sanitize_option_{$option}", $value, $option, $original_value); }
/** * Get extended image metadata, exif or iptc as available. * * Retrieves the EXIF metadata aperture, credit, camera, caption, copyright, iso * created_timestamp, focal_length, shutter_speed, and title. * * The IPTC metadata that is retrieved is APP13, credit, byline, created date * and time, caption, copyright, and title. Also includes FNumber, Model, * DateTimeDigitized, FocalLength, ISOSpeedRatings, and ExposureTime. * * @todo Try other exif libraries if available. * @since 0.0.1 * * @param string $file * @return bool|array False on failure. Image metadata array on success. */ function hq_read_image_metadata($file) { if (!file_exists($file)) { return false; } list(, , $sourceImageType) = getimagesize($file); /* * EXIF contains a bunch of data we'll probably never need formatted in ways * that are difficult to use. We'll normalize it and just extract the fields * that are likely to be useful. Fractions and numbers are converted to * floats, dates to unix timestamps, and everything else to strings. */ $meta = array('aperture' => 0, 'credit' => '', 'camera' => '', 'caption' => '', 'created_timestamp' => 0, 'copyright' => '', 'focal_length' => 0, 'iso' => 0, 'shutter_speed' => 0, 'title' => '', 'orientation' => 0); /* * Read IPTC first, since it might contain data not available in exif such * as caption, description etc. */ if (is_callable('iptcparse')) { getimagesize($file, $info); if (!empty($info['APP13'])) { $iptc = iptcparse($info['APP13']); // Headline, "A brief synopsis of the caption." if (!empty($iptc['2#105'][0])) { $meta['title'] = trim($iptc['2#105'][0]); /* * Title, "Many use the Title field to store the filename of the image, * though the field may be used in many ways." */ } elseif (!empty($iptc['2#005'][0])) { $meta['title'] = trim($iptc['2#005'][0]); } if (!empty($iptc['2#120'][0])) { // description / legacy caption $caption = trim($iptc['2#120'][0]); mbstring_binary_safe_encoding(); $caption_length = strlen($caption); reset_mbstring_encoding(); if (empty($meta['title']) && $caption_length < 80) { // Assume the title is stored in 2:120 if it's short. $meta['title'] = $caption; } $meta['caption'] = $caption; } if (!empty($iptc['2#110'][0])) { // credit $meta['credit'] = trim($iptc['2#110'][0]); } elseif (!empty($iptc['2#080'][0])) { // creator / legacy byline $meta['credit'] = trim($iptc['2#080'][0]); } if (!empty($iptc['2#055'][0]) && !empty($iptc['2#060'][0])) { // created date and time $meta['created_timestamp'] = strtotime($iptc['2#055'][0] . ' ' . $iptc['2#060'][0]); } if (!empty($iptc['2#116'][0])) { // copyright $meta['copyright'] = trim($iptc['2#116'][0]); } } } /** * Filter the image types to check for exif data. * * @since 0.0.1 * * @param array $image_types Image types to check for exif data. */ if (is_callable('exif_read_data') && in_array($sourceImageType, apply_filters('hq_read_image_metadata_types', array(IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM)))) { $exif = @exif_read_data($file); if (!empty($exif['ImageDescription'])) { mbstring_binary_safe_encoding(); $description_length = strlen($exif['ImageDescription']); reset_mbstring_encoding(); if (empty($meta['title']) && $description_length < 80) { // Assume the title is stored in ImageDescription $meta['title'] = trim($exif['ImageDescription']); } if (empty($meta['caption']) && !empty($exif['COMPUTED']['UserComment'])) { $meta['caption'] = trim($exif['COMPUTED']['UserComment']); } if (empty($meta['caption'])) { $meta['caption'] = trim($exif['ImageDescription']); } } elseif (empty($meta['caption']) && !empty($exif['Comments'])) { $meta['caption'] = trim($exif['Comments']); } if (empty($meta['credit'])) { if (!empty($exif['Artist'])) { $meta['credit'] = trim($exif['Artist']); } elseif (!empty($exif['Author'])) { $meta['credit'] = trim($exif['Author']); } } if (empty($meta['copyright']) && !empty($exif['Copyright'])) { $meta['copyright'] = trim($exif['Copyright']); } if (!empty($exif['FNumber'])) { $meta['aperture'] = round(hq_exif_frac2dec($exif['FNumber']), 2); } if (!empty($exif['Model'])) { $meta['camera'] = trim($exif['Model']); } if (empty($meta['created_timestamp']) && !empty($exif['DateTimeDigitized'])) { $meta['created_timestamp'] = hq_exif_date2ts($exif['DateTimeDigitized']); } if (!empty($exif['FocalLength'])) { $meta['focal_length'] = (string) hq_exif_frac2dec($exif['FocalLength']); } if (!empty($exif['ISOSpeedRatings'])) { $meta['iso'] = is_array($exif['ISOSpeedRatings']) ? reset($exif['ISOSpeedRatings']) : $exif['ISOSpeedRatings']; $meta['iso'] = trim($meta['iso']); } if (!empty($exif['ExposureTime'])) { $meta['shutter_speed'] = (string) hq_exif_frac2dec($exif['ExposureTime']); } if (!empty($exif['Orientation'])) { $meta['orientation'] = $exif['Orientation']; } } foreach (array('title', 'caption', 'credit', 'copyright', 'camera', 'iso') as $key) { if ($meta[$key] && !seems_utf8($meta[$key])) { $meta[$key] = utf8_encode($meta[$key]); } } foreach ($meta as &$value) { if (is_string($value)) { $value = hq_kses_post($value); } } /** * Filter the array of meta data read from an image's exif data. * * @since 0.0.1 * * @param array $meta Image meta data. * @param string $file Path to image file. * @param int $sourceImageType Type of image. */ return apply_filters('hq_read_image_metadata', $meta, $file, $sourceImageType); }