. * * Followed the following tutorials * http://wpengineer.com/2076/add-custom-field-attachment-in-wordpress/ * http://bueltge.de/eigene-felder-dateiverwaltung-wordpress/1226/ (same like above, but in German) * * */ //avoid direct calls to this file if (!function_exists('add_action')) { header('Status: 403 Forbidden'); header('HTTP/1.1 403 Forbidden'); exit(); } define('ISCVERSION', '1.1'); define('ISCNAME', 'Image Source Control'); define('ISCTEXTDOMAIN', 'isc'); define('ISCDIR', basename(dirname(__FILE__))); define('ISCPATH', plugin_dir_path(__FILE__)); load_plugin_textdomain(ISCTEXTDOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages/'); if (!class_exists('ISC_CLASS')) { class ISC_CLASS { /** * define default meta fields */ var $_fields = array( 'image_source' => array( 'id' => 'isc_image_source', 'default' => '', ), 'image_source_own' => array( 'id' => 'isc_image_source_own', 'default' => '', ) ); /** * allowed image file types/extensions * @since 1.1 */ var $_allowedExtensions = array( 'jpg', 'png', 'gif' ); public function __construct() { if (!current_user_can('upload_files')) return FALSE; add_filter('attachment_fields_to_edit', array(&$this, 'add_isc_fields'), 10, 2); add_filter('attachment_fields_to_save', array(&$this, 'isc_fields_save'), 10, 2); add_action('admin_menu', array($this, 'create_menu')); add_shortcode('isc_list', array($this, 'list_post_attachments_with_sources_shortcode')); add_action('admin_enqueue_scripts', array($this, 'add_admin_scripts')); // ajax function; 'add_meta_fields' is the action defined in isc.js as the action to be called via ajax add_action('wp_ajax_add_meta_fields', array($this, 'add_meta_values_to_attachments')); // save image information in meta field when a post is saved add_action('save_post', array($this, 'save_image_information_on_post_save')); } /** * create the menu pages for isc */ public function create_menu() { // this page should be accessable by editors and higher $menuhook = add_submenu_page('upload.php', 'missing image sources by Image Source Control Plugin', __('Missing Sources', ISCTEXTDOMAIN), 'edit_others_posts', ISCPATH . '/templates/missing_sources.php', ''); } /** * add scripts to admin pages */ public function add_admin_scripts($hook) { if ('wg-image-source-control/templates/missing_sources.php' != $hook) return; wp_enqueue_script('isc_script', plugins_url('/js/isc.js', __FILE__), false, ISCVERSION); // this is to define ajaxurl to be able to use this in its own js script // wp_localize_script( 'isc_script', 'IscAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); } /** * add custom field to attachment * @param arr $form_fields * @param object $post * @return arr * @since 1.0 * @updated 1.1 */ public function add_isc_fields($form_fields, $post) { // add input field for source $form_fields['isc_image_source']['label'] = __('Image Source', ISCTEXTDOMAIN); $form_fields['isc_image_source']['value'] = get_post_meta($post->ID, 'isc_image_source', true); $form_fields['isc_image_source']['helps'] = __('Include the image source here.', ISCTEXTDOMAIN); // add checkbox to mark as your own image $form_fields['isc_image_source_own']['input'] = 'html'; $form_fields['isc_image_source_own']['helps'] = __('Check this box if this is your own image and doesn\'t need a source.', ISCTEXTDOMAIN); $form_fields['isc_image_source_own']['html'] = "ID, 'isc_image_source_own', true), 1, false ) . "/> " . __('This is my image', ISCTEXTDOMAIN); return $form_fields; } /** * save image source to post_meta * @param object $post * @param $attachment * @return object $post */ public function isc_fields_save($post, $attachment) { if (isset($attachment['isc_image_source'])) update_post_meta($post['ID'], 'isc_image_source', $attachment['isc_image_source']); update_post_meta($post['ID'], 'isc_image_source_own', $attachment['isc_image_source_own']); return $post; } /** * create image sources list for all images of this post * @since 1.0 * @update 1.1 * @param int $post_id id of the current post/page * @return echo output */ public function list_post_attachments_with_sources($post_id = 0) { if (empty($post_id)) { global $post; if (!empty($post->ID)) { $post_id = $post->ID; } } if (empty($post_id)) return; $attachments = get_post_meta($post_id, 'isc_post_images', true); // if attachments is an empty string, search for images in it if ( $attachments == '' ) { $this->save_image_information_on_load ($post_id, $_content); $attachments = get_post_meta($post_id, 'isc_post_images', true); } $return = ''; if (!empty($attachments)) : ob_start(); ?>

