PluginProbe
Image Source Control Lite – Show Image Credits and Captions / 1.3.3
Image Source Control Lite – Show Image Credits and Captions v1.3.3
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.3.3, at isc.php

1,529 lines 64.8 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.3.3
5 Plugin URI: http://webgilde.com/en/image-source-control/
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.3.3');
42 define('ISCNAME', 'Image Source Control');
43 define('ISCTEXTDOMAIN', 'isc');
44 define('ISCDIR', basename(dirname(__FILE__)));
45 define('ISCPATH', plugin_dir_path(__FILE__));
46 define('WEBGILDE', 'http://webgilde.com/en/image-source-control');
47
48 load_plugin_textdomain(ISCTEXTDOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages/');
49
50 if (!class_exists('ISC_CLASS')) {
51
52 class ISC_CLASS
53 {
54 /**
55 * define default meta fields
56 */
57 protected $_fields = array(
58 'image_source' => array(
59 'id' => 'isc_image_source',
60 'default' => '',
61 ),
62 'image_source_own' => array(
63 'id' => 'isc_image_source_own',
64 'default' => '',
65 ),
66 'image_posts' => array(
67 'id' => 'isc_image_posts',
68 'default' => array()
69 )
70 );
71
72 /**
73 * Commonly used text elements
74 */
75 protected $_common_texts = array();
76
77 /**
78 * allowed image file types/extensions
79 * @since 1.1
80 */
81 protected $_allowedExtensions = array(
82 'jpg', 'png', 'gif', 'jpeg'
83 );
84
85 /**
86 * Thumbnail size in list of all images.
87 * @since 1.2
88 */
89 protected $_thumbnail_size = array('thumbnail', 'medium', 'large', 'custom');
90
91 /**
92 * options saved in the db
93 * @since 1.2
94 */
95 protected $_options = array();
96
97 /**
98 * Position of image's caption
99 */
100 protected $_caption_position = array(
101 'top-left',
102 'top-center',
103 'top-right',
104 'center',
105 'bottom-left',
106 'bottom-center',
107 'bottom-right'
108 );
109
110 /**
111 * Setup registers filterts and actions.
112 */
113 public function __construct()
114 {
115 // load all plugin options
116 $this->_options = get_option('isc_options');
117 $this->_common_texts['not_available'] = __('Not available', ISCTEXTDOMAIN);
118
119 // insert all function for the frontend here
120
121 add_shortcode('isc_list', array($this, 'list_post_attachments_with_sources_shortcode'));
122 add_shortcode('isc_list_all', array($this, 'list_all_post_attachments_sources_shortcode'));
123 add_action('wp_enqueue_scripts', array($this, 'front_scripts'));
124 add_action('wp_head', array($this, 'front_head'));
125 add_action('the_content', array($this, 'content_filter'));
126 // insert all backend functions below this check
127 if (!current_user_can('upload_files')) {
128 return false;
129 }
130
131 register_activation_hook(ISCPATH . '/isc.php', array($this, 'activation'));
132
133 add_action('add_attachment', array($this, 'attachment_added'), 10, 2);
134 add_filter('attachment_fields_to_edit', array($this, 'add_isc_fields'), 10, 2);
135 add_filter('attachment_fields_to_save', array($this, 'isc_fields_save'), 10, 2);
136
137 add_action('admin_notices', array($this, 'admin_notices'));
138
139 add_action('admin_menu', array($this, 'create_menu'));
140 add_action('admin_init', array($this, 'SAPI_init'));
141
142 add_action('admin_enqueue_scripts', array($this, 'add_admin_scripts'));
143 add_action( 'admin_print_scripts', array($this, 'admin_headjs') );
144
145 // save image information in meta field when a post is saved
146 add_action('save_post', array($this, 'save_image_information_on_post_save'));
147 }
148
149 public function get_source_by_url($url)
150 {
151 $id = $this->get_image_by_url($url);
152 $metadata['source'] = get_post_meta($id, 'isc_image_source', true);
153 $metadata['own'] = get_post_meta($id, 'isc_image_source_own', true);
154
155 $source = $this->_common_texts['not_available'];
156
157 $att_post = get_post($id);
158
159 if ('' != $metadata['own']) {
160 if ($this->_options['use_authorname']) {
161 if (!empty($att_post)) {
162 $source = get_the_author_meta('display_name', $att_post->post_author);
163 }
164 } else {
165 $source = $this->options['by_author_text'];
166 }
167 } else {
168 if ('' != $metadata['source']) {
169 $source = $metadata['source'];
170 }
171 }
172 return $source;
173 }
174
175 public function content_filter($content)
176 {
177 $options = $this->get_isc_options();
178 if ($options['source_on_image']) {
179 $pattern = '#(\[caption.*align="(.+)"[^\]*]{0,}\])? *(<a [^>]+>)? *(<img .*class=".*(align\d{4,})?.*wp-image-(\d+)\D*".*src="(.+)".*/?>).*(?(3)(?:</a>)|.*).*(?(1)(?:\[/caption\])|.*)#isU';
180 $count = preg_match_all($pattern, $content, $matches);
181 if (false !== $count) {
182 for ($i=0; $i < $count; $i++) {
183 $id = $matches[6][$i];
184 $src = $matches[7][$i];
185 $source = '<p class="isc-source-text">' . $options['source_pretext'] . ' ' . $this->get_source_by_url($src) . '</p>';
186 $old_content = $matches[0][$i];
187 $new_content = str_replace('wp-image-' . $id, 'wp-image-' . $id . ' with-source', $old_content);
188 $alignment = (!empty($matches[1][$i]))? $matches[2][$i] : $matches[5][$i];
189
190 $content = str_replace($old_content, '<div id="isc_attachment_' . $id . '" class="isc-source ' . $alignment . '"> ' . $new_content . $source . '</div>', $content);
191 }
192 }
193 }
194 return $content;
195 }
196
197 public function attachment_added($att_id)
198 {
199 foreach ($this->_fields as $field) {
200 update_post_meta($att_id, $field['id'], $field['default']);
201 }
202 }
203
204 /**
205 * Front-end scripts in <head /> section.
206 */
207 public function front_head()
208 {
209 $options = $this->get_isc_options();
210 ?>
211 <script type="text/javascript">
212 /* <![CDATA[ */
213 var isc_front_data =
214 {
215 caption_position : '<?php echo $options['caption_position']; ?>',
216 }
217 /* ]]> */
218 </script>
219 <?php
220 }
221
222 /**
223 * Enqueue scripts for the front-end.
224 */
225 public function front_scripts() {
226 wp_enqueue_script('isc_front_js', plugins_url('/js/front-js.js', __FILE__), array('jquery'), ISCVERSION);
227 }
228
229 /**
230 * create the menu pages for isc
231 */
232 public function create_menu()
233 {
234 global $isc_missing;
235 global $isc_setting;
236
237 /**
238 * Check if the page is already created.
239 */
240 if (empty($isc_missing)) {
241 // these pages should be accessible by editors and higher
242 $isc_missing = add_submenu_page('upload.php', 'missing image sources by Image Source Control Plugin', __('Missing Sources', ISCTEXTDOMAIN), 'edit_others_posts', ISCPATH . '/templates/missing_sources.php', '');
243 $isc_setting = add_options_page(__('Image control - ISC plugin', ISCTEXTDOMAIN), __('Image Control', ISCTEXTDOMAIN), 'edit_others_posts', 'isc_settings_page', array($this, 'render_isc_settings_page'));
244 }
245 }
246
247 /**
248 * add scripts to admin pages
249 * @since 1.0
250 * @update 1.1.1
251 */
252 public function add_admin_scripts($hook)
253 {
254 global $isc_setting;
255 if ('post.php' == $hook) {
256 wp_enqueue_script('isc_postphp_script', plugins_url('/js/post.php.js', __FILE__), array('jquery'), ISCVERSION);
257 }
258 if ($hook == $isc_setting) {
259 wp_enqueue_script('isc_script', plugins_url('/js/isc.js', __FILE__), false, ISCVERSION);
260 wp_enqueue_style('isc_image_settings_css', plugins_url('/css/image-settings.css', __FILE__), false, ISCVERSION);
261 }
262 }
263
264 /**
265 * add custom field to attachment
266 * @param arr $form_fields
267 * @param object $post
268 * @return arr
269 * @since 1.0
270 * @updated 1.1
271 */
272 public function add_isc_fields($form_fields, $post)
273 {
274 // add input field for source
275 $form_fields['isc_image_source']['label'] = __('Image Source', ISCTEXTDOMAIN);
276 $form_fields['isc_image_source']['value'] = get_post_meta($post->ID, 'isc_image_source', true);
277 $form_fields['isc_image_source']['helps'] = __('Include the image source here.', ISCTEXTDOMAIN);
278
279 // add checkbox to mark as your own image
280 $form_fields['isc_image_source_own']['input'] = 'html';
281 $form_fields['isc_image_source_own']['label'] = '';
282 $form_fields['isc_image_source_own']['helps'] =
283 __('Check this box if this is your own image and doesn\'t need a source.', ISCTEXTDOMAIN);
284 $form_fields['isc_image_source_own']['html'] =
285 "<input type='checkbox' value='1' name='attachments[{$post->ID}][isc_image_source_own]' id='attachments[{$post->ID}][isc_image_source_own]' "
286 . checked(get_post_meta($post->ID, 'isc_image_source_own', true), 1, false )
287 . " style=\"width:14px\"/> "
288 . __('This is my image', ISCTEXTDOMAIN);
289
290 return $form_fields;
291 }
292
293 /**
294 * save image source to post_meta
295 * @param object $post
296 * @param $attachment
297 * @return object $post
298 */
299 public function isc_fields_save($post, $attachment)
300 {
301 if (isset($attachment['isc_image_source'])) {
302 update_post_meta($post['ID'], 'isc_image_source', $attachment['isc_image_source']);
303 }
304 update_post_meta($post['ID'], 'isc_image_source_own', $attachment['isc_image_source_own']);
305 return $post;
306 }
307
308 /**
309 * create image sources list for all images of this post
310 * @since 1.0
311 * @update 1.1
312 * @param int $post_id id of the current post/page
313 * @return echo output
314 */
315 public function list_post_attachments_with_sources($post_id = 0)
316 {
317 global $post;
318
319 if (empty($post_id)) {
320 if (!empty($post->ID)) {
321 $post_id = $post->ID;
322 } else {
323 return;
324 }
325 }
326
327 $attachments = get_post_meta($post_id, 'isc_post_images', true);
328 // if attachments is an empty string, search for images in it
329 if ($attachments == '') {
330 $this->save_image_information_on_load();
331 $this->update_image_posts_meta($post_id, $post->post_content);
332
333 $attachments = get_post_meta($post_id, 'isc_post_images', true);
334 }
335
336 $return = '';
337 if (!empty($attachments)) {
338 $atts = array();
339 foreach ($attachments as $attachment_id => $attachment_array) {
340 $atts[$attachment_id]['title'] = get_the_title($attachment_id);
341 $own = get_post_meta($attachment_id, 'isc_image_source_own', true);
342 $source = get_post_meta($attachment_id, 'isc_image_source', true);
343
344 if ( $own == '' && $source == '' ) {
345 // remove if no information set
346 unset($atts[$attachment_id]);
347 continue;
348 } elseif ($own != '') {
349 if ($this->_options['use_authorname']) {
350 $authorname = '';
351 $att_post = get_post($attachment_id);
352 if (null !== $att_post) {
353 $authorname = get_the_author_meta('display_name', $att_post->post_author);
354 }
355 $atts[$attachment_id ]['source'] = $authorname;
356 } else {
357 $atts[$attachment_id ]['source'] = $this->_options['by_author_text'];
358 }
359 } else {
360 $atts[$attachment_id ]['source'] = $source;
361 }
362 }
363
364 $return = $this->_renderAttachments($atts);
365 }
366
367 return $return;
368 }
369
370 /**
371 * @param array $attachments
372 */
373 protected function _renderAttachments($attachments)
374 {
375 // don't display anything, if no image sources displayed
376 if ($attachments == array()) {
377 return ;
378 }
379
380 $options = $this->get_isc_options();
381 $show_text = __('Show the list', ISCTEXTDOMAIN);
382 $hide_text = __('Hide the list', ISCTEXTDOMAIN);
383
384 ob_start();
385 $headline = $this->_options['image_list_headline'];
386 $hide_style = ($options['hide_list'])? 'style="height: 0px; overflow: hidden;"': 'style="height: 100%; overflow: hidden;"';
387 $hide_class = ($options['hide_list'])? ' isc-list-up': ' isc-list-down';
388 $hide_title = ($options['hide_list'])? $show_text : $hide_text;
389 printf('<p class="isc_image_list_title" title="%2$s" style="cursor: pointer;">%1$s</p>', $headline, $hide_title); ?>
390 <script type="text/javascript">
391 /* <!--[CDATA[ */
392 isc_jstext = {
393 show_list: "<?php echo esc_attr($show_text); ?>",
394 hide_list: "<?php echo esc_attr($hide_text); ?>"
395 }
396 /* ]]--> */
397 </script>
398 <ul class="isc_image_list <?php echo $hide_class; ?>"<?php echo $hide_style; ?>><?php
399
400 foreach ($attachments as $atts_id => $atts_array) {
401 if (empty($atts_array['source'])) {
402 continue;
403 }
404 printf('<li>%1$s: %2$s</li>', $atts_array['title'], $atts_array['source']);
405 }
406 ?></ul><?php
407 return ob_get_clean();
408 }
409
410 /**
411 * shortcode function to list all image sources
412 * @param arr $atts
413 */
414 public function list_post_attachments_with_sources_shortcode($atts = array())
415 {
416 global $post;
417 extract(shortcode_atts(array('id' => 0), $atts));
418
419 // if $id not set, use the current ID from the post
420 if (empty($id)) {
421 $id = $post->ID;
422 }
423
424 if (empty($id)) {
425 return;
426 }
427 return $this->list_post_attachments_with_sources($id);
428 }
429
430 /**
431 * get all attachments without sources
432 * the downside of this function: is there is not even an empty metakey field, nothing is going to be retrieved
433 * @todo fix this in WP 3.5 with compare => 'NOT EXISTS'
434 */
435 public function get_attachments_without_sources()
436 {
437 $args = array(
438 'post_type' => 'attachment',
439 'numberposts' => -1,
440 'post_status' => null,
441 'post_parent' => null,
442 'meta_query' => array(
443 // image source is empty
444 array(
445 'key' => 'isc_image_source',
446 'value' => '',
447 'compare' => '=',
448 ),
449 // and image source is not set
450 array(
451 'key' => 'isc_image_source_own',
452 'value' => '1',
453 'compare' => '!=',
454 ),
455 )
456 );
457
458 $attachments = get_posts($args);
459 if (!empty($attachments)) {
460 return $attachments;
461 }
462 }
463
464 /**
465 * add meta values to all attachments
466 * @todo probably need to fix this when more fields are added along the way
467 * @todo use compare => 'NOT EXISTS' when WP 3.5 is up to retrieve only values where it is not set
468 * @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
469 */
470 public function add_meta_values_to_attachments()
471 {
472 // retrieve all attachments
473 $args = array(
474 'post_type' => 'attachment',
475 'numberposts' => -1,
476 'post_status' => null,
477 'post_parent' => null,
478 );
479
480 $attachments = get_posts($args);
481 if (empty($attachments)) {
482 return;
483 }
484
485 $count = 0;
486 foreach ($attachments as $_attachment) {
487 $set = false;
488 setup_postdata($_attachment);
489 foreach ($this->_fields as $_field) {
490 $meta = get_post_meta($_attachment->ID, $_field['id'], true);
491 if (empty($meta)) {
492 update_post_meta($_attachment->ID, $_field['id'], $_field['default']);
493 $set = true;
494 }
495 }
496 if ($set) {
497 $count++;
498 }
499 }
500 }
501
502 /**
503 * Display scripts in <head></head> section of admin page. Useful for creating js variables in the js global namespace.
504 */
505 public function admin_headjs()
506 {
507 global $pagenow;
508 $options = $this->get_isc_options();
509 if ('post.php' == $pagenow) {
510 ?>
511 <script type="text/javascript">
512 /* <![CDATA[ */
513 isc_data = {
514 warning_nosource : <?php echo (($options['warning_nosource'])? 'true' : 'false'); ?>,
515 block_form_message : '<?php _e('Please specify the image source', ISCTEXTDOMAIN); ?>'
516 }
517 /* ]]> */
518 </script>
519 <?php
520 }
521 }
522
523 /**
524 * show the loading image from wp-admin/images/loading.gif
525 * @param bool $display should this be displayed directly or hidden? via inline css
526 */
527 public function show_loading_image($display = true)
528 {
529 $img_path = admin_url("/images/loading.gif");
530 $file_path = ABSPATH . "wp-admin/images/loading.gif";
531 if (file_exists($file_path)) {
532 echo '<span id="isc_loading_img" style="display: none;"><img src="' . $img_path . '" width="16" height="16" alt="loading"/></span>';
533 }
534 }
535
536 /**
537 * this is an entry function to save image information to a post when it is saved
538 * @since 1.1
539 * @param type $post_id
540 */
541 public function save_image_information_on_post_save($post_id)
542 {
543 // return, if save_post is called more than one time
544 if (did_action('save_post') !== 1) {
545 return;
546 }
547
548 if (isset($_POST['post_type']) && 'attachment' == $_POST['post_type']) {
549 return;
550 }
551
552 // check if this is a revision and if so, use parent post id
553 if ($_id = wp_is_post_revision($post_id)) {
554 $post_id = $_id;
555 }
556
557 $_content = '';
558 if ( !empty( $_REQUEST['content']) ) $_content = stripslashes($_REQUEST['content']);
559
560 // Needs to be called before the 'isc_post_images' field is updated.
561 $this->update_image_posts_meta($post_id, $_content);
562
563 $this->save_image_information($post_id, $_content);
564 }
565
566 /**
567 * save image information for a post when it is viewed and the image source list is enabled
568 * (this is in case the plugin is new and the current post wasn't saved before)
569 *
570 * @since 1.1
571 */
572 public function save_image_information_on_load()
573 {
574 global $post;
575 if (empty($post->ID)) {
576 return;
577 }
578
579 $post_id = $post->ID;
580 $_content = $post->post_content;
581
582 $this->save_image_information($post_id, $_content);
583 }
584
585 /**
586 * retrieve images added to a post or page and save all information as a meta value
587 * @since 1.1
588 * @todo check for more post types that maybe should not be parsed here
589 */
590 public function save_image_information($post_id, $_content)
591 {
592 $_image_urls = $this->_filter_src_attributes($_content);
593 $_imgs = array();
594
595 foreach ($_image_urls as $_image_url) {
596 // get ID of images by url
597 $img_id = $this->get_image_by_url($_image_url);
598 $_imgs[$img_id] = array(
599 'src' => $_image_url
600 );
601 }
602
603 // add thumbnail information
604 $thumb_id = get_post_thumbnail_id($post_id);
605
606 /**
607 * if an image is used both inside the post and as post thumbnail, the thumbnail entry overrides the regular image.
608 */
609 if ( !empty( $thumb_id )) {
610 $_imgs[$thumb_id] = array(
611 'src' => wp_get_attachment_url($thumb_id),
612 'thumbnail' => true
613 );
614 }
615
616 if (empty($_imgs)) {
617 $_imgs = false;
618 }
619 update_post_meta($post_id, 'isc_post_images', $_imgs);
620 }
621
622 /**
623 * filter image src attribute from text
624 * @since 1.1
625 * @updated 1.1.3
626 * @return array with image src uris
627 */
628 public function _filter_src_attributes($content = '')
629 {
630 $srcs = array();
631 if (empty($content))
632 return $srcs;
633
634 // parse HTML with DOM
635 $dom = new DOMDocument;
636
637 libxml_use_internal_errors(true);
638 $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
639 $dom->loadHTML($content);
640
641 // Prevents from sending E_WARNINGs notice (Outputs are forbidden during activation)
642 libxml_clear_errors();
643
644 foreach ($dom->getElementsByTagName('img') as $node) {
645 $srcs[] = $node->getAttribute('src');
646 }
647
648 return $srcs;
649 }
650
651 /**
652 * get image by url accessing the database directly
653 * @since 1.1
654 * @updated 1.1.3
655 * @param string $url url of the image
656 * @return id of the image
657 */
658 public function get_image_by_url($url = '')
659 {
660 if (empty($url)) {
661 return 0;
662 }
663 $types = implode('|', $this->_allowedExtensions);
664 // check for the format 'image-title-(e12452112-)300x200.jpg' and remove the image size and edit mark from it
665 $newurl = preg_replace("/(-e\d+){0,1}-(\d+)x(\d+)\.({$types})$/i", '.${4}', $url);
666 global $wpdb;
667 $query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid = %s", $newurl);
668 $id = $wpdb->get_var($query);
669 return $id;
670 }
671
672 /**
673 * Update isc_image_posts meta field for all images found in a post with a given ID.
674 * @param $post_id ID of the target post
675 * @param $content content of the target post
676 */
677 public function update_image_posts_meta($post_id, $content)
678 {
679 $image_urls = $this->_filter_src_attributes($content);
680 $image_ids = array();
681 $added_images = array();
682 $removed_images = array();
683
684 // add thumbnail information
685 $thumb_id = get_post_thumbnail_id($post_id);
686 if ( !empty( $thumb_id )) { $image_urls[] = wp_get_attachment_url($thumb_id); }
687
688 $isc_post_images = get_post_meta($post_id, 'isc_post_images', true);
689
690 foreach ($image_urls as $url) {
691 $id = intval($this->get_image_by_url($url));
692 array_push($image_ids, $id);
693 if (is_array($isc_post_images) && !array_key_exists($id, $isc_post_images)) {
694 array_push($added_images, $id);
695 }
696 }
697 if (is_array($isc_post_images)) {
698 foreach ($isc_post_images as $old_id => $value) {
699 if (!in_array($old_id, $image_ids)) {
700 array_push($removed_images, $old_id);
701 } else {
702 if (!empty($old_id)) {
703 $meta = get_post_meta($old_id, 'isc_image_posts', true);
704 if (empty($meta)) {
705 update_post_meta($old_id, 'isc_image_posts', array($post_id));
706 } else {
707 // In case the isc_image_posts is not up to date
708 if (is_array($meta) && !in_array($post_id, $meta)) {
709 array_push($meta, $post_id);
710 update_post_meta($old_id, 'isc_image_posts', $meta);
711 }
712 }
713 }
714 }
715 }
716 }
717
718 foreach ($added_images as $id) {
719 $meta = get_post_meta($id, 'isc_image_posts', true);
720 if (!is_array($meta) || array() == $meta) {
721 update_post_meta($id, 'isc_image_posts', array($post_id));
722 } else {
723 array_push($meta, $post_id);
724 update_post_meta($id, 'isc_image_posts', $meta);
725 }
726 }
727
728 foreach ($removed_images as $id) {
729 $image_meta = get_post_meta($id, 'isc_image_posts', true);
730 if (is_array($image_meta)) {
731 $offset = array_search($post_id, $image_meta);
732 if (false !== $offset) {
733 array_splice($image_meta, $offset, 1);
734 update_post_meta($id, 'isc_image_posts', $image_meta);
735 }
736 }
737 }
738 }
739
740 /**
741 * create shortcode to list all image sources in the frontend
742 * @param array $atts
743 * @since 1.1.3
744 * @todo link to the post
745 */
746 public function list_all_post_attachments_sources_shortcode($atts = array())
747 {
748
749 /**
750 * @todo why not translate here with the code below?
751 * > Because the two if statements below will need to call gettext (again) for comparing values.
752 */
753 extract(shortcode_atts(array(
754 'per_page' => 99999,
755 'before_links' => '',
756 'after_links' => '',
757 'prev_text' => '&#171; Previous',
758 'next_text' => 'Next &#187;'
759 ),
760 $atts));
761
762 /**
763 * @todo why not include this into the array above?
764 */
765 if ('&#171; Previous' == $prev_text)
766 $prev_text = __('&#171; Previous', ISCTEXTDOMAIN);
767 if ('Next &#187;' == $next_text)
768 $next_text = __('Next &#187;', ISCTEXTDOMAIN);
769
770 // retrieve all attachments
771 $args = array(
772 'post_type' => 'attachment',
773 'numberposts' => -1,
774 'post_status' => null,
775 'post_parent' => null,
776 'meta_query' => array(
777 array(
778 'key' => 'isc_image_posts',
779 'value' => 'a:0:{}',
780 'compare' => '!='
781 )
782 )
783 /** @todo maybe add offset to not retrieve the first results when not on first page */
784 /** @todo maybe add limit to not retrieve more results than on the current page */
785 /** >No, we need to get total count of attachment with parents for $max_page in the pagination link. */
786 );
787
788 $attachments = get_posts($args);
789 if (empty($attachments)) {
790 return;
791 }
792
793 $options = $this->get_isc_options();
794
795 $connected_atts = array();
796
797 //Keeps only those ones who have parent
798
799 foreach ($attachments as $_attachment) {
800 $connected_atts[$_attachment->ID]['source'] = get_post_meta($_attachment->ID, 'isc_image_source', true);
801 $connected_atts[$_attachment->ID]['own'] = get_post_meta($_attachment->ID, 'isc_image_source_own', true);
802 $connected_atts[$_attachment->ID]['title'] = $_attachment->post_title;
803 $connected_atts[$_attachment->ID]['author_name'] = '';
804 if ('' != $connected_atts[$_attachment->ID]['own']) {
805 $connected_atts[$_attachment->ID]['author_name'] = get_the_author_meta('display_name', $_attachment->post_author);
806 }
807
808 $metadata = get_post_meta($_attachment->ID, 'isc_image_posts', true);
809 $usage_data = '';
810
811 if (is_array($metadata) && array() != $metadata) {
812 $usage_data .= "<ul style='margin: 0;'>";
813 foreach($metadata as $data) {
814 $usage_data .= sprintf(__('<li><a href="%1$s" title="View %2$s">%3$s</a></li>', ISCTEXTDOMAIN),
815 esc_url(get_permalink($data)),
816 esc_attr(get_the_title($data)),
817 esc_html(get_the_title($data))
818 );
819 }
820 $usage_data .= "</ul>";
821 }
822
823 $connected_atts[$_attachment->ID]['posts'] = $usage_data;
824 }
825
826 $total = count($connected_atts);
827
828 if (0 == $total)
829 return;
830
831 $page = isset($_GET['isc-page']) ? intval($_GET['isc-page']) : 1;
832 $down_limit = 1; // First page
833
834 $up_limit = 1;
835
836 if ($per_page < $total) {
837 $rem = $total % $per_page; // The Remainder of $total/$per_page
838 $up_limit = ($total - $rem) / $per_page;
839 if (0 < $rem) {
840 $up_limit++; //If rem is positive, add the last page that contains less than $per_page attachment;
841 }
842 }
843
844 ob_start();
845 if ( 2 > $up_limit ) {
846 $this->display_all_attachment_list($connected_atts);
847 } else {
848 $starting_atts = $per_page * ($page - 1); // for page 2 and 3 $per_page start display on $connected_atts[3*(2-1) = 3]
849 $paged_atts = array_slice($connected_atts, $starting_atts, $per_page, true);
850 $this->display_all_attachment_list($paged_atts);
851 $this->pagination_links($up_limit, $before_links, $after_links, $prev_text, $next_text);
852 }
853 if (isset($options['webgilde']) && true == $options['webgilde']) {
854 ?>
855 <p class="isc-backlink"><?php printf(__('Image list created by <a href="%s" title="Image Source Control">Image Source Control Plugin</a>', ISCTEXTDOMAIN), WEBGILDE); ?></p>
856 <?php
857 }
858
859 $output = ob_get_clean();
860 return $output;
861 }
862
863
864 /**
865 * performs rendering of all attachments list
866 * @since 1.1.3
867 */
868 public function display_all_attachment_list($atts)
869 {
870 if (!is_array($atts) || $atts == array())
871 return;
872 $options = $this->get_isc_options();
873 ?>
874 <table>
875 <thead>
876 <?php if ($options['thumbnail_in_list']) : ?>
877 <th><?php _e('Thumbnail', ISCTEXTDOMAIN); ?></th>
878 <?php endif; ?>
879 <th><?php _e("Attachment's ID", ISCTEXTDOMAIN); ?></th>
880 <th><?php _e('Title', ISCTEXTDOMAIN); ?></th>
881 <th><?php _e('Attached to', ISCTEXTDOMAIN); ?></th>
882 <th><?php _e('Source', ISCTEXTDOMAIN); ?></th>
883 </thead>
884 <tbody>
885 <?php foreach ($atts as $id => $data) : ?>
886 <?php
887 $source = $this->_common_texts['not_available'];
888 if ('' != $data['own']) {
889 /** @todo ment for later: this text was used above already; find a place to but it so it is defined only once and used where needed */
890 if ($this->_options['use_authorname']) {
891 $source = $data['author_name'];
892 } else {
893 $source = $this->_options['by_author_text'];
894 }
895 } else {
896 if (!empty($data['source']))
897 $source = $data['source'];
898 }
899 ?>
900 <tr>
901 <?php
902 $v_align = '';
903 if ($options['thumbnail_in_list']) :
904 $v_align = 'style="vertical-align: top;"';
905 ?>
906 <?php if ('custom' != $options['thumbnail_size']) : ?>
907 <td><?php echo wp_get_attachment_image($id, $options['thumbnail_size']); ?></td>
908 <?php else : ?>
909 <td><?php echo wp_get_attachment_image($id, array($options['thumbnail_width'], $options['thumbnail_height'])); ?></td>
910 <?php endif; ?>
911 <?php endif; ?>
912 <td <?php echo $v_align;?>><?php echo $id; ?></td>
913 <td <?php echo $v_align;?>><?php echo $data['title']; ?></td>
914 <td <?php echo $v_align;?>><?php echo $data['posts']; ?></td>
915 <td <?php echo $v_align;?>><?php echo esc_html($source); ?></td>
916 </tr>
917 <?php endforeach; ?>
918 </tbody>
919 </table>
920 <?php
921 }
922
923 /**
924 * Render pagination links, use $before_links and after_links to wrap pagination links inside an additional block
925 * @param int $max_page total page count
926 * @param string $before_links optional html to display before pagination links
927 * @param string $after_links optional html to display after pagination links
928 * @param string $prev_text text for the previous page link
929 * @param string $next_text text for the next page link
930 * @since 1.1.3
931 *
932 */
933 public function pagination_links($max_page, $before_links, $after_links, $prev_text, $next_text)
934 {
935 if ((!isset($max_page)) || (!isset($before_links)) || (!isset($after_links)) || (!isset($prev_text)) || (!isset($next_text)))
936 return;
937 if (!empty($before_links))
938 echo $before_links;
939 ?>
940 <div class="isc-paginated-links">
941 <?php
942 $page = isset($_GET['isc-page']) ? intval($_GET['isc-page']) : 1;
943 if ($max_page < $page) {
944 $page = $max_page;
945 }
946 if ($page < 1) {
947 $page = 1;
948 }
949 $min_page = 1;
950 $backward_distance = $page - $min_page;
951 $forward_distance = $max_page - $page;
952
953 $page_link = get_page_link();
954
955 /**
956 * Remove the query_string of the page_link (?page_id=xyz for the standard permalink structure),
957 * which is already captured in $_SERVER['QUERY_STRING'].
958 * @todo replace regex with other value (does WP store the url path without attributes somewhere?
959 * >get_page_link() returns the permalink but for the default WP permalink structure, the permalink looks like "http://domain.tld/?p=52", while $_GET
960 * still has a field named 'page_id' with the same value of 52.
961 */
962
963 $pos = strpos($page_link, '?');
964 if (false !== $pos) {
965 $page_link = substr($page_link, 0, $pos);
966 }
967
968 /**
969 * Unset the actual "$_GET['isc-page']" variable (if is set). Pagination variable will be appended to the new query string with a different value for each
970 * pagination link.
971 */
972
973 if (isset($_GET['isc-page'])) {
974 unset($_GET['isc-page']);
975 }
976
977 $query_string = http_build_query($_GET);
978
979 $isc_query_tag = '';
980 if (empty($query_string)) {
981 $isc_query_tag = '?isc-page=';
982 } else {
983 $query_string = '?' . $query_string;
984 $isc_query_tag = '&isc-page=';
985 }
986
987 if ($min_page != $page) {
988 ?>
989 <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page-1); ?>" class="prev page-numbers"><?php echo $prev_text; ?></a>
990 <?php
991 }
992
993 if (5 < $max_page) {
994
995 if (3 < $backward_distance) {
996 ?>
997 <a href="<?php echo $page_link . $query_string . $isc_query_tag; ?>1" class="page-numbers">1</a>
998 <span class="page-numbers dots">...</span>
999 <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page-2);?>" class="page-numbers"><?php echo $page-2; ?></a>
1000 <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page-1);?>" class="page-numbers"><?php echo $page-1; ?></a>
1001 <span class="page-numbers current"><?php echo $page; ?></span>
1002 <?php
1003 } else {
1004 for ($i = 1; $i <= $page; $i++) {
1005 if ($i == $page) {
1006 ?>
1007 <span class="page-numbers current"><?php echo $i; ?></span>
1008 <?php
1009 } else {
1010 ?>
1011 <a href="<?php echo $page_link . $query_string . $isc_query_tag . $i;?>" class="page-numbers"><?php echo $i; ?></a>
1012 <?php
1013 }
1014 }
1015 }
1016
1017 if (3 < $forward_distance) {
1018 ?>
1019 <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page+1);?>" class="page-numbers"><?php echo $page+1; ?></a>
1020 <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page+2);?>" class="page-numbers"><?php echo $page+2; ?></a>
1021 <span class="page-numbers dots">...</span>
1022 <a href="<?php echo $page_link . $query_string . $isc_query_tag . $max_page;?>" class="page-numbers"><?php echo $max_page; ?></a>
1023 <?php
1024 } else {
1025 for ($i = $page+1; $i <= $max_page; $i++) {
1026 ?>
1027 <a href="<?php echo $page_link . $query_string . $isc_query_tag . $i;?>" class="page-numbers"><?php echo $i; ?></a>
1028 <?php
1029 }
1030 }
1031 } else {
1032 for ($i = 1; $i <= $max_page; $i++) {
1033 if ($i == $page) {
1034 ?>
1035 <span class="page-numbers current"><?php echo $i; ?></span>
1036 <?php
1037 } else {
1038 ?>
1039 <a href="<?php echo $page_link . $query_string . $isc_query_tag . $i;?>" class="page-numbers"><?php echo $i; ?></a>
1040 <?php
1041 }
1042 }
1043 }
1044 if ($page != $max_page) {
1045 ?>
1046 <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page+1);?>" class="next page-numbers"><?php echo $next_text; ?></a>
1047 <?php
1048 }
1049 ?>
1050 </div>
1051 <?php
1052 echo $after_links;
1053 }
1054
1055 /**
1056 * The activation function
1057 */
1058 public function activation()
1059 {
1060 if (!is_array(get_option('isc_options'))) {
1061 update_option( 'isc_options', $this->default_options() );
1062 }
1063 $options = $this->get_isc_options();
1064 if (!$options['installed']) {
1065 /**
1066 * Here, all jobs to perform during first activation, especially options and custom fields.
1067 * Important: NO add_action('something', 'somefunction') here.
1068 */
1069
1070 // adds meta fields for attachments
1071 $this->add_meta_values_to_attachments();
1072
1073 // set all isc_image_posts meta fields.
1074 $this->init_image_posts_metafield();
1075
1076 $options['installed'] = true;
1077 update_option('isc_options', $options);
1078 }
1079 }
1080
1081 /**
1082 * Returns default options
1083 */
1084 public function default_options()
1085 {
1086 $default['image_list_headline'] = __('image sources', ISCTEXTDOMAIN);
1087 $default['use_authorname'] = true;
1088 $default['by_author_text'] = __('Owned by the author', ISCTEXTDOMAIN);
1089 $default['installed'] = false;
1090 $default['version'] = ISCVERSION;
1091 $default['webgilde'] = false;
1092 $default['thumbnail_in_list'] = false;
1093 $default['thumbnail_size'] = 'thumbnail';
1094 $default['thumbnail_width'] = 150;
1095 $default['thumbnail_height'] = 150;
1096 $default['warning_nosource'] = true;
1097 $default['warning_onesource_missing'] = true;
1098 $default['hide_list'] = false;
1099 $default['caption_position'] = 'top-left';
1100 $default['source_on_image'] = false;
1101 $default['source_pretext'] = __('Source:', ISCTEXTDOMAIN);
1102 return $default;
1103 }
1104
1105 /**
1106 * Settings API initialization
1107 */
1108 public function SAPI_init()
1109 {
1110 $this->upgrade_management();
1111 register_setting('isc_options_group', 'isc_options', array($this, 'settings_validation'));
1112 add_settings_section('isc_settings_section', '', '__return_false', 'isc_settings_page');
1113
1114 // Starts Page/Post settings group
1115 add_settings_field('image_list_headline', __('Image list headline', ISCTEXTDOMAIN), array($this, 'renderfield_list_headline'), 'isc_settings_page', 'isc_settings_section');
1116 /**
1117 * All new setting in Page/Post group Here!
1118 */
1119 add_settings_field('hide_list', __('Hide the image list', ISCTEXTDOMAIN), array($this, 'renderfield_hide_list'), 'isc_settings_page', 'isc_settings_section');
1120 // Ends Page/Post settings group
1121
1122 // Starts Full images list group
1123 add_settings_field('use_thumbnail', __("Use thumbnails in images list", ISCTEXTDOMAIN), array($this, 'renderfield_use_thumbnail'), 'isc_settings_page', 'isc_settings_section');
1124 /**
1125 * All new setting in Full images list group Here!
1126 */
1127 add_settings_field('thumbnail_width', __("Thumbnails max-width", ISCTEXTDOMAIN), array($this, 'renderfield_thumbnail_width'), 'isc_settings_page', 'isc_settings_section');
1128 add_settings_field('thumbnail_height', __("Thumbnails max-height", ISCTEXTDOMAIN), array($this, 'renderfield_thumbnail_height'), 'isc_settings_page', 'isc_settings_section');
1129 // Ends Full images list group
1130
1131 // Starts Misc settings group
1132 add_settings_field('use_authorname', __('Use authors names', ISCTEXTDOMAIN), array($this, 'renderfield_use_authorname'), 'isc_settings_page', 'isc_settings_section');
1133 add_settings_field('by_author_text', __('Custom text for owned images', ISCTEXTDOMAIN), array($this, 'renderfield_byauthor_text'), 'isc_settings_page', 'isc_settings_section');
1134 add_settings_field('webgilde_backlink', __("Link to webgilde's website", ISCTEXTDOMAIN), array($this, 'renderfield_webgile'), 'isc_settings_page', 'isc_settings_section');
1135 /**
1136 * All new setting in Misc settings group Here!
1137 */
1138 add_settings_field('source_caption', __("Source as caption on image", ISCTEXTDOMAIN), array($this, 'renderfield_source_caption'), 'isc_settings_page', 'isc_settings_section');
1139 add_settings_field('caption_position', __("Caption position", ISCTEXTDOMAIN), array($this, 'renderfield_caption_pos'), 'isc_settings_page', 'isc_settings_section');
1140 add_settings_field('warning_one_source', __("Warning when there is at least one missing source", ISCTEXTDOMAIN), array($this, 'renderfield_warning_onesource_misisng'), 'isc_settings_page', 'isc_settings_section');
1141 add_settings_field('warning_nosource', __("Warnings when source not available", ISCTEXTDOMAIN), array($this, 'renderfield_warning_nosource'), 'isc_settings_page', 'isc_settings_section');
1142 // Ends Misc settings group
1143 }
1144
1145 /**
1146 * manage data structure upgrading of outdated versions
1147 */
1148 public function upgrade_management() {
1149
1150 /*
1151 * Since the activation hook is not executed on plugin upgrade, this function checks options in database
1152 * during the admin_init hook to handle plugin's upgrade.
1153 */
1154
1155 $options = get_option('isc_options');
1156
1157 if (!is_array($options)) {
1158 // special case for version prior to 1.2 (which don't have options)
1159 $options = $this->default_options();
1160 $this->init_image_posts_metafield();
1161 $options['installed'] = true;
1162 update_option('isc_options', $options);
1163 }
1164
1165 if (ISCVERSION != $options['version']) {
1166 $options = $options + $this->default_options();
1167 $options['version'] = ISCVERSION;
1168 update_option('isc_options', $options);
1169 }
1170 }
1171
1172 /**
1173 * Image_control's page callback
1174 */
1175 public function render_isc_settings_page()
1176 {
1177 ?>
1178 <div id="icon-options-general" class="icon32"><br></div>
1179 <h2><?php _e('Images control settings', ISCTEXTDOMAIN); ?></h2>
1180 <div id="isc-admin-wrap">
1181 <form id="image-control-form" method="post" action="options.php">
1182 <div class="postbox isc-setting-group"><?php // Open the div for the first settings group ?>
1183 <h3 class="setting-group-head"><?php _e('Post / Page images list', ISCTEXTDOMAIN); ?></h3>
1184 <?php
1185 settings_fields( 'isc_options_group' );
1186 do_settings_sections( 'isc_settings_page' );
1187 ?>
1188 </div><?php //Close the last settings group div ?>
1189 <p class="submit">
1190 <input type="submit" name="submit" id="submit" class="button button-primary" value="Save Changes">
1191 </p>
1192 </form>
1193 </div><!-- #isc-admin-wrap -->
1194 <?php
1195 }
1196
1197 /**
1198 * image_list field callbacks
1199 */
1200 public function renderfield_list_headline()
1201 {
1202 $options = $this->get_isc_options();
1203 $description = __('The headline of the image list added via shortcode or function in your theme.', ISCTEXTDOMAIN);
1204 ?>
1205 <div id="image-list-headline-block">
1206 <label for="list-head"><?php __('Image list headline', ISCTEXTDOMAIN); ?></label>
1207 <input type="text" name="isc_options[image_list_headline_field]" id="list-head" value="<?php echo $options['image_list_headline'] ?>" class="regular-text" />
1208 <p><em><?php echo $description; ?></em></p>
1209 </div>
1210 <?php
1211 }
1212
1213 public function renderfield_hide_list()
1214 {
1215 $options = $this->get_isc_options();
1216 $description = __("Hide the list when the post is loaded. A simple click on the list headline will show the list content.", ISCTEXTDOMAIN);
1217 ?>
1218 <div id="hide-list-block">
1219 <label for="hide-list"><?php _e('Hide the image list of a post', ISCTEXTDOMAIN) ?></label>
1220 <input type="checkbox" name="isc_options[hide_list]" id="hide-list" <?php checked($options['hide_list']); ?> />
1221 <p><em><?php echo $description; ?></em></p>
1222 </div>
1223 </td></tr></tbody></table>
1224 </div><!-- .postbox -->
1225 <div class="postbox isc-setting-group">
1226 <h3 class="setting-group-head"><?php _e('Full images list', ISCTEXTDOMAIN) ?></h3>
1227 <table class="form-table"><tbody><tr><td>
1228 <?php
1229 }
1230
1231 public function renderfield_use_authorname()
1232 {
1233 $options = $this->get_isc_options();
1234 $description = __("Display the author's public name as source when the image is owned by the author (the uploader of the image, not necessarily the author of the post the image is displayed on). Uncheck to use a custom text instead.", ISCTEXTDOMAIN);
1235
1236 ?>
1237 <div id="use-authorname-block">
1238 <label for="use_authorname"><?php _e('Use author name', ISCTEXTDOMAIN) ?></label>
1239 <input type="checkbox" name="isc_options[use_authorname_ckbox]" id="use_authorname" <?php checked($options['use_authorname']); ?> />
1240 <p><em><?php echo $description; ?></em></p>
1241 </div>
1242 <?php
1243 }
1244
1245 public function renderfield_byauthor_text()
1246 {
1247 $options = $this->get_isc_options();
1248 $description = __("Enter the custom text to display if you do not want to use the author's public name.", ISCTEXTDOMAIN);
1249 ?>
1250 <div id="by-author-text">
1251 <input type="text" id="byauthor" name="isc_options[by_author_text_field]" value="<?php echo $options['by_author_text']; ?>" <?php disabled($options['use_authorname']); ?> class="regular-text" />
1252 <p><em><?php echo $description; ?></em></p>
1253 </div>
1254 <?php
1255 }
1256
1257 public function renderfield_webgile()
1258 {
1259 $options = $this->get_isc_options();
1260 $description = sprintf(__('Display a link to <a href="%s">Image Source Control plugin&#39;s website</a> below the list of all images in the blog?', ISCTEXTDOMAIN), WEBGILDE);
1261 ?>
1262 <div id="webgilde-block">
1263 <input type="checkbox" id="webgilde-link" name="isc_options[webgilde_field]" <?php checked($options['webgilde']); ?> />
1264 <p><em><?php echo $description; ?></em></p>
1265 </div>
1266 <?php
1267 }
1268
1269 public function renderfield_use_thumbnail()
1270 {
1271 $options = $this->get_isc_options();
1272 $description = __('Display thumbnails on the list of all images in the blog.' ,ISCTEXTDOMAIN);
1273 ?>
1274 <div id="use-thumbnail-block">
1275 <input type="checkbox" id="use-thumbnail" name="isc_options[use_thumbnail]" value="1" <?php checked($options['thumbnail_in_list']); ?> />
1276 <select id="thumbnail-size-select" name="isc_options[size_select]" <?php disabled(!$options['thumbnail_in_list']) ?>>
1277 <?php foreach ($this->_thumbnail_size as $size) : ?>
1278 <option value="<?php echo $size; ?>" <?php selected($size, $options['thumbnail_size']);?>><?php echo $size; ?></option>
1279 <?php endforeach; ?>
1280 </select>
1281 <p><em><?php echo $description; ?></em></p>
1282 </div>
1283 <?php
1284 }
1285
1286 public function renderfield_thumbnail_width()
1287 {
1288 $options = $this->get_isc_options();
1289 $description = __('Custom value of the maximum allowed width for thumbnail.' ,ISCTEXTDOMAIN);
1290 ?>
1291 <div id="thumbnail-custom-width">
1292 <input type="text" id="custom-width" name="isc_options[thumbnail_width]" class="small-text" value="<?php echo $options['thumbnail_width'] ?>" /> px
1293 <p><em><?php echo $description; ?></em></p>
1294 </div>
1295 <?php
1296 }
1297
1298 public function renderfield_thumbnail_height()
1299 {
1300 $options = $this->get_isc_options();
1301 $description = __('Custom value of the maximum allowed height for thumbnail.' ,ISCTEXTDOMAIN);
1302 ?>
1303 <div id="thumbnail-custom-height">
1304 <input type="text" id="custom-height" name="isc_options[thumbnail_height]" class="small-text" value="<?php echo $options['thumbnail_height'] ?>"/> px
1305 <p><em><?php echo $description; ?></em></p>
1306 </div>
1307 </td></tr></tbody></table>
1308 </div><!-- .postbox -->
1309 <div class="postbox isc-setting-group">
1310 <h3 class="setting-group-head"><?php _e('Miscellaneous settings', ISCTEXTDOMAIN); ?></h3>
1311 <table class="form-table"><tbody><tr><td>
1312 <?php
1313 }
1314
1315 public function renderfield_warning_nosource()
1316 {
1317 $options = $this->get_isc_options();
1318 $description = __('Warn and prevent data to be saved when an attachment is edited and the source has not been specified.' ,ISCTEXTDOMAIN);
1319 ?>
1320 <div id="no-source-block">
1321 <input type="checkbox" id="no-source" name="isc_options[no_source]"value="1" <?php checked($options['warning_nosource']); ?>/>
1322 <p><em><?php echo $description; ?></em></p>
1323 </div>
1324 <?php
1325 }
1326
1327 public function renderfield_warning_onesource_misisng()
1328 {
1329 $options = $this->get_isc_options();
1330 $description = __('Display an admin notice in admin pages when one or more image sources are missing.' ,ISCTEXTDOMAIN);
1331 ?>
1332 <div id="one-source-block">
1333 <input type="checkbox" id="one-source" name="isc_options[one_source]"value="1" <?php checked($options['warning_onesource_missing']); ?>/>
1334 <p><em><?php echo $description; ?></em></p>
1335 </div>
1336 <?php
1337 }
1338
1339 public function renderfield_caption_pos()
1340 {
1341 $options = $this->get_isc_options();
1342 $description = __('Position of captions into images' ,ISCTEXTDOMAIN);
1343 ?>
1344 <div id="caption-position-block">
1345 <select id="caption-pos" name="isc_options[cap_pos]">
1346 <?php foreach ($this->_caption_position as $pos) : ?>
1347 <option value="<?php echo $pos; ?>" <?php selected($pos, $options['caption_position']); ?>><?php echo $pos; ?></option>
1348 <?php endforeach; ?>
1349 </select>
1350 <p><em><?php echo $description; ?></em></p>
1351 </div>
1352 <?php
1353 }
1354
1355 public function renderfield_source_caption()
1356 {
1357 $options = $this->get_isc_options();
1358 $description_checkbox = __('Tick to display source onto each image.' ,ISCTEXTDOMAIN);
1359 $description_textfield = __('The text preceding the source on each image.' ,ISCTEXTDOMAIN);
1360 ?>
1361 <div id="caption-block">
1362 <input type="checkbox" id="source-on-image" value="1" name="isc_options[source_on_image]" <?php checked($options['source_on_image']); ?> />
1363 <p><em><?php echo $description_checkbox; ?></em></p>
1364 <input type="text" id='source-pretext' name="isc_options[source_pretext]" value="<?php echo $options['source_pretext']; ?>" />
1365 <p><em><?php echo $description_textfield; ?></em></p>
1366 </div>
1367 <?php
1368 }
1369
1370 /**
1371 * Returns isc_options if it exists, returns the default options otherwise.
1372 */
1373 public function get_isc_options() {
1374 return get_option('isc_options', $this->default_options());
1375 }
1376
1377 /*
1378 * Input validation function.
1379 * @param array $input values from the admin panel
1380 */
1381 public function settings_validation($input)
1382 {
1383 $output = $this->get_isc_options();
1384 $output['image_list_headline'] = esc_html($input['image_list_headline_field']);
1385 if (isset($input['use_authorname_ckbox'])) {
1386 // Don't worry about the custom text if the author name is selected.
1387 $output['use_authorname'] = true;
1388 } else {
1389 $output['use_authorname'] = false;
1390 $output['by_author_text'] = esc_html($input['by_author_text_field']);
1391 }
1392 if (isset($input['webgilde_field'])) {
1393 $output['webgilde'] = true;
1394 } else {
1395 $output['webgilde'] = false;
1396 }
1397 if (isset($input['use_thumbnail'])) {
1398 $output['thumbnail_in_list'] = true;
1399 if (in_array($input['size_select'], $this->_thumbnail_size)) {
1400 $output['thumbnail_size'] = $input['size_select'];
1401 }
1402 if ('custom' == $input['size_select']) {
1403 if (is_numeric($input['thumbnail_width'])) {
1404 // Ensures that the value stored in database in a positive integer.
1405 $output['thumbnail_width'] = abs(intval(round($input['thumbnail_width'])));
1406 }
1407 if (is_numeric($input['thumbnail_height'])) {
1408 $output['thumbnail_height'] = abs(intval(round($input['thumbnail_height'])));
1409 }
1410 }
1411 } else {
1412 $output['thumbnail_in_list'] = false;
1413 }
1414 if (isset($input['no_source'])) {
1415 $output['warning_nosource'] = true;
1416 } else {
1417 $output['warning_nosource'] = false;
1418 }
1419 if (isset($input['one_source'])) {
1420 $output['warning_onesource_missing'] = true;
1421 } else {
1422 $output['warning_onesource_missing'] = false;
1423 }
1424 if (isset($input['hide_list'])){
1425 $output['hide_list'] = true;
1426 } else {
1427 $output['hide_list'] = false;
1428 }
1429 if (in_array($input['cap_pos'], $this->_caption_position))
1430 $output['caption_position'] = $input['cap_pos'];
1431 if (isset($input['source_on_image'])) {
1432 $output['source_on_image'] = true;
1433 $output['source_pretext'] = $input['source_pretext'];
1434 } else {
1435 $output['source_on_image'] = false;
1436 }
1437 return $output;
1438 }
1439
1440 /**
1441 * Adds isc_image_posts on all attachments. Launched during first installation.
1442 */
1443 public function init_image_posts_metafield()
1444 {
1445 $args = array(
1446 'post_type' => 'any',
1447 'numberposts' => -1,
1448 'post_status' => null,
1449 'post_parent' => null,
1450 );
1451 $posts = get_posts($args);
1452 foreach ($posts as $post) {
1453 setup_postdata($post);
1454 $image_urls = $this->_filter_src_attributes($post->post_content);
1455 $image_ids = array();
1456 foreach ($image_urls as $url) {
1457 $image_id = intval($this->get_image_by_url($url));
1458 array_push($image_ids,$image_id);
1459 }
1460 foreach ($image_ids as $id) {
1461 $meta = get_post_meta($id, 'isc_image_posts', true);
1462 if (empty($meta)) {
1463 update_post_meta($id, 'isc_image_posts', array($post->ID));
1464 } else {
1465 if (!in_array($post->ID, $meta)) {
1466 array_push($meta, $post->ID);
1467 update_post_meta($id, 'isc_image_posts', $meta);
1468 }
1469 }
1470 }
1471 }
1472 }
1473
1474 /**
1475 *
1476 */
1477 public function admin_notices()
1478 {
1479 $args = array(
1480 'post_type' => 'attachment',
1481 'numberposts' => -1,
1482 'post_status' => null,
1483 'post_parent' => null,
1484 'meta_query' => array(
1485 array(
1486 'key' => 'isc_image_source',
1487 'value' => '',
1488 'compare' => '='
1489 ),
1490 array(
1491 'key' => 'isc_image_source_own',
1492 'value' => '',
1493 'compare' => ''
1494 )
1495 )
1496 );
1497 $attachments = get_posts($args);
1498 $options = $this->get_isc_options();
1499 if (!empty($attachments) && $options['warning_onesource_missing'] ) {
1500 $missing_src = esc_url(admin_url('upload.php?page=image-source-control-isc/templates/missing_sources.php'));
1501 ?>
1502 <div class="updated"><p><?php printf(__('One or more attachments still have no source. See the <a href="%s">missing sources</a> list', ISCTEXTDOMAIN), $missing_src);?></p></div>
1503 <?php
1504 }
1505 }
1506
1507 }// end of class
1508
1509 $inc_path = ABSPATH . 'wp-includes/';
1510 /**
1511 * "pluggable.php" is not defined at this point. Not sure about the reason.
1512 */
1513 require_once($inc_path . 'pluggable.php');
1514
1515 /**
1516 * Need an instance of ISC_CLASS when the register_activation_hook is called (earlier than the "plugins_loaded" hook).
1517 */
1518 global $my_isc;
1519 $my_isc = new ISC_CLASS();
1520
1521 /**
1522 * the next functions are just to have an easier access from outside the class
1523 */
1524 function isc_list($post_id = 0) {
1525 $isc = new ISC_CLASS();
1526 echo $isc->list_post_attachments_with_sources($post_id);
1527 }
1528 }
1529