PluginProbe
Image Source Control Lite – Show Image Credits and Captions / 1.10.2
Image Source Control Lite – Show Image Credits and Captions v1.10.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
image-source-control-isc / isc.class.php

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

528 lines 21.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class ISC_Class {
4
5 /**
6 * define default meta fields
7 */
8 protected $_fields = array(
9 'image_source' => array(
10 'id' => 'isc_image_source',
11 'default' => '',
12 ),
13 'image_source_url' => array(
14 'id' => 'isc_image_source_url',
15 'default' => '',
16 ),
17 'image_source_own' => array(
18 'id' => 'isc_image_source_own',
19 'default' => '',
20 ),
21 'image_posts' => array(
22 'id' => 'isc_image_posts',
23 'default' => array()
24 ),
25 'image_licence' => array(
26 'id' => 'isc_image_licence',
27 'default' => ''
28 )
29 );
30
31 /**
32 * allowed image file types/extensions
33 * @since 1.1
34 */
35 protected $_allowedExtensions = array(
36 'jpg', 'png', 'gif', 'jpeg'
37 );
38
39 /**
40 * Thumbnail size in list of all images.
41 * @since 1.2
42 */
43 protected $_thumbnail_size = array('thumbnail', 'medium', 'large', 'custom');
44
45 /**
46 * options saved in the db
47 * @since 1.2
48 */
49 protected $_options = array();
50
51 /**
52 * Position of image's caption
53 */
54 protected $_caption_position = array(
55 'top-left',
56 'top-center',
57 'top-right',
58 'center',
59 'bottom-left',
60 'bottom-center',
61 'bottom-right'
62 );
63
64 protected static $instance;
65
66 public static function get_instance() {
67 return self::$instance;
68 }
69
70 /**
71 * Setup registers filterts and actions.
72 */
73 public function __construct()
74 {
75 // load all plugin options
76 $this->_options = get_option('isc_options');
77 self::$instance = $this;
78 }
79
80 /**
81 * add meta values to all attachments
82 * @todo probably need to fix this when more fields are added along the way
83 * @todo use compare => 'NOT EXISTS' when WP 3.5 is up to retrieve only values where it is not set
84 * @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
85 */
86 public function add_meta_values_to_attachments()
87 {
88 // retrieve all attachments
89 $args = array(
90 'post_type' => 'attachment',
91 'numberposts' => -1,
92 'post_status' => null,
93 'post_parent' => null,
94 );
95
96 $attachments = get_posts($args);
97 if ( empty($attachments) || !is_array($attachments) ) {
98 return;
99 }
100
101 $count = 0;
102 foreach ( $attachments as $_attachment ) {
103 $set = false;
104 setup_postdata($_attachment);
105 foreach ( $this->_fields as $_field ) {
106 $meta = get_post_meta($_attachment->ID, $_field['id'], true);
107 if (empty($meta)) {
108 update_post_meta($_attachment->ID, $_field['id'], $_field['default']);
109 $set = true;
110 }
111 }
112 if ($set) {
113 $count++;
114 }
115 }
116 }
117
118 /**
119 * retrieve images added to a post or page and save all information as a post meta value for the post
120 * @since 1.1
121 * @updated 1.3.5 added isc_images_in_posts filter
122 * @todo check for more post types that maybe should not be parsed here
123 */
124 public function save_image_information($post_id, $content = '' )
125 {
126 // creates an infinite loop if not secured, see ISC_Public::list_post_attachments_with_sources()
127 $content = apply_filters( 'the_content', $content );
128
129 /*$_image_urls = $this->_filter_src_attributes($_content);
130 $_imgs = array();
131
132 foreach ($_image_urls as $_image_url) {
133 // get ID of images by url
134 $img_id = $this->get_image_by_url($_image_url);
135 $_imgs[$img_id] = array(
136 'src' => $_image_url
137 );
138 }*/
139
140 $_imgs = $this->_filter_image_ids($content);
141
142 // add thumbnail information
143 $thumb_id = get_post_thumbnail_id($post_id);
144
145 /**
146 * if an image is used both inside the post and as post thumbnail, the thumbnail entry overrides the regular image.
147 */
148 if ( !empty( $thumb_id )) {
149 $_imgs[$thumb_id] = array(
150 'src' => wp_get_attachment_url($thumb_id),
151 'thumbnail' => true
152 );
153 }
154
155 // apply filter to image array, so other developers can add their own logic
156 $_imgs = apply_filters('isc_images_in_posts', $_imgs, $post_id);
157
158 if (empty($_imgs)) {
159 $_imgs = array();
160 }
161 update_post_meta($post_id, 'isc_post_images', $_imgs);
162 }
163
164 /**
165 * filter image src attribute from text
166 * @since 1.1
167 * @updated 1.1.3
168 * @deprecated since 1.9 use _filter_image_ids instead
169 * @return array with image src uri-s
170 */
171 public function _filter_src_attributes($content = '')
172 {
173 $srcs = array();
174 if (empty($content))
175 return $srcs;
176
177 // parse HTML with DOM
178 $dom = new DOMDocument;
179
180 libxml_use_internal_errors(true);
181 if ( function_exists('mb_convert_encoding') ) {
182 $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
183 }
184 $dom->loadHTML($content);
185
186 // Prevents from sending E_WARNINGs notice (Outputs are forbidden during activation)
187 libxml_clear_errors();
188
189 foreach ($dom->getElementsByTagName('img') as $node) {
190 if ( isset( $node->attributes ) ) {
191 if ( null !== $node->attributes->getNamedItem('src') ) {
192 $srcs[] = $node->attributes->getNamedItem('src')->textContent;
193 }
194 }
195 }
196
197 return $srcs;
198 }
199
200 /**
201 * filter image ids from text
202 + * @return array with image ids => image src uri-s
203 + */
204 public function _filter_image_ids($content = '') {
205 $srcs = array();
206 if (empty($content)){
207 return $srcs;
208 }
209
210 // parse HTML with DOM
211 $dom = new DOMDocument;
212
213 libxml_use_internal_errors(true);
214 if ( function_exists('mb_convert_encoding') ) {
215 $content = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
216 }
217 $dom->loadHTML($content);
218
219 // Prevents from sending E_WARNINGs notice (Outputs are forbidden during activation)
220 libxml_clear_errors();
221
222 foreach ($dom->getElementsByTagName('img') as $node) {
223 if ( isset( $node->attributes ) ) {
224 $matched = false;
225 if ( null !== $node->attributes->getNamedItem('class') ) {
226 if (preg_match('#.*wp-image-(\d+?).*#U', $node->attributes->getNamedItem('class')->textContent, $matches)) {
227 $srcs[intval($matches[1])] = $node->attributes->getNamedItem('src')->textContent;
228 $matched = true;
229 }
230 }
231 if (!$matched) {
232 if ( null !== $node->attributes->getNamedItem('src') ) {
233 $url = $node->attributes->getNamedItem('src')->textContent;
234 // get ID of images by url
235 $id = $this->get_image_by_url($url);
236 if ($id) {
237 $srcs[$id] = $url;
238 }
239 }
240 }
241 }
242 }
243
244 return $srcs;
245 }
246
247 /**
248 * get image by url accessing the database directly
249 * @since 1.1
250 * @updated 1.1.3
251 * @param string $url url of the image
252 * @return id of the image
253 */
254 public function get_image_by_url($url = '')
255 {
256 global $wpdb;
257
258 if (empty($url)) {
259 return 0;
260 }
261 $types = implode( '|', $this->_allowedExtensions );
262 /**
263 * check for the format 'image-title-(e12452112-)300x200.jpg(?query…)' and removes
264 * the image size
265 * edit marks
266 * additional query vars
267 */
268 $newurl = esc_url( preg_replace( "/(-e\d+){0,1}(-\d+x\d+){0,1}\.({$types})(.*)/i", '.${3}', $url ) );
269
270 // remove protocoll (http or https)
271 $url = str_ireplace( array( 'http:', 'https:' ) , '', $url );
272 $newurl = str_ireplace( array( 'http:', 'https:' ) , '', $newurl );
273
274 // not escaped, because escaping already happened above
275 $raw_query = $wpdb->prepare(
276 "SELECT ID FROM `$wpdb->posts` WHERE post_type='attachment' AND guid = %s OR guid = %s OR guid = %s OR guid = %s LIMIT 1",
277 "http:$url",
278 "https:$url",
279 "http:$newurl",
280 "https:$newurl"
281 );
282
283 $query = apply_filters( 'isc_get_image_by_url_query', $raw_query, $newurl );
284 $id = $wpdb->get_var($query);
285
286 return intval( $id );
287 }
288
289 /**
290 * Update isc_image_posts meta field for all images found in a post with a given ID.
291 * @param $post_id ID of the target post
292 * @param $content content of the target post
293 * @updated 1.3.5 added images_in_posts_simple filter
294 */
295 public function update_image_posts_meta($post_id, $content)
296 {
297 $content = apply_filters( 'the_content', $content );
298
299 $image_ids = $this->_filter_image_ids($content);
300 $added_images = array();
301 $removed_images = array();
302
303 // add thumbnail information
304 $thumb_id = get_post_thumbnail_id($post_id);
305 if ( !empty( $thumb_id )) {
306 $image_ids[$thumb_id] = wp_get_attachment_url($thumb_id);
307 }
308
309 // get urls from gallery images
310 // this might not be needed, since the gallery shortcode might have run already, but just in case
311 // only for php 5.3 and higher
312 if ( -1 !== version_compare( phpversion(), '5.3' ) && preg_match_all('/\[gallery([^\]]+)\]/m', $content, $results, PREG_SET_ORDER)) {
313 foreach ($results as $result) {
314 if (! preg_match('/ids="([^"]+)"/m', $result[1], $ids)) {
315 continue;
316 }
317 //$image_urls = array_merge($image_urls, array_map( 'map_walker', explode(',', $ids[1])));
318 foreach (explode(',', $ids[1]) as $id) {
319 $image_ids[intval($id)] = get_the_guid($id);
320 }
321 }
322 }
323
324 // apply filter to image array, so other developers can add their own logic
325 // $image_urls = apply_filters('isc_images_in_posts_simple', $image_urls, $post_id);
326 $filtered_image_ids = apply_filters('isc_images_in_posts_simple', $image_ids, $post_id);
327 //for backwards compatibilty: check if the array-keys are valid image ids
328 if ($filtered_image_ids != $image_ids) {
329 $image_ids = array();
330 $valid_post_types = apply_filters('isc_valid_post_types', array('attachment'));
331 if (in_array(get_post_type($post_id), $valid_post_types)) {
332 if ($id = $this->get_image_by_url($url)) {
333 $image_ids[$id] = $url;
334 }
335 } else {
336 $image_ids[$post_id] = $url;
337 }
338 } else {
339 $image_ids = $filtered_image_ids;
340 }
341
342 $isc_post_images = get_post_meta($post_id, 'isc_post_images', true);
343 // just needed in very rare cases, when updates comes from outside of isc and meta fields doesn’t exist yet
344 if(empty($isc_post_images)) $isc_post_images = array();
345
346 foreach ($image_ids as $id => $url) {
347 if (is_array($isc_post_images) && !array_key_exists($id, $isc_post_images)) {
348 array_push($added_images, $id);
349 }
350 }
351 if (is_array($isc_post_images)) {
352 foreach ($isc_post_images as $old_id => $value) {
353 // if (!in_array($old_id, $image_ids)) {
354 if (!array_key_exists($old_id, $image_ids)) {
355 array_push($removed_images, $old_id);
356 } else {
357 if (!empty($old_id)) {
358 $meta = get_post_meta($old_id, 'isc_image_posts', true);
359 if (empty($meta)) {
360 update_post_meta($old_id, 'isc_image_posts', array($post_id));
361 } else {
362 // In case the isc_image_posts is not up to date
363 if (is_array($meta) && !in_array($post_id, $meta)) {
364 array_push($meta, $post_id);
365 $meta = array_unique( $meta );
366 update_post_meta($old_id, 'isc_image_posts', $meta);
367 }
368 }
369 }
370 }
371 }
372 }
373
374 foreach ($added_images as $id) {
375 $meta = get_post_meta($id, 'isc_image_posts', true);
376 if (!is_array($meta) || array() == $meta) {
377 update_post_meta($id, 'isc_image_posts', array($post_id));
378 } else {
379 array_push($meta, $post_id);
380 $meta = array_unique( $meta );
381 update_post_meta($id, 'isc_image_posts', $meta);
382 }
383 }
384
385 foreach ($removed_images as $id) {
386 $image_meta = get_post_meta($id, 'isc_image_posts', true);
387 if (is_array($image_meta)) {
388 $offset = array_search($post_id, $image_meta);
389 if (false !== $offset) {
390 array_splice($image_meta, $offset, 1);
391 $image_meta = array_unique( $image_meta );
392 update_post_meta($id, 'isc_image_posts', $image_meta);
393 }
394 }
395 }
396 }
397
398 /**
399 * Returns default options
400 */
401 public function default_options()
402 {
403
404 $licences = "All Rights Reserved
405 Public Domain Mark 1.0|https://creativecommons.org/publicdomain/mark/1.0/
406 CC0 1.0 Universal|https://creativecommons.org/publicdomain/zero/1.0/
407 CC BY 4.0 International|https://creativecommons.org/licenses/by/4.0/
408 CC BY-SA 4.0 International|https://creativecommons.org/licenses/by-sa/4.0/
409 CC BY-ND 4.0 International|https://creativecommons.org/licenses/by-nd/4.0/
410 CC BY-NC 4.0 International|https://creativecommons.org/licenses/by-nc/4.0/
411 CC BY-NC-SA 4.0 International|https://creativecommons.org/licenses/by-nc-sa/4.0/
412 CC BY-NC-ND 4.0 International|https://creativecommons.org/licenses/by-nc-nd/4.0/
413 CC BY 3.0 Unported|https://creativecommons.org/licenses/by/3.0/
414 CC BY-SA 3.0 Unported|https://creativecommons.org/licenses/by-sa/3.0/
415 CC BY-ND 3.0 Unported|https://creativecommons.org/licenses/by-nd/3.0/
416 CC BY-NC 3.0 Unported|https://creativecommons.org/licenses/by-nc/3.0/
417 CC BY-NC-SA 3.0 Unported|https://creativecommons.org/licenses/by-nc-sa/3.0/
418 CC BY-NC-ND 3.0 Unported|https://creativecommons.org/licenses/by-nc-nd/3.0/
419 CC BY 2.5 Generic|https://creativecommons.org/licenses/by/2.5/
420 CC BY-SA 2.5 Generic|https://creativecommons.org/licenses/by-sa/2.5/
421 CC BY-ND 2.5 Generic|https://creativecommons.org/licenses/by-nd/2.5/
422 CC BY-NC 2.5 Generic|https://creativecommons.org/licenses/by-nc/2.5/
423 CC BY-NC-SA 2.5 Generic|https://creativecommons.org/licenses/by-nc-sa/2.5/
424 CC BY-NC-ND 2.5 Generic|https://creativecommons.org/licenses/by-nc-nd/2.5/
425 CC BY 2.0 Generic|https://creativecommons.org/licenses/by/2.0/
426 CC BY-SA 2.0 Generic|https://creativecommons.org/licenses/by-sa/2.0/
427 CC BY-ND 2.0 Generic|https://creativecommons.org/licenses/by-nd/2.0/
428 CC BY-NC 2.0 Generic|https://creativecommons.org/licenses/by-nc/2.0/
429 CC BY-NC-SA 2.0 Generic|https://creativecommons.org/licenses/by-nc-sa/2.0/
430 CC BY-NC-ND 2.0 Generic|https://creativecommons.org/licenses/by-nc-nd/2.0/";
431
432 $default['display_type'] = array('list');
433 $default['list_on_archives'] = false;
434 $default['list_on_excerpts'] = false;
435 $default['image_list_headline'] = __('image sources', 'image-source-control-isc');
436 $default['exclude_own_images'] = false;
437 $default['use_authorname'] = true;
438 $default['by_author_text'] = __('Owned by the author', 'image-source-control-isc');
439 $default['installed'] = false;
440 $default['version'] = ISCVERSION;
441 $default['webgilde'] = false;
442 $default['thumbnail_in_list'] = false;
443 $default['thumbnail_size'] = 'thumbnail';
444 $default['thumbnail_width'] = 150;
445 $default['thumbnail_height'] = 150;
446 $default['warning_nosource'] = true;
447 $default['warning_onesource_missing'] = true;
448 $default['hide_list'] = false;
449 $default['caption_position'] = 'top-left';
450 $default['source_pretext'] = __('Source:', 'image-source-control-isc');
451 $default['enable_licences'] = false;
452 $default['licences'] = apply_filters( 'isc-licences-list', $licences );
453 return $default;
454 }
455
456 /**
457 * Returns isc_options if it exists, returns the default options otherwise.
458 */
459 public function get_isc_options() {
460 return get_option('isc_options', $this->default_options());
461 }
462
463 /**
464 * Add isc_image_posts on all attachments. Launched during first installation.
465 */
466 public function init_image_posts_metafield()
467 {
468 $args = array(
469 'post_type' => 'any',
470 'numberposts' => -1,
471 'post_status' => null,
472 'post_parent' => null,
473 );
474 $posts = get_posts($args);
475 foreach ($posts as $post) {
476 setup_postdata($post);
477 /*$image_urls = $this->_filter_src_attributes($post->post_content);
478 $image_ids = array();
479 foreach ($image_urls as $url) {
480 $image_id = intval($this->get_image_by_url($url));
481 array_push($image_ids,$image_id);
482 }*/
483 $image_ids = $this->_filter_image_ids($post->post_content);
484 foreach ($image_ids as $id) {
485 $meta = get_post_meta($id, 'isc_image_posts', true);
486 if (empty($meta)) {
487 update_post_meta($id, 'isc_image_posts', array($post->ID));
488 } else {
489 if (!in_array($post->ID, $meta)) {
490 array_push($meta, $post->ID);
491 $meta = array_unique( $meta );
492 update_post_meta($id, 'isc_image_posts', $meta);
493 }
494 }
495 }
496 }
497 }
498
499 /**
500 * transform the licenses from the options textfield into an array
501 *
502 * @param string $licences text with licenses
503 * @return array $new_licences array with licenses and license information
504 * @return false if no array created
505 * @since 1.3.5
506 */
507 public function licences_text_to_array($licences = '')
508 {
509 if($licences == '') return false;
510 // split the text by line
511 $licences_array = preg_split('/\r?\n/', trim($licences));
512 if(count($licences_array) == 0 ) return false;
513 // create the array with licence => url
514 $new_licences = array();
515 foreach($licences_array as $_licence) {
516 if(trim($_licence) != '') {
517 $temp = explode('|', $_licence);
518 $new_licences[$temp[0]] = array();
519 if( isset($temp[1]))
520 $new_licences[$temp[0]]['url'] = esc_url ($temp[1]);
521 }
522 }
523
524 if($new_licences == array()) return false;
525 else return $new_licences;
526 }
527 }// end of class
528