PluginProbe
Image Source Control Lite – Show Image Credits and Captions / 1.2
Image Source Control Lite – Show Image Credits and Captions v1.2
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 +1235 -45 trunk1.2 View file →
@@ -1,58 +1,1248 @@
1 1 <?php
2 -/**
3 - * Plugin Name: Image Source Control Lite
4 - * Version: 3.12.0
5 - * Plugin URI: https://imagesourcecontrol.com/
6 - * Description: Image Source Control saves the source of an image, lists them and warns if it is missing.
7 - * Author: Thomas Maier
8 - * Author URI: https://imagesourcecontrol.com/
9 - * License: GPL v3
2 +/*
3 + Plugin Name: Image Source Control
4 + Version: 1.2
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/>.
10 26 *
11 - * Image Source Control Plugin for WordPress
12 - * Copyright (C) 2012-2026, Thomas Maier & webgilde GmbH
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)
13 30 *
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 31 *
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 32 */
27 33
28 -if ( defined( 'ISCVERSION' ) ) {
29 - wp_die( 'You can only activate Image Source Control once. Please disable the other version first.' );
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();
30 39 }
31 40
32 -define( 'ISCVERSION', '3.12.0' );
33 -define( 'ISCNAME', 'Image Source Control' );
34 -define( 'ISCDIR', basename( __DIR__ ) );
35 -define( 'ISCPATH', plugin_dir_path( __FILE__ ) );
36 -define( 'ISCBASE', plugin_basename( __FILE__ ) ); // plugin base as used by WordPress to identify it.
37 -define( 'ISCBASEURL', plugin_dir_url( __FILE__ ) ); // URL to the plugin directory.
41 +define('ISCVERSION', '1.2');
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');
38 47
39 -// Load the autoloader.
40 -require_once ISCPATH . 'includes/class-autoloader.php';
41 -\ISC\Autoloader::get()->initialize();
48 +load_plugin_textdomain(ISCTEXTDOMAIN, false, dirname(plugin_basename(__FILE__)) . '/languages/');
42 49
43 -if ( is_admin() ) {
44 - new ISC\Admin();
45 -} elseif ( ! is_admin() && ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX ) ) {
46 - // include frontend functions.
47 - new ISC_Public();
48 - require_once ISCPATH . 'includes/functions.php';
49 -}
50 +if (!class_exists('ISC_CLASS')) {
50 51
51 -// deprecated. Added here for backward compatibility. Will be removed in future versions.
52 -new ISC_Class();
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 + );
53 71
54 -if ( ! class_exists( 'ISC_Pro_Model', false ) && file_exists( ISCPATH . 'pro/isc-pro.php' ) ) {
55 - require_once ISCPATH . 'pro/isc-pro.php';
72 + /**
73 + * allowed image file types/extensions
74 + * @since 1.1
75 + */
76 + protected $_allowedExtensions = array(
77 + 'jpg', 'png', 'gif'
78 + );
79 +
80 + protected $_upgrade_step = array(
81 + '1.2'
82 + );
83 +
84 + /**
85 + * Thumbnail size in list of all images.
86 + */
87 + protected $_thumbnail_size = array('thumbnail', 'medium', 'large', 'custom');
88 +
89 + /**
90 + * options saved in the db
91 + * @since 1.2
92 + */
93 + protected $_options = array();
94 +
95 + /**
96 + * Setup registers filterts and actions.
97 + */
98 + public function __construct()
99 + {
100 +
101 + // load all plugin options
102 + $this->_options = get_option('isc_options');
103 +
104 + // insert all function for the frontend here
105 +
106 + add_shortcode('isc_list', array($this, 'list_post_attachments_with_sources_shortcode'));
107 + add_shortcode('isc_list_all', array($this, 'list_all_post_attachments_sources_shortcode'));
108 +
109 + // insert all backend functions below this check
110 + if (!current_user_can('upload_files')) {
111 + return false;
112 + }
113 +
114 + register_activation_hook(ISCPATH . '/isc.php', array($this, 'activation'));
115 +
116 + add_filter('attachment_fields_to_edit', array($this, 'add_isc_fields'), 10, 2);
117 + add_filter('attachment_fields_to_save', array($this, 'isc_fields_save'), 10, 2);
118 +
119 + add_action('admin_menu', array($this, 'create_menu'));
120 + add_action('admin_init', array($this, 'SAPI_init'));
121 +
122 + add_action('admin_enqueue_scripts', array($this, 'add_admin_scripts'));
123 +
124 + // ajax function; 'add_meta_fields' is the action defined in isc.js as the action to be called via ajax
125 + add_action('wp_ajax_add_meta_fields', array($this, 'add_meta_values_to_attachments'));
126 +
127 + // save image information in meta field when a post is saved
128 + add_action('save_post', array($this, 'save_image_information_on_post_save'));
129 + }
130 +
131 + /**
132 + * create the menu pages for isc
133 + */
134 + public function create_menu()
135 + {
136 + global $isc_missing;
137 + global $isc_setting;
138 +
139 + /**
140 + * Check if the page is already created.
141 + */
142 + if (empty($isc_missing)) {
143 + // these pages should be accessible by editors and higher
144 + $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', '');
145 + $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'));
146 + }
147 + }
148 +
149 + /**
150 + * add scripts to admin pages
151 + * @since 1.0
152 + * @update 1.1.1
153 + */
154 + public function add_admin_scripts($hook)
155 + {
156 + global $isc_setting;
157 + if ($hook != $isc_setting) {
158 + return;
159 + }
160 + wp_enqueue_script('isc_script', plugins_url('/js/isc.js', __FILE__), false, ISCVERSION);
161 + // this is to define ajaxurl to be able to use this in its own js script
162 + // wp_localize_script( 'isc_script', 'IscAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
163 + }
164 +
165 + /**
166 + * add custom field to attachment
167 + * @param arr $form_fields
168 + * @param object $post
169 + * @return arr
170 + * @since 1.0
171 + * @updated 1.1
172 + */
173 + public function add_isc_fields($form_fields, $post)
174 + {
175 + // add input field for source
176 + $form_fields['isc_image_source']['label'] = __('Image Source', ISCTEXTDOMAIN);
177 + $form_fields['isc_image_source']['value'] = get_post_meta($post->ID, 'isc_image_source', true);
178 + $form_fields['isc_image_source']['helps'] = __('Include the image source here.', ISCTEXTDOMAIN);
179 +
180 + // add checkbox to mark as your own image
181 + $form_fields['isc_image_source_own']['input'] = 'html';
182 + $form_fields['isc_image_source_own']['label'] = '';
183 + $form_fields['isc_image_source_own']['helps'] =
184 + __('Check this box if this is your own image and doesn\'t need a source.', ISCTEXTDOMAIN);
185 + $form_fields['isc_image_source_own']['html'] =
186 + "<input type='checkbox' value='1' name='attachments[{$post->ID}][isc_image_source_own]' id='attachments[{$post->ID}][isc_image_source_own]' "
187 + . checked(get_post_meta($post->ID, 'isc_image_source_own', true), 1, false )
188 + . " style=\"width:14px\"/> "
189 + . __('This is my image', ISCTEXTDOMAIN);
190 +
191 + return $form_fields;
192 + }
193 +
194 + /**
195 + * save image source to post_meta
196 + * @param object $post
197 + * @param $attachment
198 + * @return object $post
199 + */
200 + public function isc_fields_save($post, $attachment)
201 + {
202 + if (isset($attachment['isc_image_source'])) {
203 + update_post_meta($post['ID'], 'isc_image_source', $attachment['isc_image_source']);
204 + }
205 +
206 + update_post_meta($post['ID'], 'isc_image_source_own', $attachment['isc_image_source_own']);
207 + return $post;
208 + }
209 +
210 + /**
211 + * create image sources list for all images of this post
212 + * @since 1.0
213 + * @update 1.1
214 + * @param int $post_id id of the current post/page
215 + * @return echo output
216 + */
217 + public function list_post_attachments_with_sources($post_id = 0)
218 + {
219 + global $post;
220 +
221 + if (empty($post_id)) {
222 + if (!empty($post->ID)) {
223 + $post_id = $post->ID;
224 + } else {
225 + return;
226 + }
227 + }
228 +
229 + $attachments = get_post_meta($post_id, 'isc_post_images', true);
230 + // if attachments is an empty string, search for images in it
231 + if ($attachments == '') {
232 + $this->save_image_information_on_load();
233 + $this->update_image_posts_meta($post_id, $post->post_content);
234 +
235 + $attachments = get_post_meta($post_id, 'isc_post_images', true);
236 + }
237 +
238 + $authorname = '';
239 + if (!empty($post->post_author))
240 + $authorname = get_the_author_meta('display_name', $post->post_author);
241 +
242 + $return = '';
243 + if (!empty($attachments)) {
244 + $atts = array();
245 + foreach ($attachments as $attachment_id => $attachment_array) {
246 + $atts[$attachment_id]['title'] = get_the_title($attachment_id);
247 + $own = get_post_meta($attachment_id, 'isc_image_source_own', true);
248 + $source = get_post_meta($attachment_id, 'isc_image_source', true);
249 +
250 + if ( $own == '' && $source == '' ) {
251 + // remove if no information set
252 + unset($atts[$attachment_id]);
253 + continue;
254 + } elseif ($own != '') {
255 + if ($this->_options['use_authorname'] && !empty($authorname)) {
256 + $atts[$attachment_id ]['source'] = $authorname;
257 + } else {
258 + $atts[$attachment_id ]['source'] = $this->_options['by_author_text'];
259 + }
260 + } else {
261 + $atts[$attachment_id ]['source'] = $source;
262 + }
263 + }
264 +
265 + $return = $this->_renderAttachments($atts);
266 + }
267 +
268 + return $return;
269 + }
270 +
271 + /**
272 + * @param array $attachments
273 + */
274 + protected function _renderAttachments($attachments)
275 + {
276 + // don't display anything, if no image sources displayed
277 + if ($attachments == array()) {
278 + return ;
279 + }
280 + ob_start();
281 +
282 + $headline = $this->_options['image_list_headline'];
283 + printf('<p class="isc_image_list_title">%s</p>', $headline); ?>
284 + <ul class="isc_image_list"><?php
285 +
286 + foreach ($attachments as $atts_id => $atts_array) {
287 + if (empty($atts_array['source'])) {
288 + continue;
289 + }
290 + printf('<li>%1$s: %2$s</li>', $atts_array['title'], $atts_array['source']);
291 + }
292 + ?></ul><?php
293 + return ob_get_clean();
294 + }
295 +
296 + /**
297 + * shortcode function to list all image sources
298 + * @param arr $atts
299 + */
300 + public function list_post_attachments_with_sources_shortcode($atts = array())
301 + {
302 + global $post;
303 + extract(shortcode_atts(array('id' => 0), $atts));
304 +
305 + // if $id not set, use the current ID from the post
306 + if (empty($id)) {
307 + $id = $post->ID;
308 + }
309 +
310 + if (empty($id)) {
311 + return;
312 + }
313 + return $this->list_post_attachments_with_sources($id);
314 + }
315 +
316 + /**
317 + * get all attachments without sources
318 + * the downside of this function: is there is not even an empty metakey field, nothing is going to be retrieved
319 + * @todo fix this in WP 3.5 with compare => 'NOT EXISTS'
320 + */
321 + public function get_attachments_without_sources()
322 + {
323 + $args = array(
324 + 'post_type' => 'attachment',
325 + 'numberposts' => -1,
326 + 'post_status' => null,
327 + 'post_parent' => null,
328 + 'meta_query' => array(
329 + // image source is empty
330 + array(
331 + 'key' => 'isc_image_source',
332 + 'value' => '',
333 + 'compare' => '=',
334 + ),
335 + // and image source is not set
336 + array(
337 + 'key' => 'isc_image_source_own',
338 + 'value' => '1',
339 + 'compare' => '!=',
340 + ),
341 + )
342 + );
343 +
344 + $attachments = get_posts($args);
345 + if (!empty($attachments)) {
346 + return $attachments;
347 + }
348 + }
349 +
350 + /**
351 + * add meta values to all attachments
352 + * @todo probably need to fix this when more fields are added along the way
353 + * @todo use compare => 'NOT EXISTS' when WP 3.5 is up to retrieve only values where it is not set
354 + * @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
355 + */
356 + public function add_meta_values_to_attachments()
357 + {
358 + // retrieve all attachments
359 + $args = array(
360 + 'post_type' => 'attachment',
361 + 'numberposts' => -1,
362 + 'post_status' => null,
363 + 'post_parent' => null,
364 + );
365 +
366 + $attachments = get_posts($args);
367 + if (empty($attachments)) {
368 + return;
369 + }
370 +
371 + $count = 0;
372 + foreach ($attachments as $_attachment) {
373 + $set = false;
374 + setup_postdata($_attachment);
375 + foreach ($this->_fields as $_field) {
376 + $meta = get_post_meta($_attachment->ID, $_field['id'], true);
377 + if (empty($meta)) {
378 + update_post_meta($_attachment->ID, $_field['id'], $_field['default']);
379 + $set = true;
380 + }
381 + }
382 + if ($set) {
383 + $count++;
384 + }
385 + }
386 + }
387 +
388 + /**
389 + * show the loading image from wp-admin/images/loading.gif
390 + * @param bool $display should this be displayed directly or hidden? via inline css
391 + */
392 + public function show_loading_image($display = true)
393 + {
394 + $img_path = admin_url("/images/loading.gif");
395 + $file_path = ABSPATH . "wp-admin/images/loading.gif";
396 + if (file_exists($file_path)) {
397 + echo '<span id="isc_loading_img" style="display: none;"><img src="' . $img_path . '" width="16" height="16" alt="loading"/></span>';
398 + }
399 + }
400 +
401 + /**
402 + * this is an entry function to save image information to a post when it is saved
403 + * @since 1.1
404 + * @param type $post_id
405 + */
406 + public function save_image_information_on_post_save($post_id)
407 + {
408 + // return, if save_post is called more than one time
409 + if (did_action('save_post') !== 1) {
410 + return;
411 + }
412 +
413 + if (isset($_POST['post_type']) && 'attachment' == $_POST['post_type']) {
414 + return;
415 + }
416 +
417 + // check if this is a revision and if so, use parent post id
418 + if ($_id = wp_is_post_revision($post_id)) {
419 + $post_id = $_id;
420 + }
421 +
422 + $_content = '';
423 + if ( !empty( $_REQUEST['content']) ) $_content = stripslashes($_REQUEST['content']);
424 +
425 + // Needs to be called before the 'isc_post_images' field is updated.
426 + $this->update_image_posts_meta($post_id, $_content);
427 +
428 + $this->save_image_information($post_id, $_content);
429 + }
430 +
431 + /**
432 + * save image information for a post when it is viewed and the image source list is enabled
433 + * (this is in case the plugin is new and the current post wasn't saved before)
434 + *
435 + * @since 1.1
436 + */
437 + public function save_image_information_on_load()
438 + {
439 + global $post;
440 + if (empty($post->ID)) {
441 + return;
442 + }
443 +
444 + $post_id = $post->ID;
445 + $_content = $post->post_content;
446 +
447 + $this->save_image_information($post_id, $_content);
448 + }
449 +
450 + /**
451 + * retrieve images added to a post or page and save all information as a meta value
452 + * @since 1.1
453 + * @todo check for more post types that maybe should not be parsed here
454 + */
455 + public function save_image_information($post_id, $_content)
456 + {
457 + $_image_urls = $this->_filter_src_attributes($_content);
458 + $_imgs = array();
459 +
460 + foreach ($_image_urls as $_image_url) {
461 + // get ID of images by url
462 + $img_id = $this->get_image_by_url($_image_url);
463 + $_imgs[$img_id] = array(
464 + 'src' => $_image_url
465 + );
466 + }
467 +
468 + // add thumbnail information
469 + $thumb_id = get_post_thumbnail_id($post_id);
470 +
471 + /**
472 + * if an image is used both inside the post and as post thumbnail, the thumbnail entry overrides the regular image.
473 + */
474 + if ( !empty( $thumb_id )) {
475 + $_imgs[$thumb_id] = array(
476 + 'src' => wp_get_attachment_url($thumb_id),
477 + 'thumbnail' => true
478 + );
479 + }
480 +
481 + if (empty($_imgs)) {
482 + $_imgs = false;
483 + }
484 + update_post_meta($post_id, 'isc_post_images', $_imgs);
485 + }
486 +
487 + /**
488 + * filter image src attribute from text
489 + * @since 1.1
490 + * @updated 1.1.3
491 + * @return array with image src uris
492 + */
493 + public function _filter_src_attributes($content = '')
494 + {
495 + $srcs = array();
496 + if (empty($content))
497 + return $srcs;
498 +
499 + // parse HTML with DOM
500 + $dom = new DOMDocument;
501 +
502 + libxml_use_internal_errors(true);
503 + $dom->loadHTML($content);
504 +
505 + // Prevents from sending E_WARNINGs notice (Outputs are forbidden during activation)
506 + libxml_clear_errors();
507 +
508 + foreach ($dom->getElementsByTagName('img') as $node) {
509 + $srcs[] = $node->getAttribute('src');
510 + }
511 +
512 + return $srcs;
513 + }
514 +
515 + /**
516 + * get image by url accessing the database directly
517 + * @since 1.1
518 + * @updated 1.1.3
519 + * @param string $url url of the image
520 + * @return id of the image
521 + */
522 + public function get_image_by_url($url = '')
523 + {
524 + if (empty($url)) {
525 + return 0;
526 + }
527 + $types = implode('|', $this->_allowedExtensions);
528 + // check for the format 'image-title-(e12452112-)300x200.jpg' and remove the image size and edit mark from it
529 + $newurl = preg_replace("/(-e\d+){0,1}-(\d+)x(\d+)\.({$types})$/i", '.${4}', $url);
530 + global $wpdb;
531 + $query = $wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid = %s", $newurl);
532 + $id = $wpdb->get_var($query);
533 + return $id;
534 + }
535 +
536 + /**
537 + * Update isc_image_posts meta field for all images found in a post with a given ID.
538 + * @param $post_id ID of the target post
539 + * @param $content content of the target post
540 + */
541 + public function update_image_posts_meta($post_id, $content)
542 + {
543 + $image_urls = $this->_filter_src_attributes($content);
544 + $image_ids = array();
545 + $added_images = array();
546 + $removed_images = array();
547 +
548 + $isc_post_images = get_post_meta($post_id, 'isc_post_images', true);
549 +
550 + foreach ($image_urls as $url) {
551 + $id = intval($this->get_image_by_url($url));
552 + array_push($image_ids, $id);
553 + if (is_array($isc_post_images) && !array_key_exists($id, $isc_post_images)) {
554 + array_push($added_images, $id);
555 + }
556 + }
557 + if (is_array($isc_post_images)) {
558 + foreach ($isc_post_images as $old_id => $value) {
559 + if (!in_array($old_id, $image_ids)) {
560 + array_push($removed_images, $old_id);
561 + } else {
562 + if (!empty($old_id)) {
563 + $meta = get_post_meta($old_id, 'isc_image_posts', true);
564 + if (empty($meta)) {
565 + update_post_meta($old_id, 'isc_image_posts', array($post_id));
566 + } else {
567 + // In case the isc_image_posts is not up to date
568 + if (is_array($meta) && !in_array($post_id, $meta)) {
569 + array_push($meta, $post_id);
570 + update_post_meta($old_id, 'isc_image_posts', $meta);
571 + }
572 + }
573 + }
574 + }
575 + }
576 + }
577 +
578 + foreach ($added_images as $id) {
579 + $meta = get_post_meta($id, 'isc_image_posts', true);
580 + if (!is_array($meta) || array() == $meta) {
581 + update_post_meta($id, 'isc_image_posts', array($post_id));
582 + } else {
583 + array_push($meta, $post_id);
584 + update_post_meta($id, 'isc_image_posts', $meta);
585 + }
586 + }
587 +
588 + foreach ($removed_images as $id) {
589 + $image_meta = get_post_meta($id, 'isc_image_posts', true);
590 + if (is_array($image_meta)) {
591 + $offset = array_search($post_id, $image_meta);
592 + if (false !== $offset) {
593 + array_splice($image_meta, $offset, 1);
594 + update_post_meta($id, 'isc_image_posts', $image_meta);
595 + }
596 + }
597 + }
598 + }
599 +
600 + /**
601 + * create shortcode to list all image sources in the frontend
602 + * @param array $atts
603 + * @since 1.1.3
604 + * @todo link to the post
605 + */
606 + public function list_all_post_attachments_sources_shortcode($atts = array())
607 + {
608 +
609 + /**
610 + * @todo why not translate here with the code below?
611 + * > Because the two if statements below will need to call gettext (again) for comparing values.
612 + */
613 + extract(shortcode_atts(array(
614 + 'per_page' => 99999,
615 + 'before_links' => '',
616 + 'after_links' => '',
617 + 'prev_text' => '&#171; Previous',
618 + 'next_text' => 'Next &#187;'
619 + ),
620 + $atts));
621 +
622 + /**
623 + * @todo why not include this into the array above?
624 + */
625 + if ('&#171; Previous' == $prev_text)
626 + $prev_text = __('&#171; Previous', ISCTEXTDOMAIN);
627 + if ('Next &#187;' == $next_text)
628 + $next_text = __('Next &#187;', ISCTEXTDOMAIN);
629 +
630 + // retrieve all attachments
631 + $args = array(
632 + 'post_type' => 'attachment',
633 + 'numberposts' => -1,
634 + 'post_status' => null,
635 + 'post_parent' => null,
636 + 'meta_query' => array(
637 + array(
638 + 'key' => 'isc_image_posts',
639 + 'value' => 'a:0:{}',
640 + 'compare' => '!='
641 + )
642 + )
643 + /** @todo maybe add offset to not retrieve the first results when not on first page */
644 + /** @todo maybe add limit to not retrieve more results than on the current page */
645 + /** >No, we need to get total count of attachment with parents for $max_page in the pagination link. */
646 + );
647 +
648 + $attachments = get_posts($args);
649 + if (empty($attachments)) {
650 + return;
651 + }
652 +
653 + $options = $this->get_isc_options();
654 +
655 + $connected_atts = array();
656 +
657 + //Keeps only those ones who have parent
658 +
659 + foreach ($attachments as $_attachment) {
660 + $connected_atts[$_attachment->ID]['source'] = get_post_meta($_attachment->ID, 'isc_image_source', true);
661 + $connected_atts[$_attachment->ID]['own'] = get_post_meta($_attachment->ID, 'isc_image_source_own', true);
662 + $connected_atts[$_attachment->ID]['title'] = $_attachment->post_title;
663 + $connected_atts[$_attachment->ID]['author_name'] = '';
664 + if ('' != $connected_atts[$_attachment->ID]['own']) {
665 + $parent = get_post($_attachment->post_parent);
666 + $connected_atts[$_attachment->ID]['author_name'] = get_the_author_meta('display_name', $parent->post_author);
667 + }
668 +
669 + $metadata = get_post_meta($_attachment->ID, 'isc_image_posts', true);
670 + $parents_data = '';
671 +
672 + if (is_array($metadata) && array() != $metadata) {
673 + $parents_data .= "<ul style='margin: 0;'>";
674 + foreach($metadata as $data) {
675 + $parents_data .= sprintf(__('<li><a href="%1$s" title="View %2$s">%3$s</a></li>', ISCTEXTDOMAIN),
676 + esc_url(get_permalink($data)),
677 + esc_attr(get_the_title($data)),
678 + esc_html(get_the_title($data))
679 + );
680 + }
681 + $parents_data .= "</ul>";
682 + }
683 +
684 + $connected_atts[$_attachment->ID]['posts'] = $parents_data;
685 + }
686 +
687 + $total = count($connected_atts);
688 +
689 + if (0 == $total)
690 + return;
691 +
692 + $page = isset($_GET['isc-page']) ? intval($_GET['isc-page']) : 1;
693 + $down_limit = 1; // First page
694 +
695 + $up_limit = 1;
696 +
697 + if ($per_page < $total) {
698 + $rem = $total % $per_page; // The Remainder of $total/$per_page
699 + $up_limit = ($total - $rem) / $per_page;
700 + if (0 < $rem) {
701 + $up_limit++; //If rem is positive, add the last page that contains less than $per_page attachment;
702 + }
703 + }
704 +
705 + ob_start();
706 + if ( 2 > $up_limit ) {
707 + $this->display_all_attachment_list($connected_atts);
708 + } else {
709 + $starting_atts = $per_page * ($page - 1); // for page 2 and 3 $per_page start display on $connected_atts[3*(2-1) = 3]
710 + $paged_atts = array_slice($connected_atts, $starting_atts, $per_page, true);
711 + $this->display_all_attachment_list($paged_atts);
712 + $this->pagination_links($up_limit, $before_links, $after_links, $prev_text, $next_text);
713 + }
714 + if (isset($options['webgilde']) && true == $options['webgilde']) {
715 + ?>
716 + <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>
717 + <?php
718 + }
719 +
720 + $output = ob_get_clean();
721 + return $output;
722 + }
723 +
724 +
725 + /**
726 + * performs rendering of all attachments list
727 + * @since 1.1.3
728 + */
729 + public function display_all_attachment_list($atts)
730 + {
731 + if (!is_array($atts) || $atts == array())
732 + return;
733 + $options = $this->get_isc_options();
734 + if (!isset($options['thumbnail_size'])) {
735 + $options = $options + $this->default_options();
736 + }
737 + ?>
738 + <table>
739 + <thead>
740 + <?php if ($options['thumbnail_in_list']) : ?>
741 + <th><?php _e('Thumbnail', ISCTEXTDOMAIN); ?></th>
742 + <?php endif; ?>
743 + <th><?php _e("Attachment's ID", ISCTEXTDOMAIN); ?></th>
744 + <th><?php _e('Title', ISCTEXTDOMAIN); ?></th>
745 + <th><?php _e('Attached to', ISCTEXTDOMAIN); ?></th>
746 + <th><?php _e('Source', ISCTEXTDOMAIN); ?></th>
747 + </thead>
748 + <tbody>
749 + <?php foreach ($atts as $id => $data) : ?>
750 + <?php
751 + /** @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 */
752 + $source = __('Not available', ISCTEXTDOMAIN);
753 + if ('' != $data['own']) {
754 + /** @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 */
755 + if ($this->_options['use_authorname']) {
756 + $source = $data['author_name'];
757 + } else {
758 + $source = $this->_options['by_author_text'];
759 + }
760 + } else {
761 + if (!empty($data['source']))
762 + $source = $data['source'];
763 + }
764 + ?>
765 + <tr>
766 + <?php
767 + $v_align = '';
768 + if ($options['thumbnail_in_list']) :
769 + $v_align = 'style="vertical-align: top;"';
770 + ?>
771 + <?php if ('custom' != $options['thumbnail_size']) : ?>
772 + <td><?php echo wp_get_attachment_image($id, $options['thumbnail_size']); ?></td>
773 + <?php else : ?>
774 + <td><?php echo wp_get_attachment_image($id, array($options['thumbnail_width'], $options['thumbnail_height'])); ?></td>
775 + <?php endif; ?>
776 + <?php endif; ?>
777 + <td <?php echo $v_align;?>><?php echo $id; ?></td>
778 + <td <?php echo $v_align;?>><?php echo $data['title']; ?></td>
779 + <td <?php echo $v_align;?>><?php echo $data['posts']; ?></td>
780 + <td <?php echo $v_align;?>><?php echo esc_html($source); ?></td>
781 + </tr>
782 + <?php endforeach; ?>
783 + </tbody>
784 + </table>
785 + <?php
786 + }
787 +
788 + /**
789 + * Render pagination links, use $before_links and after_links to wrap pagination links inside an additional block
790 + * @param int $max_page total page count
791 + * @param string $before_links optional html to display before pagination links
792 + * @param string $after_links optional html to display after pagination links
793 + * @param string $prev_text text for the previous page link
794 + * @param string $next_text text for the next page link
795 + * @since 1.1.3
796 + *
797 + */
798 + public function pagination_links($max_page, $before_links, $after_links, $prev_text, $next_text)
799 + {
800 + if ((!isset($max_page)) || (!isset($before_links)) || (!isset($after_links)) || (!isset($prev_text)) || (!isset($next_text)))
801 + return;
802 + if (!empty($before_links))
803 + echo $before_links;
804 + ?>
805 + <div class="isc-paginated-links">
806 + <?php
807 + $page = isset($_GET['isc-page']) ? intval($_GET['isc-page']) : 1;
808 + if ($max_page < $page) {
809 + $page = $max_page;
810 + }
811 + if ($page < 1) {
812 + $page = 1;
813 + }
814 + $min_page = 1;
815 + $backward_distance = $page - $min_page;
816 + $forward_distance = $max_page - $page;
817 +
818 + $page_link = get_page_link();
819 +
820 + /**
821 + * Remove the query_string of the page_link (?page_id=xyz for the standard permalink structure),
822 + * which is already captured in $_SERVER['QUERY_STRING'].
823 + * @todo replace regex with other value (does WP store the url path without attributes somewhere?
824 + * >get_page_link() returns the permalink but for the default WP permalink structure, the permalink looks like "http://domain.tld/?p=52", while $_GET
825 + * still has a field named 'page_id' with the same value of 52.
826 + */
827 +
828 + $pos = strpos($page_link, '?');
829 + if (false !== $pos) {
830 + $page_link = substr($page_link, 0, $pos);
831 + }
832 +
833 + /**
834 + * 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
835 + * pagination link.
836 + */
837 +
838 + if (isset($_GET['isc-page'])) {
839 + unset($_GET['isc-page']);
840 + }
841 +
842 + $query_string = http_build_query($_GET);
843 +
844 + $isc_query_tag = '';
845 + if (empty($query_string)) {
846 + $isc_query_tag = '?isc-page=';
847 + } else {
848 + $query_string = '?' . $query_string;
849 + $isc_query_tag = '&isc-page=';
850 + }
851 +
852 + if ($min_page != $page) {
853 + ?>
854 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page-1); ?>" class="prev page-numbers"><?php echo $prev_text; ?></a>
855 + <?php
856 + }
857 +
858 + if (5 < $max_page) {
859 +
860 + if (3 < $backward_distance) {
861 + ?>
862 + <a href="<?php echo $page_link . $query_string . $isc_query_tag; ?>1" class="page-numbers">1</a>
863 + <span class="page-numbers dots">...</span>
864 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page-2);?>" class="page-numbers"><?php echo $page-2; ?></a>
865 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page-1);?>" class="page-numbers"><?php echo $page-1; ?></a>
866 + <span class="page-numbers current"><?php echo $page; ?></span>
867 + <?php
868 + } else {
869 + for ($i = 1; $i <= $page; $i++) {
870 + if ($i == $page) {
871 + ?>
872 + <span class="page-numbers current"><?php echo $i; ?></span>
873 + <?php
874 + } else {
875 + ?>
876 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . $i;?>" class="page-numbers"><?php echo $i; ?></a>
877 + <?php
878 + }
879 + }
880 + }
881 +
882 + if (3 < $forward_distance) {
883 + ?>
884 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page+1);?>" class="page-numbers"><?php echo $page+1; ?></a>
885 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page+2);?>" class="page-numbers"><?php echo $page+2; ?></a>
886 + <span class="page-numbers dots">...</span>
887 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . $max_page;?>" class="page-numbers"><?php echo $max_page; ?></a>
888 + <?php
889 + } else {
890 + for ($i = $page+1; $i <= $max_page; $i++) {
891 + ?>
892 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . $i;?>" class="page-numbers"><?php echo $i; ?></a>
893 + <?php
894 + }
895 + }
896 + } else {
897 + for ($i = 1; $i <= $max_page; $i++) {
898 + if ($i == $page) {
899 + ?>
900 + <span class="page-numbers current"><?php echo $i; ?></span>
901 + <?php
902 + } else {
903 + ?>
904 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . $i;?>" class="page-numbers"><?php echo $i; ?></a>
905 + <?php
906 + }
907 + }
908 + }
909 + if ($page != $max_page) {
910 + ?>
911 + <a href="<?php echo $page_link . $query_string . $isc_query_tag . ($page+1);?>" class="next page-numbers"><?php echo $next_text; ?></a>
912 + <?php
913 + }
914 + ?>
915 + </div>
916 + <?php
917 + echo $after_links;
918 + }
919 +
920 + /**
921 + * The activation function
922 + */
923 + public function activation()
924 + {
925 + if (!is_array(get_option('isc_options'))) {
926 + update_option( 'isc_options', $this->default_options() );
927 + }
928 + $options = $this->get_isc_options();
929 + if (!$options['installed']) {
930 + /**
931 + * Here, all jobs to perform during first installation, especially options and custom fields.
932 + * Important: No add_action('something', 'somefunction').
933 + */
934 +
935 + // adds meta fields for attachments
936 + $this->add_meta_values_to_attachments();
937 +
938 + // set all isc_image_posts meta fields.
939 + $this->init_image_posts_metafield();
940 +
941 + $options['installed'] = true;
942 + update_option('isc_options', $options);
943 + }
944 + }
945 +
946 + /**
947 + * Returns default options
948 + */
949 + public function default_options()
950 + {
951 + $default['image_list_headline'] = __('image sources', ISCTEXTDOMAIN);
952 + $default['use_authorname'] = true;
953 + $default['by_author_text'] = __('Owned by the author', ISCTEXTDOMAIN);
954 + $default['installed'] = false;
955 + $default['version'] = '1.2';
956 + $default['webgilde'] = false;
957 + $default['thumbnail_in_list'] = false;
958 + $default['thumbnail_size'] = 'thumbnail';
959 + $default['thumbnail_width'] = 150;
960 + $default['thumbnail_height'] = 150;
961 + return $default;
962 + }
963 +
964 + /**
965 + * Settings API initialization
966 + */
967 + public function SAPI_init()
968 + {
969 + $this->upgrade_management();
970 + register_setting('isc_options_group', 'isc_options', array($this, 'settings_validation'));
971 + add_settings_section('isc_settings_section', '', '__return_false', 'isc_settings_page');
972 + add_settings_field('image_list_headline', __('Image list headline', ISCTEXTDOMAIN), array($this, 'renderfield_list_headline'), 'isc_settings_page', 'isc_settings_section');
973 + add_settings_field('use_authorname', __('Use authors names', ISCTEXTDOMAIN), array($this, 'renderfield_use_authorname'), 'isc_settings_page', 'isc_settings_section');
974 + add_settings_field('by_author_text', __('Custom text for owned images', ISCTEXTDOMAIN), array($this, 'renderfield_byauthor_text'), 'isc_settings_page', 'isc_settings_section');
975 + add_settings_field('webgilde_backlink', __("Link to webgilde's website", ISCTEXTDOMAIN), array($this, 'renderfield_webgile'), 'isc_settings_page', 'isc_settings_section');
976 + add_settings_field('use_thumbnail', __("Use thumbnails in images list", ISCTEXTDOMAIN), array($this, 'renderfield_use_thumbnail'), 'isc_settings_page', 'isc_settings_section');
977 + add_settings_field('thumbnail_width', __("Thumbnails max-width", ISCTEXTDOMAIN), array($this, 'renderfield_thumbnail_width'), 'isc_settings_page', 'isc_settings_section');
978 + add_settings_field('thumbnail_height', __("Thumbnails max-height", ISCTEXTDOMAIN), array($this, 'renderfield_thumbnail_height'), 'isc_settings_page', 'isc_settings_section');
979 + }
980 +
981 + /**
982 + * manage data structure upgrading of outdated versions
983 + */
984 + public function upgrade_management() {
985 + /**
986 + * Since the activation hook is not executed on plugin upgrade, this function checks options in database
987 + * during the admin_init hook to handle plugin's upgrade.
988 + */
989 +
990 + $options = get_option( 'isc_options' );
991 +
992 + $max_step = count($this->_upgrade_step);
993 + $step_count = 0;
994 +
995 + if (!is_array($options) || !isset($options['version'])){ // versions prior to 1.2
996 +
997 + $default = $this->default_options();
998 + $options = $options + $default;
999 + $this->init_image_posts_metafield();
1000 + $options['installed'] = true;
1001 +
1002 + update_option('isc_options', $options);
1003 + $step_count++;
1004 +
1005 + } elseif(ISCVERSION != $options['version']) {
1006 +
1007 + while (ISCVERSION != $options['version'] && $step_count <= $max_step) {
1008 + switch ($options['version']) {
1009 + /**
1010 + * Here, the incremental upgrade process depending on the currently installed version.
1011 + */
1012 + }
1013 + }
1014 +
1015 + }
1016 + }
1017 +
1018 + /**
1019 + * Image_control's page callback
1020 + */
1021 + public function render_isc_settings_page()
1022 + {
1023 + ?>
1024 + <div id="icon-options-general" class="icon32"><br></div>
1025 + <h2><?php _e('Images control settings', ISCTEXTDOMAIN); ?></h2>
1026 + <form id="image-control-form" method="post" action="options.php">
1027 + <?php
1028 + settings_fields( 'isc_options_group' );
1029 + do_settings_sections( 'isc_settings_page' );
1030 + submit_button();
1031 + ?>
1032 + </form>
1033 + <?php
1034 + }
1035 +
1036 + /**
1037 + * image_list field callbacks
1038 + */
1039 + public function renderfield_list_headline()
1040 + {
1041 + $options = $this->get_isc_options();
1042 + $description = __('The headline of the image list added via shortcode or function in your theme.', ISCTEXTDOMAIN);
1043 + ?>
1044 + <div id="image-list-headline-block">
1045 + <label for="list-head"><?php __('Image list headline', ISCTEXTDOMAIN); ?></label>
1046 + <input type="text" name="isc_options[image_list_headline_field]" id="list-head" value="<?php echo $options['image_list_headline'] ?>" class="regular-text" />
1047 + <p><em><?php echo $description; ?></em></p>
1048 + </div>
1049 + <?php
1050 + }
1051 +
1052 + public function renderfield_use_authorname()
1053 + {
1054 + $options = $this->get_isc_options();
1055 + $description = __("Display the author's public name as source when the image is owned by the author. Uncheck to use a custom text instead.", ISCTEXTDOMAIN);
1056 + ?>
1057 + <div id="use-authorname-block">
1058 + <label for="use_authorname"><?php _e('Use author name') ?></label>
1059 + <input type="checkbox" name="isc_options[use_authorname_ckbox]" id="use_authorname" <?php checked($options['use_authorname']); ?> />
1060 + <p><em><?php echo $description; ?></em></p>
1061 + </div>
1062 + <?php
1063 + }
1064 +
1065 + public function renderfield_byauthor_text()
1066 + {
1067 + $options = $this->get_isc_options();
1068 + $description = __("Enter the custom text to display if you do not want to use the author's public name.", ISCTEXTDOMAIN);
1069 + ?>
1070 + <div id="by-author-text">
1071 + <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" />
1072 + <p><em><?php echo $description; ?></em></p>
1073 + </div>
1074 + <?php
1075 + }
1076 +
1077 + public function renderfield_webgile()
1078 + {
1079 + $options = $this->get_isc_options();
1080 + /**
1081 + * Avoid warning notices because of the absence of webgilde field in isc_options throughout development steps.
1082 + * This 'if' block can be removed for the next release.
1083 + */
1084 + if (!isset($options['webgilde'])) {
1085 + $options = $options + $this->default_options();
1086 + }
1087 + $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);
1088 + ?>
1089 + <div id="webgilde-block">
1090 + <input type="checkbox" id="webgilde-link" name="isc_options[webgilde_field]" <?php checked($options['webgilde']); ?> />
1091 + <p><em><?php echo $description; ?></em></p>
1092 + </div>
1093 + <?php
1094 + }
1095 +
1096 + public function renderfield_use_thumbnail()
1097 + {
1098 + $options = $this->get_isc_options();
1099 + if (!isset($options['thumbnail_size'])) {
1100 + $options = $options + $this->default_options();
1101 + }
1102 + $description = __('Display thumbnails on the list of all images in the blog.' ,ISCTEXTDOMAIN);
1103 + ?>
1104 + <div id="use-thumbnail-block">
1105 + <input type="checkbox" id="use-thumbnail" name="isc_options[use_thumbnail]" <?php checked($options['thumbnail_in_list']); ?> />
1106 + <select id="thumbnail-size-select" name="isc_options[size_select]" <?php disabled(!$options['thumbnail_in_list']) ?>>
1107 + <?php foreach ($this->_thumbnail_size as $size) : ?>
1108 + <option value="<?php echo $size; ?>" <?php selected($size, $options['thumbnail_size']);?>><?php echo $size; ?></option>
1109 + <?php endforeach; ?>
1110 + </select>
1111 + <p><em><?php echo $description; ?></em></p>
1112 + </div>
1113 + <?php
1114 + }
1115 +
1116 + public function renderfield_thumbnail_width()
1117 + {
1118 + $options = $this->get_isc_options();
1119 + if (!isset($options['thumbnail_size'])) {
1120 + $options = $options + $this->default_options();
1121 + }
1122 + $description = __('Custom value of the maximum allowed width for thumbnail.' ,ISCTEXTDOMAIN);
1123 + ?>
1124 + <div id="thumbnail-custom-width">
1125 + <input type="text" id="custom-width" name="isc_options[thumbnail_width]" class="small-text" value="<?php echo $options['thumbnail_width'] ?>" /> px
1126 + <p><em><?php echo $description; ?></em></p>
1127 + </div>
1128 + <?php
1129 + }
1130 +
1131 + public function renderfield_thumbnail_height()
1132 + {
1133 + $options = $this->get_isc_options();
1134 + if (!isset($options['thumbnail_size'])) {
1135 + $options = $options + $this->default_options();
1136 + }
1137 + $description = __('Custom value of the maximum allowed height for thumbnail.' ,ISCTEXTDOMAIN);
1138 + ?>
1139 + <div id="thumbnail-custom-height">
1140 + <input type="text" id="custom-height" name="isc_options[thumbnail_height]" class="small-text" value="<?php echo $options['thumbnail_height'] ?>"/> px
1141 + <p><em><?php echo $description; ?></em></p>
1142 + </div>
1143 + <?php
1144 + }
1145 +
1146 + /**
1147 + * Returns isc_options if it exists, returns the default options otherwise.
1148 + */
1149 + public function get_isc_options() {
1150 + return get_option('isc_options', $this->default_options());
1151 + }
1152 +
1153 + /*
1154 + * Input validation function.
1155 + * @param array $input values from the admin panel
1156 + */
1157 + public function settings_validation($input)
1158 + {
1159 + $output = $this->get_isc_options();
1160 + $output['image_list_headline'] = esc_html($input['image_list_headline_field']);
1161 + if (isset($input['use_authorname_ckbox'])) {
1162 + // Don't worry about the custom text if the author name is selected.
1163 + $output['use_authorname'] = true;
1164 + } else {
1165 + $output['use_authorname'] = false;
1166 + $output['by_author_text'] = esc_html($input['by_author_text_field']);
1167 + }
1168 + if (isset($input['webgilde_field'])) {
1169 + $output['webgilde'] = true;
1170 + } else {
1171 + $output['webgilde'] = false;
1172 + }
1173 + if (isset($input['use_thumbnail'])) {
1174 + $output['thumbnail_in_list'] = true;
1175 + if (in_array($input['size_select'], $this->_thumbnail_size)) {
1176 + $output['thumbnail_size'] = $input['size_select'];
1177 + }
1178 + if ('custom' == $input['size_select']) {
1179 + if (is_numeric($input['thumbnail_width'])) {
1180 + // Ensures that the value stored in database in a positive integer.
1181 + $output['thumbnail_width'] = abs(intval(round($input['thumbnail_width'])));
1182 + }
1183 + if (is_numeric($input['thumbnail_height'])) {
1184 + $output['thumbnail_height'] = abs(intval(round($input['thumbnail_height'])));
1185 + }
1186 + }
1187 + } else {
1188 + $output['thumbnail_in_list'] = false;
1189 + }
1190 + return $output;
1191 + }
1192 +
1193 + /**
1194 + * Adds isc_image_posts on all attachments. Launched during first installation.
1195 + */
1196 + public function init_image_posts_metafield()
1197 + {
1198 + $args = array(
1199 + 'post_type' => 'any',
1200 + 'numberposts' => -1,
1201 + 'post_status' => null,
1202 + 'post_parent' => null,
1203 + );
1204 + $posts = get_posts($args);
1205 + foreach ($posts as $post) {
1206 + setup_postdata($post);
1207 + $image_urls = $this->_filter_src_attributes($post->post_content);
1208 + $image_ids = array();
1209 + foreach ($image_urls as $url) {
1210 + $image_id = intval($this->get_image_by_url($url));
1211 + array_push($image_ids,$image_id);
1212 + }
1213 + foreach ($image_ids as $id) {
1214 + $meta = get_post_meta($id, 'isc_image_posts', true);
1215 + if (empty($meta)) {
1216 + update_post_meta($id, 'isc_image_posts', array($post->ID));
1217 + } else {
1218 + if (!in_array($post->ID, $meta)) {
1219 + array_push($meta, $post->ID);
1220 + update_post_meta($id, 'isc_image_posts', $meta);
1221 + }
1222 + }
1223 + }
1224 + }
1225 + }
1226 +
1227 + }// end of class
1228 +
1229 + $inc_path = ABSPATH . 'wp-includes/';
1230 + /**
1231 + * "pluggable.php" is not defined at this point. Not sure about the reason.
1232 + */
1233 + require_once($inc_path . 'pluggable.php');
1234 +
1235 + /**
1236 + * Need an instance of ISC_CLASS when the register_activation_hook is called (earlier than the "plugins_loaded" hook).
1237 + */
1238 + global $my_isc;
1239 + $my_isc = new ISC_CLASS();
1240 +
1241 + /**
1242 + * the next functions are just to have an easier access from outside the class
1243 + */
1244 + function isc_list($post_id = 0) {
1245 + $isc = new ISC_CLASS();
1246 + echo $isc->list_post_attachments_with_sources($post_id);
1247 + }
56 1248 }
57 -
58 -new ISC_Block_Options();