Changeset 627803
- Timestamp:
- 11/20/2012 05:35:24 PM (13 years ago)
- Location:
- image-metadata-cruncher
- Files:
-
- 1 added
- 3 edited
-
tags/1.1 (added)
-
trunk/README.txt (modified) (2 diffs)
-
trunk/image-metadata-cruncher.php (modified) (11 diffs)
-
trunk/js/script.js (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
image-metadata-cruncher/trunk/README.txt
r624203 r627803 5 5 Requires at least: 2.7 6 6 Tested up to: 3.4 7 Stable tag: 1. 07 Stable tag: 1.1 8 8 License: GPLv2 or later 9 9 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 38 38 == Changelog == 39 39 40 = 1.1 = 41 * Fixed several bugs 42 * Added an option to disable syntax highlighting of template tags 43 40 44 = 1.0 = 41 45 * Initial version -
image-metadata-cruncher/trunk/image-metadata-cruncher.php
r624533 r627803 3 3 Plugin Name: Image Metadata Cruncher 4 4 Description: Gives you ultimate controll over which image metadata (EXIF or IPTC) WordPress extracts from an uploaded image and where and in what form it then goes. You can even specify unlimited custom post meta tags as the target of the extracted image metadata. 5 Version: 1. 05 Version: 1.1 6 6 Author: Peter Hudec 7 7 Author URI: http://peterhudec.com … … 109 109 110 110 // add custom post meta if any 111 foreach ( $options['custom_meta'] as $key => $value ) { 112 113 // get value 114 $value = $this->render_template( $value ); 115 116 // update or create the post meta 117 add_post_meta( $post_ID, $key, $value, true ) or update_post_meta( $post_ID, $key, $value ); 111 if ( isset( $options['custom_meta'] ) ) { 112 foreach ( $options['custom_meta'] as $key => $value ) { 113 // get value 114 $value = $this->render_template( $value ); 115 116 // update or create the post meta 117 add_post_meta( $post_ID, $key, $value, true ) or update_post_meta( $post_ID, $key, $value ); 118 } 118 119 } 119 120 … … 129 130 private function extract_metadata( $file ) { 130 131 132 $this->metadata = array(); 133 131 134 // extract metadata from file 132 135 // the $meta variable will be populated with it 133 136 $size = getimagesize( $file, $meta ); 134 137 138 if ( $size ) { 139 $this->metadata['Image'] = $size; 140 } 141 135 142 // parse iptc 136 143 // IPTC is stored in the APP13 key of the extracted metadata 137 144 $iptc = iptcparse( $meta['APP13'] ); 138 145 139 // symplify array structure 140 foreach ( $iptc as &$i ) { 141 $i = $i[0]; 142 } 143 144 // add named copies to all found IPTC items 145 foreach ( $iptc as $key => $value ) { 146 if ( isset( $this->IPTC_MAPPING[ $key ] ) ) { 147 $name = $this->IPTC_MAPPING[ $key ]; 148 149 // add "Caption" alias to "Caption-Caption-Abstract" 150 if ( $key == '2#120' ) { 151 $this->insert_next_to_key( $iptc, $key, array( 'Caption' => $value ) ); 146 if ( $iptc ) { 147 // symplify array structure 148 foreach ( $iptc as &$i ) { 149 $i = $i[0]; 150 } 151 152 // add named copies to all found IPTC items 153 foreach ( $iptc as $key => $value ) { 154 if ( isset( $this->IPTC_MAPPING[ $key ] ) ) { 155 $name = $this->IPTC_MAPPING[ $key ]; 156 157 // add "Caption" alias to "Caption-Caption-Abstract" 158 if ( $key == '2#120' ) { 159 $this->insert_next_to_key( $iptc, $key, array( 'Caption' => $value ) ); 160 } 161 162 $this->insert_next_to_key( $iptc, $key, array( $name => $value ) ); 152 163 } 153 154 $this->insert_next_to_key( $iptc, $key, array( $name => $value ) );155 164 } 156 165 } 157 166 158 // parse exif 167 if ( $iptc ) { 168 $this->metadata['IPTC'] = $iptc; 169 } 170 171 // parse exif 172 $exif = NULL; 159 173 160 174 // the exif_read_data() function throws a warning if it is passed an unsupported file format. … … 185 199 } 186 200 } 187 } else { 188 $exif = "File type \"$size[mime]\" doesn't support EXIF metadata!"; 189 } 190 191 // construct the metadata array 192 $this->metadata = array( 193 'Image' => $size, 194 'IPTC' => $iptc, 195 'EXIF' => $exif 196 ); 201 } 202 203 if ( $exif ) { 204 $this->metadata['EXIF'] = $exif; 205 } 197 206 198 207 // no need for return but good for testing … … 225 234 $result = preg_replace_callback( $this->pattern, array( $this, 'parse_tag' ), $template ); 226 235 227 $result = $result ? $result : $template; 236 if ( $result === NULL ) { 237 $result = $template; 238 } 228 239 229 240 // handle escaped curly brackets … … 590 601 'alt' => '', 591 602 'caption' => '', 603 'enable_highlighting' => 'on', 592 604 'description' => '{ IPTC:Caption | EXIF:ImageDescription }', 593 605 'custom_meta' => array() … … 621 633 // Sections 622 634 /////////////////////////////////// 635 $this->section( 0, 'Tag Syntax Highlighting:' ); 623 636 $this->section( 1, 'Media form fields:' ); 624 637 $this->section( 2, 'Custom image meta tags:' ); … … 708 721 add_action( 'admin_print_scripts-' . $page, array( $this, 'js_rangy_core' ) ); 709 722 add_action( 'admin_print_scripts-' . $page, array( $this, 'js_rangy_selectionsaverestore' ) ); 710 add_action( 'admin_print_scripts-' . $page, array( $this, 'js_highlighting' ) );711 723 add_action( 'admin_print_scripts-' . $page, array( $this, 'js' ) ); 712 724 add_action( 'admin_print_styles-' . $page, array( $this, 'css' ) ); … … 745 757 settings_fields( "{$this->prefix}_title" ); // renders hidden input fields 746 758 settings_fields( "{$this->prefix}_alt" ); // renders hidden input fields 759 do_settings_sections( "{$this->prefix}-section-0" ); 747 760 do_settings_sections( "{$this->prefix}-section-1" ); 748 761 do_settings_sections( "{$this->prefix}-section-2" ); … … 764 777 /////////////////////////////////// 765 778 779 public function section_0() { ?> 780 <p> 781 The fancy syntax highlighting of template tags may in some cases cause strange caret/cursor behaviour. 782 If you encounter any of such problems, you can disable this feature here. 783 </p> 784 <?php $options = get_option( $this->prefix ); ?> 785 <input type="checkbox" <?php checked( 'on', $options['enable_highlighting'] ); ?> name="<?php echo $this->prefix; ?>[enable_highlighting]" id="enable-highlighting" /> 786 <label for="highlighting">Enable highlighting</label> 787 <?php } 788 766 789 // media form fields 767 790 public function section_1() { ?> 768 <p>791 <p> 769 792 Specify text templates with which should the media upload form be prepopulated with. 770 793 Use template tags like this <code>{ IPTC:Headline }</code> to place found metadata into the templates. … … 798 821 <th>Delete</th> 799 822 </thead> 800 <?php foreach ( $options['custom_meta'] as $key => $value ): ?> 801 <tr> 802 <td><input type="text" class="name" value="<?php echo $key ?>" /></td> 803 <td> 804 <div class="highlighted ce" contenteditable="true"><?php echo $value ?></div> 805 <?php // used textarea because hidden input caused bugs when whitespace got converted to ?> 806 <textarea class="hidden-input template" name="<?php echo $this->prefix; ?>[custom_meta][<?php echo $key ?>]" ><?php echo $value ?></textarea> 807 </td> 808 <td><button class="button">Remove</button></td> 809 </tr> 810 <?php endforeach; ?> 823 <?php if ( is_array( $options['custom_meta'] ) ): ?> 824 <?php foreach ( $options['custom_meta'] as $key => $value ): ?> 825 <tr> 826 <td><input type="text" class="name" value="<?php echo $key ?>" /></td> 827 <td> 828 <div class="highlighted ce" contenteditable="true"><?php echo $value ?></div> 829 <?php // used textarea because hidden input caused bugs when whitespace got converted to ?> 830 <textarea class="hidden-input template" name="<?php echo $this->prefix; ?>[custom_meta][<?php echo $key ?>]" ><?php echo $value ?></textarea> 831 </td> 832 <td><button class="button">Remove</button></td> 833 </tr> 834 <?php endforeach; ?> 835 <?php endif ?> 811 836 </table> 812 837 <div> -
image-metadata-cruncher/trunk/js/script.js
r624533 r627803 76 76 /////////////////////////////////////////// 77 77 78 // checks whether highlighting is allowed by the user 79 function enableHighlighting(){ 80 // highlighting causes problems only by content editable elements which are only on the settings tab 81 if($('#enable-highlighting').length > 0){ 82 // if there is a checkbox we are on the settings tab 83 return $('#enable-highlighting').prop("checked"); 84 }else{ 85 // allow highlighting 86 return true; 87 } 88 } 89 78 90 // Highlights all elements of class="highlighted" on keyup 79 91 $('#metadata-cruncher').delegate('.highlighted', 'keyup', function(event) { … … 81 93 82 94 // highlight and get non HTML text 83 var text = highlight(event); 95 if(enableHighlighting()){ 96 var text = highlight(event); 97 } 84 98 85 99 // pass the resulting text to the hidden input form field … … 97 111 rangy.addInitListener(function(r){ 98 112 $('#metadata-cruncher .highlighted').keyup(); 113 }); 114 115 // reset highlighted elements 116 $('#metadata-cruncher').delegate('#enable-highlighting', 'change', function(event) { 117 $('#metadata-cruncher .highlighted').each(function(index) { 118 $(this).html($(this).text()); 119 $(this).keyup(); 120 }); 99 121 }); 100 122 … … 182 204 var selection = rangy.saveSelection(); 183 205 184 // replace rangy boundary markers with this unusual unicode character ▨which survives html to text conversion206 // replace rangy boundary markers with this unusual unicode character \u25A8 which survives html to text conversion 185 207 // and save them to a temporary array 186 208 var p = /(<span[\s]*id="selectionBoundary[^<>]*>[^<>]*<\/[\s]*span>)/g; … … 190 212 markers.push(match); 191 213 // ...and replace with identifier 192 return ' ▨';214 return '\u25A8'; 193 215 }); 194 216 // put it back to input … … 199 221 200 222 // restore rangy identifiers 201 newHTML = newHTML.replace(' ▨', function(match){223 newHTML = newHTML.replace('\u25A8', function(match){ 202 224 // retrieve from temp storage 203 225 return markers.shift(); … … 218 240 219 241 // matches sequence of word characters including period "." and hash "#" 220 // with min lenght of 1 and proper handling of " ▨" cursor character221 var prefixPattern = /(?:[\w.# ▨]{2,}|[^▨\s]{1})/.source;242 // with min lenght of 1 and proper handling of "\u25A8" cursor character 243 var prefixPattern = /(?:[\w.#\u25A8]{2,}|[^\u25A8\s]{1})/.source; 222 244 223 245 // matches sequence of word characters including period ".", hash "#" and colon ":" 224 // with min lenght of 1 and proper handling of " ▨" cursor character225 var keywordPartPattern = /(?:[\w.:# ▨\-]{2,}|[^▨\s]{1})/.source;246 // with min lenght of 1 and proper handling of "\u25A8" cursor character 247 var keywordPartPattern = /(?:[\w.:#\u25A8\-]{2,}|[^\u25A8\s]{1})/.source; 226 248 227 249 // matches keyword in form of "abc:def(>ijk)*" … … 240 262 keywordPattern, // must begin with at least one keyword 241 263 '(?:', // followed by zero or more groups of ( | keyword) 242 '[\\s ▨]*', // optional space264 '[\\s\u25A8]*', // optional space 243 265 '\\|', // must begin with pipe 244 '[\\s ▨]*', // optional space266 '[\\s\u25A8]*', // optional space 245 267 keywordPattern, // keyword 246 268 ')*' … … 261 283 '[^"]', // any non doublequote character... 262 284 '|', // or... 263 '\\\\ ▨?"', // escaped doublequote with optional cursor identifier285 '\\\\\u25A8?"', // escaped doublequote with optional cursor identifier 264 286 ')*', // zero or more times 265 287 '"', // must end with doublequote … … 273 295 '({)', // (1) opening bracket 274 296 275 '([\\s ▨]*)', // (2) space1297 '([\\s\u25A8]*)', // (2) space1 276 298 277 299 '(', // (3) keywords … … 279 301 ')', 280 302 281 '([\\s ▨]*)', // (4) space2303 '([\\s\u25A8]*)', // (4) space2 282 304 283 305 '(?:', // begin success group 284 '(@[\\s ▨]*)', // (5) success identifier "@"306 '(@[\\s\u25A8]*)', // (5) success identifier "@" 285 307 quotesPattern, // (6) success value 286 308 ')?', // end success group 287 309 288 '([\\s ▨]*)', // (7) space3310 '([\\s\u25A8]*)', // (7) space3 289 311 290 312 '(?:', // begin default group 291 '(%[\\s ▨]*)', // (8) default identifier "?"313 '(%[\\s\u25A8]*)', // (8) default identifier "?" 292 314 quotesPattern, // (9) default value 293 315 ')?', // end default group 294 316 295 '([\\s ▨]*)', // (10) space4317 '([\\s\u25A8]*)', // (10) space4 296 318 297 319 '(?:', // begin delimiter group 298 '(#[\\s ▨]*)', // (11) delimiter identifier ":"320 '(#[\\s\u25A8]*)', // (11) delimiter identifier ":" 299 321 quotesPattern, // (12) delimiter value 300 322 ')?', // end delimiter group 301 323 302 '([\\s ▨]*)', // (13) space5324 '([\\s\u25A8]*)', // (13) space5 303 325 304 326 '(})' // (14) closing bracket … … 359 381 var p = re( 360 382 '(', // must be preceded with 361 '[^\\\\ ▨]', // one non-backslash, non-cursor character383 '[^\\\\\u25A8]', // one non-backslash, non-cursor character 362 384 '|', // or 363 '[^\\\\] ▨', // non-backslash followed by cursor385 '[^\\\\]\u25A8', // non-backslash followed by cursor 364 386 ')', 365 387 '(\\$)' // dolar … … 380 402 '([^|\\s]+)', // key 381 403 ')?', 382 '([\\s ▨]*\\|)?' // pipe404 '([\\s\u25A8]*\\|)?' // pipe 383 405 ); 384 406
Note: See TracChangeset
for help on using the changeset viewer.