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
← All changes | isc.php +415 -14 1.3.41.1 View file →
@@ -1,12 +1,12 @@
1 1 <?php
2 2 /*
3 3 Plugin Name: Image Source Control
4 - Version: 1.3.4
5 - Plugin URI: http://webgilde.com/en/image-source-control/
4 + Version: 1.1
5 + Plugin URI: none
6 6 Description: The Image Source Control saves the source of an image, lists them and warns if it is missing.
7 7 Author: Thomas Maier
8 - Author URI: http://www.webgilde.com/
8 + Author URI: http://www.webgilde.com
9 9 License: GPL v3
10 10
11 11 Image Source Control Plugin for WordPress
12 12 Copyright (C) 2012, Thomas Maier - thomas.maier@webgilde.com
@@ -22,14 +22,14 @@
22 22 GNU General Public License for more details.
23 23
24 24 You should have received a copy of the GNU General Public License
25 25 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 - *
26 + *
27 27 * Followed the following tutorials
28 28 * http://wpengineer.com/2076/add-custom-field-attachment-in-wordpress/
29 29 * http://bueltge.de/eigene-felder-dateiverwaltung-wordpress/1226/ (same like above, but in German)
30 - *
31 - *
30 + *
31 + *
32 32 */
33 33
34 34 //avoid direct calls to this file
35 35 if (!function_exists('add_action')) {
@@ -37,22 +37,423 @@
37 37 header('HTTP/1.1 403 Forbidden');
38 38 exit();
39 39 }
40 40
41 -define('ISCVERSION', '1.3.4');
41 +define('ISCVERSION', '1.1');
42 42 define('ISCNAME', 'Image Source Control');
43 43 define('ISCTEXTDOMAIN', 'isc');
44 44 define('ISCDIR', basename(dirname(__FILE__)));
45 45 define('ISCPATH', plugin_dir_path(__FILE__));
46 -define('WEBGILDE', 'http://webgilde.com/en/image-source-control');
47 46
48 47 load_plugin_textdomain(ISCTEXTDOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages/');
49 48
50 -require_once(ISCPATH . '/isc.class.php');
49 +if (!class_exists('ISC_CLASS')) {
51 50
52 -global $my_isc;
53 -$my_isc = new ISC_CLASS();
51 + class ISC_CLASS {
54 52
55 -function isc_list($post_id = 0) {
56 - global $my_isc;
57 - echo $my_isc->list_post_attachments_with_sources($post_id);
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 +
58 458 }
459 +