ames of all taxonomy of $object_type. */ function get_taxonomies_for_attachments( $output = 'names' ) { $taxonomies = array(); foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) { foreach ( $taxonomy->object_type as $object_type ) { if ( 'attachment' == $object_type || 0 === strpos( $object_type, 'attachment:' ) ) { if ( 'names' == $output ) $taxonomies[] = $taxonomy->name; else $taxonomies[ $taxonomy->name ] = $taxonomy; break; } } } return $taxonomies; } /** * Create new GD image resource with transparency support * @TODO: Deprecate if possible. * * @since 2.9.0 * * @param int $width Image width * @param int $height Image height * @return image resource */ function wp_imagecreatetruecolor($width, $height) { $img = imagecreatetruecolor($width, $height); if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) { imagealphablending($img, false); imagesavealpha($img, true); } return $img; } /** * Register an embed handler. This function should probably only be used for sites that do not support oEmbed. * * @since 2.9.0 * @see WP_Embed::register_handler() */ function wp_embed_register_handler( $id, $regex, $callback, $priority = 10 ) { global $wp_embed; $wp_embed->register_handler( $id, $regex, $callback, $priority ); } /** * Unregister a previously registered embed handler. * * @since 2.9.0 * @see WP_Embed::unregister_handler() */ function wp_embed_unregister_handler( $id, $priority = 10 ) { global $wp_embed; $wp_embed->unregister_handler( $id, $priority ); } /** * Create default array of embed parameters. * * The width defaults to the content width as specified by the theme. If the * theme does not specify a content width, then 500px is used. * * The default height is 1.5 times the width, or 1000px, whichever is smaller. * * The 'embed_defaults' filter can be used to adjust either of these values. * * @since 2.9.0 * * @return array Default embed parameters. */ function wp_embed_defaults() { if ( ! empty( $GLOBALS['content_width'] ) ) $width = (int) $GLOBALS['content_width']; if ( empty( $width ) ) $width = 500; $height = min( ceil( $width * 1.5 ), 1000 ); return apply_filters( 'embed_defaults', compact( 'width', 'height' ) ); } /** * Based on a supplied width/height example, return the biggest possible dimensions based on the max width/height. * * @since 2.9.0 * @uses wp_constrain_dimensions() This function passes the widths and the heights. * * @param int $example_width The width of an example embed. * @param int $example_height The height of an example embed. * @param int $max_width The maximum allowed width. * @param int $max_height The maximum allowed height. * @return array The maximum possible width and height based on the example ratio. */ function wp_expand_dimensions( $example_width, $example_height, $max_width, $max_height ) { $example_width = (int) $example_width; $example_height = (int) $example_height; $max_width = (int) $max_width; $max_height = (int) $max_height; return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height ); } /** * Attempts to fetch the embed HTML for a provided URL using oEmbed. * * @since 2.9.0 * @see WP_oEmbed * * @uses _wp_oembed_get_object() * @uses WP_oEmbed::get_html() * * @param string $url The URL that should be embedded. * @param array $args Additional arguments and parameters. * @return bool|string False on failure or the embed HTML on success. */ function wp_oembed_get( $url, $args = '' ) { require_once( ABSPATH . WPINC . '/class-oembed.php' ); $oembed = _wp_oembed_get_object(); return $oembed->get_html( $url, $args ); } /** * Adds a URL format and oEmbed provider URL pair. * * @since 2.9.0 * @see WP_oEmbed * * @uses _wp_oembed_get_object() * * @param string $format The format of URL that this provider can handle. You can use asterisks as wildcards. * @param string $provider The URL to the oEmbed provider. * @param boolean $regex Whether the $format parameter is in a regex format. */ function wp_oembed_add_provider( $format, $provider, $regex = false ) { require_once( ABSPATH . WPINC . '/class-oembed.php' ); $oembed = _wp_oembed_get_object(); $oembed->providers[$format] = array( $provider, $regex ); } /** * Removes an oEmbed provider. * * @since 3.5 * @see WP_oEmbed * * @uses _wp_oembed_get_object() * * @param string $format The URL format for the oEmbed provider to remove. */ function wp_oembed_remove_provider( $format ) { require_once( ABSPATH . WPINC . '/class-oembed.php' ); $oembed = _wp_oembed_get_object(); if ( isset( $oembed->providers[ $format ] ) ) { unset( $oembed->providers[ $format ] ); return true; } return false; } /** * Determines if default embed handlers should be loaded. * * Checks to make sure that the embeds library hasn't already been loaded. If * it hasn't, then it will load the embeds library. * * @since 2.9.0 */ function wp_maybe_load_embeds() { if ( ! apply_filters( 'load_default_embeds', true ) ) return; wp_embed_register_handler( 'googlevideo', '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i', 'wp_embed_handler_googlevideo' ); } /** * The Google Video embed handler callback. Google Video does not support oEmbed. * * @see WP_Embed::register_handler() * @see WP_Embed::shortcode() * * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}. * @param array $attr Embed attributes. * @param string $url The original URL that was matched by the regex. * @param array $rawattr The original unmodified attributes. * @return string The embed HTML. */ function wp_embed_handler_googlevideo( $matches, $attr, $url, $rawattr ) { // If the user supplied a fixed width AND height, use it if ( !empty($rawattr['width']) && !empty($rawattr['height']) ) { $width = (int) $rawattr['width']; $height = (int) $rawattr['height']; } else { list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] ); } return apply_filters( 'embed_googlevideo', '', $matches, $attr, $url, $rawattr ); } /** * {@internal Missing Short Description}} * * @since 2.3.0 * * @param unknown_type $size * @return unknown */ function wp_convert_hr_to_bytes( $size ) { $size = strtolower( $size ); $bytes = (int) $size; if ( strpos( $size, 'k' ) !== false ) $bytes = intval( $size ) * 1024; elseif ( strpos( $size, 'm' ) !== false ) $bytes = intval($size) * 1024 * 1024; elseif ( strpos( $size, 'g' ) !== false ) $bytes = intval( $size ) * 1024 * 1024 * 1024; return $bytes; } /** * {@internal Missing Short Description}} * * @since 2.3.0 * * @param unknown_type $bytes * @return unknown */ function wp_convert_bytes_to_hr( $bytes ) { $units = array( 0 => 'B', 1 => 'kB', 2 => 'MB', 3 => 'GB' ); $log = log( $bytes, 1024 ); $power = (int) $log; $size = pow( 1024, $log - $power ); return $size . $units[$power]; } /** * {@internal Missing Short Description}} * * @since 2.5.0 * * @return unknown */ function wp_max_upload_size() { $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ); $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) ); $bytes = apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes ); return $bytes; } /** * Returns a WP_Image_Editor instance and loads file into it. * * @since 3.5.0 * @access public * * @param string $path Path to file to load * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } * @return WP_Image_Editor|WP_Error */ function wp_get_image_editor( $path, $args = array() ) { $args['path'] = $path; if ( ! isset( $args['mime_type'] ) ) { $file_info = wp_check_filetype( $args['path'] ); // If $file_info['type'] is false, then we let the editor attempt to // figure out the file type, rather than forcing a failure based on extension. if ( isset( $file_info ) && $file_info['type'] ) $args['mime_type'] = $file_info['type']; } $implementation = _wp_image_editor_choose( $args ); if ( $implementation ) { $editor = new $implementation( $path ); $loaded = $editor->load(); if ( is_wp_error( $loaded ) ) return $loaded; return $editor; } return new WP_Error( 'image_no_editor', __('No editor could be selected.') ); } /** * Tests whether there is an editor that supports a given mime type or methods. * * @since 3.5.0 * @access public * * @param string|array $args Array of requirements. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } * @return boolean true if an eligible editor is found; false otherwise */ function wp_image_editor_supports( $args = array() ) { return (bool) _wp_image_editor_choose( $args ); } /** * Tests which editors are capable of supporting the request. * * @since 3.5.0 * @access private * * @param array $args Additional data. Accepts { 'mime_type'=>string, 'methods'=>{string, string, ...} } * @return string|bool Class name for the first editor that claims to support the request. False if no editor claims to support the request. */ function _wp_image_editor_choose( $args = array() ) { require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) ); foreach ( $implementations as $implementation ) { if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) continue; if ( isset( $args['mime_type'] ) && ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['mime_type'] ) ) { continue; } if ( isset( $args['methods'] ) && array_diff( $args['methods'], get_class_methods( $implementation ) ) ) { continue; } return $implementation; } return false; } /** * Prints default plupload arguments. * * @since 3.4.0 */ function wp_plupload_default_settings() { global $wp_scripts; $data = $wp_scripts->get_data( 'wp-plupload', 'data' ); if ( $data && false !== strpos( $data, '_wpPluploadSettings' ) ) return; $max_upload_size = wp_max_upload_size(); $defaults = array( 'runtimes' => 'html5,silverlight,flash,html4', 'file_data_name' => 'async-upload', // key passed to $_FILE. 'multiple_queues' => true, 'max_file_size' => $max_upload_size . 'b', 'url' => admin_url( 'async-upload.php', 'relative' ), 'flash_swf_url' => includes_url( 'js/plupload/plupload.flash.swf' ), 'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ), 'filters' => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*') ), 'multipart' => true, 'urlstream_upload' => true, ); // Multi-file uploading doesn't currently work in iOS Safari, // single-file allows the built-in camera to be used as source for images if ( wp_is_mobile() ) $defaults['multi_selection'] = false; $defaults = apply_filters( 'plupload_default_settings', $defaults ); $params = array( 'action' => 'upload-attachment', ); $params = apply_filters( 'plupload_default_params', $params ); $params['_wpnonce'] = wp_create_nonce( 'media-form' ); $defaults['multipart_params'] = $params; $settings = array( 'defaults' => $defaults, 'browser' => array( 'mobile' => wp_is_mobile(), 'supported' => _device_can_upload(), ), 'limitExceeded' => is_multisite() && ! is_upload_space_available() ); $script = 'var _wpPluploadSettings = ' . json_encode( $settings ) . ';'; if ( $data ) $script = "$data\n$script"; $wp_scripts->add_data( 'wp-plupload', 'data', $script ); } add_action( 'customize_controls_enqueue_scripts', 'wp_plupload_default_settings' ); /** * Prepares an attachment post object for JS, where it is expected * to be JSON-encoded and fit into an Attachment model. * * @since 3.5.0 * * @param mixed $attachment Attachment ID or object. * @return array Array of attachment details. */ function wp_prepare_attachment_for_js( $attachment ) { if ( ! $attachment = get_post( $attachment ) ) return; if ( 'attachment' != $attachment->post_type ) return; $meta = wp_get_attachment_metadata( $attachment->ID ); if ( false !== strpos( $attachment->post_mime_type, '/' ) ) list( $type, $subtype ) = explode( '/', $attachment->post_mime_type ); else list( $type, $subtype ) = array( $attachment->post_mime_type, '' ); $attachment_url = wp_get_attachment_url( $attachment->ID ); $response = array( 'id' => $attachment->ID, 'title' => $attachment->post_title, 'filename' => basename( $attachment->guid ), 'url' => $attachment_url, 'link' => get_attachment_link( $attachment->ID ), 'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ), 'author' => $attachment->post_author, 'description' => $attachment->post_content, 'caption' => $attachment->post_excerpt, 'name' => $attachment->post_name, 'status' => $attachment->post_status, 'uploadedTo' => $attachment->post_parent, 'date' => strtotime( $attachment->post_date_gmt ) * 1000, 'modified' => strtotime( $attachment->post_modified_gmt ) * 1000, 'menuOrder' => $attachment->menu_order, 'mime' => $attachment->post_mime_type, 'type' => $type, 'subtype' => $subtype, 'icon' => wp_mime_type_icon( $attachment->ID ), 'dateFormatted' => mysql2date( get_option('date_format'), $attachment->post_date ), 'nonces' => array( 'update' => false, 'delete' => false, ), 'editLink' => false, ); if ( current_user_can( 'edit_post', $attachment->ID ) ) { $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID ); $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' ); } if ( current_user_can( 'delete_post', $attachment->ID ) ) $response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID ); if ( $meta && 'image' === $type ) { $sizes = array(); $possible_sizes = apply_filters( 'image_size_names_choose', array( 'thumbnail' => __('Thumbnail'), 'medium' => __('Medium'), 'large' => __('Large'), 'full' => __('Full Size'), ) ); unset( $possible_sizes['full'] ); // Loop through all potential sizes that may be chosen. Try to do this with some efficiency. // First: run the image_downsize filter. If it returns something, we can use its data. // If the filter does not return something, then image_downsize() is just an expensive // way to check the image metadata, which we do second. foreach ( $possible_sizes as $size => $label ) { if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) { if ( ! $downsize[3] ) continue; $sizes[ $size ] = array( 'height' => $downsize[2], 'width' => $downsize[1], 'url' => $downsize[0], 'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape', ); } elseif ( isset( $meta['sizes'][ $size ] ) ) { if ( ! isset( $base_url ) ) $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url ); // Nothing from the filter, so consult image metadata if we have it. $size_meta = $meta['sizes'][ $size ]; // We have the actual image size, but might need to further constrain it if content_width is narrower. // Thumbnail, medium, and full sizes are also checked against the site's height/width options. list( $width, $height ) = image_constrain_size_for_editor( $size_meta['width'], $size_meta['height'], $size, 'edit' ); $sizes[ $size ] = array( 'height' => $height, 'width' => $width, 'url' => $base_url . $size_meta['file'], 'orientation' => $height > $width ? 'portrait' : 'landscape', ); } } $sizes['full'] = array( 'height' => $meta['height'], 'width' => $meta['width'], 'url' => $attachment_url, 'orientation' => $meta['height'] > $meta['width'] ? 'portrait' : 'landscape', ); $response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] ); } if ( function_exists('get_compat_media_markup') ) $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) ); return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta ); } /** * Enqueues all scripts, styles, settings, and templates necessary to use * all media JS APIs. * * @since 3.5.0 */ function wp_enqueue_media( $args = array() ) { // Enqueue me just once per page, please. if ( did_action( 'wp_enqueue_media' ) ) return; $defaults = array( 'post' => null, ); $args = wp_parse_args( $args, $defaults ); // We're going to pass the old thickbox media tabs to `media_upload_tabs` // to ensure plugins will work. We will then unset those tabs. $tabs = array( // handler action suffix => tab label 'type' => '', 'type_url' => '', 'gallery' => '', 'library' => '', ); $tabs = apply_filters( 'media_upload_tabs', $tabs ); unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] ); $props = array( 'link' => get_option( 'image_default_link_type' ), // db default is 'file' 'align' => get_option( 'image_default_align' ), // empty default 'size' => get_option( 'image_default_size' ), // empty default ); $settings = array( 'tabs' => $tabs, 'tabUrl' => add_query_arg( array( 'chromeless' => true ), admin_url('media-upload.php') ), 'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ), 'captions' => ! apply_filters( 'disable_captions', '' ), 'nonce' => array( 'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ), ), 'post' => array( 'id' => 0, ), 'defaultProps' => $props, ); $post = null; if ( isset( $args['post'] ) ) { $post = get_post( $args['post'] ); $settings['post'] = array( 'id' => $post->ID, 'nonce' => wp_create_nonce( 'update-post_' . $post->ID ), ); if ( current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ) ) { $featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true ); $settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1; } } $hier = $post && is_post_type_hierarchical( $post->post_type ); $strings = array( // Generic 'url' => __( 'URL' ), 'addMedia' => __( 'Add Media' ), 'search' => __( 'Search' ), 'select' => __( 'Select' ), 'cancel' => __( 'Cancel' ), /* translators: This is a would-be plural string used in the media manager. If there is not a word you can use in your language to avoid issues with the lack of plural support here, turn it into "selected: %d" then translate it. */ 'selected' => __( '%d selected' ), 'dragInfo' => __( 'Drag and drop to reorder images.' ), // Upload 'uploadFilesTitle' => __( 'Upload Files' ), 'uploadImagesTitle' => __( 'Upload Images' ), // Library 'mediaLibraryTitle' => __( 'Media Library' ), 'insertMediaTitle' => __( 'Insert Media' ), 'createNewGallery' => __( 'Create a new gallery' ), 'returnToLibrary' => __( '← Return to library' ), 'allMediaItems' => __( 'All media items' ), 'noItemsFound' => __( 'No items found.' ), 'insertIntoPost' => $hier ? __( 'Insert into page' ) : __( 'Insert into post' ), 'uploadedToThisPost' => $hier ? __( 'Uploaded to this page' ) : __( 'Uploaded to this post' ), 'warnDelete' => __( "You are about to permanently delete this item.\n 'Cancel' to stop, 'OK' to delete." ), // From URL 'insertFromUrlTitle' => __( 'Insert from URL' ), // Featured Images 'setFeaturedImageTitle' => __( 'Set Featured Image' ), 'setFeaturedImage' => __( 'Set featured image' ), // Gallery 'createGalleryTitle' => __( 'Create Gallery' ), 'editGalleryTitle' => __( 'Edit Gallery' ), 'cancelGalleryTitle' => __( '← Cancel Gallery' ), 'insertGallery' => __( 'Insert gallery' ), 'updateGallery' => __( 'Update gallery' ), 'addToGallery' => __( 'Add to gallery' ), 'addToGalleryTitle' => __( 'Add to Gallery' ), 'reverseOrder' => __( 'Reverse order' ), ); $settings = apply_filters( 'media_view_settings', $settings, $post ); $strings = apply_filters( 'media_view_strings', $strings, $post ); $strings['settings'] = $settings; wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings ); wp_enqueue_script( 'media-editor' ); wp_enqueue_style( 'media-views' ); wp_plupload_default_settings(); require_once ABSPATH . WPINC . '/media-template.php'; add_action( 'admin_footer', 'wp_print_media_templates' ); add_action( 'wp_footer', 'wp_print_media_templates' ); do_action( 'wp_enqueue_media' ); }