PluginProbe
Image Source Control Lite – Show Image Credits and Captions / 1.1
Image Source Control Lite – Show Image Credits and Captions v1.1
3.12.0 3.11.0 trunk 1.1 1.1.1 1.1.2 1.1.2.1 1.1.3 1.10 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.2 1.2.0.1 1.2.0.2 1.2.0.3 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.4.1 1.3.5 All 110 releases
image-source-control-isc / isc.php

isc.php in Image Source Control Lite – Show Image Credits and Captions 1.1, at isc.php

460 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Image Source Control
4 Version: 1.1
5 Plugin URI: none
6 Description: The Image Source Control saves the source of an image, lists them and warns if it is missing.
7 Author: Thomas Maier
8 Author URI: http://www.webgilde.com
9 License: GPL v3
10
11 Image Source Control Plugin for WordPress
12 Copyright (C) 2012, Thomas Maier - thomas.maier@webgilde.com
13
14 This program is free software: you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * Followed the following tutorials
28 * http://wpengineer.com/2076/add-custom-field-attachment-in-wordpress/
29 * http://bueltge.de/eigene-felder-dateiverwaltung-wordpress/1226/ (same like above, but in German)
30 *
31 *
32 */
33
34 //avoid direct calls to this file
35 if (!function_exists('add_action')) {
36 header('Status: 403 Forbidden');
37 header('HTTP/1.1 403 Forbidden');
38 exit();
39 }
40
41 define('ISCVERSION', '1.1');
42 define('ISCNAME', 'Image Source Control');
43 define('ISCTEXTDOMAIN', 'isc');
44 define('ISCDIR', basename(dirname(__FILE__)));
45 define('ISCPATH', plugin_dir_path(__FILE__));
46
47 load_plugin_textdomain(ISCTEXTDOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages/');
48
49 if (!class_exists('ISC_CLASS')) {
50
51 class ISC_CLASS {
52
53 /**
54 * define default meta fields
55 */
56 var $_fields = array(
57 'image_source' => array(
58 'id' => 'isc_image_source',
59 'default' => '',
60 ),
61 'image_source_own' => array(
62 'id' => 'isc_image_source_own',
63 'default' => '',
64 )
65 );
66
67 /**
68 * allowed image file types/extensions
69 * @since 1.1
70 */
71 var $_allowedExtensions = array(
72 'jpg', 'png', 'gif'
73 );
74
75 public function __construct() {
76
77 if (!current_user_can('upload_files'))
78 return FALSE;
79
80 add_filter('attachment_fields_to_edit', array(&$this, 'add_isc_fields'), 10, 2);
81 add_filter('attachment_fields_to_save', array(&$this, 'isc_fields_save'), 10, 2);
82
83 add_action('admin_menu', array($this, 'create_menu'));
84
85 add_shortcode('isc_list', array($this, 'list_post_attachments_with_sources_shortcode'));
86
87 add_action('admin_enqueue_scripts', array($this, 'add_admin_scripts'));
88
89 // ajax function; 'add_meta_fields' is the action defined in isc.js as the action to be called via ajax
90 add_action('wp_ajax_add_meta_fields', array($this, 'add_meta_values_to_attachments'));
91
92 // save image information in meta field when a post is saved
93 add_action('save_post', array($this, 'save_image_information_on_post_save'));
94 }
95
96 /**
97 * create the menu pages for isc
98 */
99 public function create_menu() {
100
101 // this page should be accessable by editors and higher
102 $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', '');
103 }
104
105 /**
106 * add scripts to admin pages
107 */
108 public function add_admin_scripts($hook) {
109 if ('wg-image-source-control/templates/missing_sources.php' != $hook)
110 return;
111 wp_enqueue_script('isc_script', plugins_url('/js/isc.js', __FILE__), false, ISCVERSION);
112 // this is to define ajaxurl to be able to use this in its own js script
113 // wp_localize_script( 'isc_script', 'IscAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
114 }
115
116 /**
117 * add custom field to attachment
118 * @param arr $form_fields
119 * @param object $post
120 * @return arr
121 * @since 1.0
122 * @updated 1.1
123 */
124 public function add_isc_fields($form_fields, $post) {
125 // add input field for source
126 $form_fields['isc_image_source']['label'] = __('Image Source', ISCTEXTDOMAIN);
127 $form_fields['isc_image_source']['value'] = get_post_meta($post->ID, 'isc_image_source', true);
128 $form_fields['isc_image_source']['helps'] = __('Include the image source here.', ISCTEXTDOMAIN);
129
130 // add checkbox to mark as your own image
131 $form_fields['isc_image_source_own']['input'] = 'html';
132 $form_fields['isc_image_source_own']['helps'] = __('Check this box if this is your own image and doesn\'t need a source.', ISCTEXTDOMAIN);
133 $form_fields['isc_image_source_own']['html'] = "<input type='checkbox' value='1' name='attachments[{$post->ID}][isc_image_source_own]' id='attachments[{$post->ID}][isc_image_source_own]' " . checked(get_post_meta($post->ID, 'isc_image_source_own', true), 1, false ) . "/> "
134 . __('This is my image', ISCTEXTDOMAIN);
135
136 return $form_fields;
137 }
138
139 /**
140 * save image source to post_meta
141 * @param object $post
142 * @param $attachment
143 * @return object $post
144 */
145 public function isc_fields_save($post, $attachment) {
146
147 if (isset($attachment['isc_image_source']))
148 update_post_meta($post['ID'], 'isc_image_source', $attachment['isc_image_source']);
149
150 update_post_meta($post['ID'], 'isc_image_source_own', $attachment['isc_image_source_own']);
151 return $post;
152 }
153
154 /**
155 * create image sources list for all images of this post
156 * @since 1.0
157 * @update 1.1
158 * @param int $post_id id of the current post/page
159 * @return echo output
160 */
161 public function list_post_attachments_with_sources($post_id = 0) {
162
163 if (empty($post_id)) {
164 global $post;
165 if (!empty($post->ID)) {
166 $post_id = $post->ID;
167 }
168 }
169
170 if (empty($post_id))
171 return;
172
173 $attachments = get_post_meta($post_id, 'isc_post_images', true);
174 // if attachments is an empty string, search for images in it
175 if ( $attachments == '' ) {
176 $this->save_image_information_on_load ($post_id, $_content);
177 $attachments = get_post_meta($post_id, 'isc_post_images', true);
178 }
179
180 $return = '';
181 if (!empty($attachments)) :
182 ob_start();
183 ?>
184 <p class="isc_image_list_title"><?php _e('image sources:', ISCTEXTDOMAIN); ?></p>
185 <ul class="isc_image_list"><?php
186 $atts = array();
187 foreach ($attachments as $attachment_id => $attachment_array) {
188
189 $atts[ $attachment_id ]['title'] = get_the_title($attachment_id);
190 $own = get_post_meta($attachment_id, 'isc_image_source_own', true);
191 $source = get_post_meta($attachment_id, 'isc_image_source', true);
192
193 if ( $own == '' AND $source == '' ) {
194 // remove if no information set
195 unset( $atts[ $attachment_id ] );
196 continue;
197 } elseif ( $own != '' ) {
198 $atts[ $attachment_id ]['source'] = __('by the author', ISCTEXTDOMAIN);
199 } else {
200 $atts[ $attachment_id ]['source'] = $source;
201 }
202
203 }
204
205 foreach ($atts as $atts_id => $atts_array) :
206 if ( empty( $atts_array['source'] ) ) continue;
207 ?><li><?php echo $atts_array['title'] . ': ' . $atts_array['source']; ?></li><?php
208 endforeach;
209 ?></ul><?php
210 $return = ob_get_clean();
211
212 endif;
213
214 // don't display anything, if no image sources displayed
215 if ( count( $atts ) === 0 ) return;
216
217 return $return;
218 }
219
220 /**
221 * shortcode function to list all image sources
222 * @param arr $atts
223 */
224 public function list_post_attachments_with_sources_shortcode($atts = array()) {
225
226 extract(shortcode_atts(array(
227 'id' => 0,
228 ), $atts));
229
230 // if $id not set, use the current ID from the post
231 if (empty($id)) {
232 global $post;
233 $id = $post->ID;
234 }
235
236 if (empty($id))
237 return;
238 return $this->list_post_attachments_with_sources($id);
239 }
240
241 /**
242 * get all attachments without sources
243 * the downside of this function: is there is not even an empty metakey field, nothing is going to be retrieved
244 * @todo fix this in WP 3.5 with compare => 'NOT EXISTS'
245 */
246 public function get_attachments_without_sources() {
247
248 $args = array(
249 'post_type' => 'attachment',
250 'numberposts' => -1,
251 'post_status' => null,
252 'post_parent' => null,
253 'meta_query' => array(
254 // image source is empty
255 array(
256 'key' => 'isc_image_source',
257 'value' => '',
258 'compare' => '=',
259 ),
260 // and image source is not set
261 array(
262 'key' => 'isc_image_source_own',
263 'value' => '1',
264 'compare' => '!=',
265 ),
266 )
267 );
268 $attachments = get_posts($args);
269 if (!empty($attachments)) {
270 return $attachments;
271 }
272 }
273
274 /**
275 * add meta values to all attachments
276 * @todo probably need to fix this when more fields are added along the way
277 * @todo use compare => 'NOT EXISTS' when WP 3.5 is up to retrieve only values where it is not set
278 * @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
279 */
280 public function add_meta_values_to_attachments() {
281
282 // retrieve all attachments
283 $args = array(
284 'post_type' => 'attachment',
285 'numberposts' => -1,
286 'post_status' => null,
287 'post_parent' => null,
288 );
289
290 $attachments = get_posts($args);
291 if (empty($attachments))
292 return;
293
294 $count = 0;
295 foreach ($attachments as $_attachment) {
296 $set = 0;
297 setup_postdata($_attachment);
298 foreach ($this->_fields as $_field) {
299 $meta = get_post_meta($_attachment->ID, $_field['id'], true);
300 if (empty($meta)) {
301 update_post_meta($_attachment->ID, $_field['id'], $_field['default']);
302 $set = 1;
303 }
304 }
305 if ($set)
306 $count++;
307 }
308 echo sprintf(__('Added meta fields to %d images.', ISCTEXTDOMAIN), $count);
309 die();
310 }
311
312 /**
313 * show the loading image from wp-admin/images/loading.gif
314 * @param bool $display should this be displayed directly or hidden? via inline css
315 */
316 public function show_loading_image($display = true) {
317
318 $img_path = admin_url("/images/loading.gif");
319 $file_path = ABSPATH . "wp-admin/images/loading.gif";
320 if (file_exists($file_path)) {
321 echo '<span id="isc_loading_img" style="display: none;"><img src="' . $img_path . '" width="16" height="16" alt="loading"/></span>';
322 }
323 }
324
325 /**
326 * this is an entry function to save image information to a post when it is saved
327 * @since 1.1
328 * @param type $post_id
329 */
330 public function save_image_information_on_post_save($post_id) {
331
332 // return, if save_post is called more than one time
333 if (did_action('save_post') !== 1)
334 return;
335
336 if ('attachment' == $_POST['post_type']) {
337 return;
338 }
339
340 // check if this is a revision and if so, use parent post id
341 if ($_id = wp_is_post_revision($post_id))
342 $post_id = $_id;
343
344 $_content = stripslashes($_REQUEST['content']);
345 $this->save_image_information($post_id, $_content);
346
347 }
348
349 /**
350 * save image information for a post when it is viewed and the image source list is enabled
351 * (this is in case the plugin is new and the current post wasn't saved before)
352 *
353 * @since 1.1
354 */
355
356 public function save_image_information_on_load( ) {
357
358 global $post;
359 if (empty( $post->ID )) return;
360
361 $post_id = $post->ID;
362 $_content = $post->post_content;
363
364 $this->save_image_information($post_id, $_content);
365
366 }
367
368 /**
369 * retrieve images added to a post or page and save all information as a meta value
370 * @since 1.1
371 * @todo check for more post types that maybe should not be parsed here
372 */
373 public function save_image_information( $post_id, $_content ) {
374
375 $_image_urls = $this->_filter_src_attributes($_content);
376
377 $_imgs = array();
378
379 foreach ($_image_urls as $_image_url) {
380 // get ID of images by url
381 $img_id = $this->get_image_by_url($_image_url);
382 $_imgs[$img_id] = array(
383 'src' => $_image_url
384 );
385 }
386
387 // add thumbnail information
388 $thumb_id = get_post_thumbnail_id($post_id);
389 $_imgs[$thumb_id] = array(
390 'src' => wp_get_attachment_url($thumb_id),
391 'thumbnail' => true
392 );
393
394 if (empty($_imgs))
395 $_imgs = false;
396 update_post_meta($post_id, 'isc_post_images', $_imgs);
397 }
398
399 /**
400 * filter image src attribute from text
401 * @since 1.1
402 * @return array with image src uris
403 */
404 public function _filter_src_attributes($content = '') {
405
406 $srcs = array();
407 if (empty($content))
408 return $srcs;
409
410 // parse HTML with DOM
411 $dom = new DOMDocument;
412 $dom->loadHTML($content);
413 foreach ($dom->getElementsByTagName('img') as $node) {
414 $srcs[] = $node->getAttribute('src');
415 }
416
417 return $srcs;
418 }
419
420 /**
421 * get image by url accessing the database directly
422 * @since 1.1
423 * @param string $url url of the image
424 * @return id of the image
425 */
426 public function get_image_by_url($url = '') {
427
428 if (empty($url))
429 return 0;
430 $types = implode('|', $this->_allowedExtensions);
431 // check for the format 'image-title-300x200.jpg' and remove the image size from it
432 $newurl = preg_replace("/-(\d+)x(\d+)\.({$types})$/i", '.${3}', $url);
433 global $wpdb;
434 $query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid = %s", $newurl);
435 $id = $wpdb->get_var($query);
436 return $id;
437 }
438
439 }
440
441 function add_image_source_fields_start() {
442
443 $isc = new ISC_CLASS();
444 }
445
446 add_action('plugins_loaded', 'add_image_source_fields_start');
447
448 /**
449 * the next functions are just to have an easier access from outside the class
450 */
451 function isc_list($post_id = 0) {
452
453 $isc = new ISC_CLASS();
454 echo $isc->list_post_attachments_with_sources($post_id);
455
456 }
457
458 }
459
460