0, ), $atts)); // if $id not set, use the current ID from the post if (empty($id)) { global $post; $id = $post->ID; } if (empty($id)) return; return $this->list_post_attachments_with_sources($id); } /** * get all attachments without sources * the downside of this function: is there is not even an empty metakey field, nothing is going to be retrieved * @todo fix this in WP 3.5 with compare => 'NOT EXISTS' */ public function get_attachments_without_sources() { $args = array( 'post_type' => 'attachment', 'numberposts' => -1, 'post_status' => null, 'post_parent' => null, 'meta_query' => array( // image source is empty array( 'key' => 'isc_image_source', 'value' => '', 'compare' => '=', ), // and image source is not set array( 'key' => 'isc_image_source_own', 'value' => '1', 'compare' => '!=', ), ) ); $attachments = get_posts($args); if (!empty($attachments)) { return $attachments; } } /** * add meta values to all attachments * @todo probably need to fix this when more fields are added along the way * @todo use compare => 'NOT EXISTS' when WP 3.5 is up to retrieve only values where it is not set * @todo this currently updates all empty fields; empty in this context is empty string, 0, false or not existing; add check if meta field already existed before */ public function add_meta_values_to_attachments() { // retrieve all attachments $args = array( 'post_type' => 'attachment', 'numberposts' => -1, 'post_status' => null, 'post_parent' => null, ); $attachments = get_posts($args); if (empty($attachments)) return; $count = 0; foreach ($attachments as $_attachment) { $set = 0; setup_postdata($_attachment); foreach ($this->_fields as $_field) { $meta = get_post_meta($_attachment->ID, $_field['id'], true); if (empty($meta)) { update_post_meta($_attachment->ID, $_field['id'], $_field['default']); $set = 1; } } if ($set) $count++; } echo sprintf(__('Added meta fields to %d images.', ISCTEXTDOMAIN), $count); die(); } /** * show the loading image from wp-admin/images/loading.gif * @param bool $display should this be displayed directly or hidden? via inline css */ public function show_loading_image($display = true) { $img_path = admin_url("/images/loading.gif"); $file_path = ABSPATH . "wp-admin/images/loading.gif"; if (file_exists($file_path)) { echo ''; } } /** * this is an entry function to save image information to a post when it is saved * @since 1.1 * @param type $post_id */ public function save_image_information_on_post_save($post_id) { // return, if save_post is called more than one time if (did_action('save_post') !== 1) return; if ('attachment' == $_POST['post_type']) { return; } // check if this is a revision and if so, use parent post id if ($_id = wp_is_post_revision($post_id)) $post_id = $_id; $_content = stripslashes($_REQUEST['content']); $this->save_image_information($post_id, $_content); } /** * save image information for a post when it is viewed and the image source list is enabled * (this is in case the plugin is new and the current post wasn't saved before) * * @since 1.1 */ public function save_image_information_on_load( ) { global $post; if (empty( $post->ID )) return; $post_id = $post->ID; $_content = $post->post_content; $this->save_image_information($post_id, $_content); } /** * retrieve images added to a post or page and save all information as a meta value * @since 1.1 * @todo check for more post types that maybe should not be parsed here */ public function save_image_information( $post_id, $_content ) { $_image_urls = $this->_filter_src_attributes($_content); $_imgs = array(); foreach ($_image_urls as $_image_url) { // get ID of images by url $img_id = $this->get_image_by_url($_image_url); $_imgs[$img_id] = array( 'src' => $_image_url ); } // add thumbnail information $thumb_id = get_post_thumbnail_id($post_id); $_imgs[$thumb_id] = array( 'src' => wp_get_attachment_url($thumb_id), 'thumbnail' => true ); if (empty($_imgs)) $_imgs = false; update_post_meta($post_id, 'isc_post_images', $_imgs); } /** * filter image src attribute from text * @since 1.1 * @return array with image src uris */ public function _filter_src_attributes($content = '') { $srcs = array(); if (empty($content)) return $srcs; // parse HTML with DOM $dom = new DOMDocument; $dom->loadHTML($content); foreach ($dom->getElementsByTagName('img') as $node) { $srcs[] = $node->getAttribute('src'); } return $srcs; } /** * get image by url accessing the database directly * @since 1.1 * @param string $url url of the image * @return id of the image */ public function get_image_by_url($url = '') { if (empty($url)) return 0; $types = implode('|', $this->_allowedExtensions); // check for the format 'image-title-300x200.jpg' and remove the image size from it $newurl = preg_replace("/-(\d+)x(\d+)\.({$types})$/i", '.${3}', $url); global $wpdb; $query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid = %s", $newurl); $id = $wpdb->get_var($query); return $id; } } function add_image_source_fields_start() { $isc = new ISC_CLASS(); } add_action('plugins_loaded', 'add_image_source_fields_start'); /** * the next functions are just to have an easier access from outside the class */ function isc_list($post_id = 0) { $isc = new ISC_CLASS(); echo $isc->list_post_attachments_with_sources($post_id); } }