1<?php 2/** 3 * All output and handler function needed for the media management popup 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9if(!defined('DOKU_INC')) die('meh.'); 10if(!defined('NL')) define('NL',"\n"); 11 12/** 13 * Lists pages which currently use a media file selected for deletion 14 * 15 * References uses the same visual as search results and share 16 * their CSS tags except pagenames won't be links. 17 * 18 * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 19 */ 20function media_filesinuse($data,$id){ 21 global $lang; 22 echo '<h1>'.$lang['reference'].' <code>'.hsc(noNS($id)).'</code></h1>'; 23 echo '<p>'.hsc($lang['ref_inuse']).'</p>'; 24 25 $hidden=0; //count of hits without read permission 26 foreach($data as $row){ 27 if(auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)){ 28 echo '<div class="search_result">'; 29 echo '<span class="mediaref_ref">'.hsc($row).'</span>'; 30 echo '</div>'; 31 }else 32 $hidden++; 33 } 34 if ($hidden){ 35 print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>'; 36 } 37} 38 39/** 40 * Handles the saving of image meta data 41 * 42 * @author Andreas Gohr <andi@splitbrain.org> 43 * @author Kate Arzamastseva <pshns@ukr.net> 44 */ 45function media_metasave($id,$auth,$data){ 46 if($auth < AUTH_UPLOAD) return false; 47 if(!checkSecurityToken()) return false; 48 global $lang; 49 global $conf; 50 $src = mediaFN($id); 51 52 $meta = new JpegMeta($src); 53 $meta->_parseAll(); 54 55 foreach($data as $key => $val){ 56 $val=trim($val); 57 if(empty($val)){ 58 $meta->deleteField($key); 59 }else{ 60 $meta->setField($key,$val); 61 } 62 } 63 64 $old = @filemtime($src); 65 if(!@file_exists(mediaFN($id, $old)) && @file_exists($src)) { 66 // add old revision to the attic 67 media_saveOldRevision($id); 68 } 69 70 if($meta->save()){ 71 if($conf['fperm']) chmod($src, $conf['fperm']); 72 73 $new = @filemtime($src); 74 // add a log entry to the media changelog 75 addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited']); 76 77 msg($lang['metasaveok'],1); 78 return $id; 79 }else{ 80 msg($lang['metasaveerr'],-1); 81 return false; 82 } 83} 84 85/** 86 * Display the form to edit image meta data 87 * 88 * @author Andreas Gohr <andi@splitbrain.org> 89 * @author Kate Arzamastseva <pshns@ukr.net> 90 */ 91function media_metaform($id,$auth){ 92 global $lang, $config_cascade; 93 94 if($auth < AUTH_UPLOAD) { 95 echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL; 96 return false; 97 } 98 99 // load the field descriptions 100 static $fields = null; 101 if(is_null($fields)){ 102 $config_files = getConfigFiles('mediameta'); 103 foreach ($config_files as $config_file) { 104 if(@file_exists($config_file)) include($config_file); 105 } 106 } 107 108 $src = mediaFN($id); 109 110 // output 111 $action = media_managerURL(array('tab_details' => 'view')); 112 echo '<form action="'.$action.'" id="mediamanager__save_meta" accept-charset="utf-8" method="post" class="meta">'.NL; 113 114 formSecurityToken(); 115 foreach($fields as $key => $field){ 116 // get current value 117 if (empty($field[0])) continue; 118 $tags = array($field[0]); 119 if(is_array($field[3])) $tags = array_merge($tags,$field[3]); 120 $value = tpl_img_getTag($tags,'',$src); 121 $value = cleanText($value); 122 123 // prepare attributes 124 $p = array(); 125 $p['class'] = 'edit'; 126 $p['id'] = 'meta__'.$key; 127 $p['name'] = 'meta['.$field[0].']'; 128 129 // put label 130 echo '<div class="metafield">'; 131 echo '<label for="meta__'.$key.'">'; 132 echo ($lang[$field[1]]) ? $lang[$field[1]] : $field[1]; 133 echo ':</label>'; 134 135 // put input field 136 if($field[2] == 'text'){ 137 $p['value'] = $value; 138 $p['type'] = 'text'; 139 $att = buildAttributes($p); 140 echo "<input $att/>".NL; 141 }else{ 142 $att = buildAttributes($p); 143 echo "<textarea $att rows=\"6\" cols=\"50\">".formText($value).'</textarea>'.NL; 144 } 145 echo '</div>'.NL; 146 } 147 echo '<div class="buttons">'.NL; 148 echo '<input type="hidden" name="img" value="'.hsc($id).'" />'.NL; 149 echo '<input type="hidden" name="mediado" value="save" />'; 150 151 $do = 'mediado'; 152 echo '<input name="'.$do.'[save]" type="submit" value="'.$lang['btn_save']. 153 '" title="'.$lang['btn_save'].' [S]" accesskey="s" class="button" />'.NL; 154 echo '</div>'.NL; 155 echo '</form>'.NL; 156} 157 158/** 159 * Convenience function to check if a media file is still in use 160 * 161 * @author Michael Klier <chi@chimeric.de> 162 */ 163function media_inuse($id) { 164 global $conf; 165 $mediareferences = array(); 166 if($conf['refcheck']){ 167 $mediareferences = ft_mediause($id,$conf['refshow']); 168 if(!count($mediareferences)) { 169 return false; 170 } else { 171 return $mediareferences; 172 } 173 } else { 174 return false; 175 } 176} 177 178define('DOKU_MEDIA_DELETED', 1); 179define('DOKU_MEDIA_NOT_AUTH', 2); 180define('DOKU_MEDIA_INUSE', 4); 181define('DOKU_MEDIA_EMPTY_NS', 8); 182 183/** 184 * Handles media file deletions 185 * 186 * If configured, checks for media references before deletion 187 * 188 * @author Andreas Gohr <andi@splitbrain.org> 189 * @return int One of: 0, 190 DOKU_MEDIA_DELETED, 191 DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS, 192 DOKU_MEDIA_NOT_AUTH, 193 DOKU_MEDIA_INUSE 194 */ 195function media_delete($id,$auth){ 196 global $lang; 197 if($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; 198 if(media_inuse($id)) return DOKU_MEDIA_INUSE; 199 200 $file = mediaFN($id); 201 202 // trigger an event - MEDIA_DELETE_FILE 203 $data['id'] = $id; 204 $data['name'] = basename($file); 205 $data['path'] = $file; 206 $data['size'] = (@file_exists($file)) ? filesize($file) : 0; 207 208 $data['unl'] = false; 209 $data['del'] = false; 210 $evt = new Doku_Event('MEDIA_DELETE_FILE',$data); 211 if ($evt->advise_before()) { 212 $old = @filemtime($file); 213 if(!@file_exists(mediaFN($id, $old)) && @file_exists($file)) { 214 // add old revision to the attic 215 media_saveOldRevision($id); 216 } 217 218 $data['unl'] = @unlink($file); 219 if($data['unl']){ 220 addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted']); 221 $data['del'] = io_sweepNS($id,'mediadir'); 222 } 223 } 224 $evt->advise_after(); 225 unset($evt); 226 227 if($data['unl'] && $data['del']){ 228 return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS; 229 } 230 231 return $data['unl'] ? DOKU_MEDIA_DELETED : 0; 232} 233 234/** 235 * Handle file uploads via XMLHttpRequest 236 * 237 * @return mixed false on error, id of the new file on success 238 */ 239function media_upload_xhr($ns,$auth){ 240 if(!checkSecurityToken()) return false; 241 242 $id = $_GET['qqfile']; 243 list($ext,$mime,$dl) = mimetype($id); 244 $input = fopen("php://input", "r"); 245 $temp = tmpfile(); 246 $realSize = stream_copy_to_stream($input, $temp); 247 fclose($input); 248 if ($realSize != (int)$_SERVER["CONTENT_LENGTH"]) return false; 249 if (!($tmp = io_mktmpdir())) return false; 250 $path = $tmp.'/'.md5($id); 251 $target = fopen($path, "w"); 252 fseek($temp, 0, SEEK_SET); 253 stream_copy_to_stream($temp, $target); 254 fclose($target); 255 $res = media_save( 256 array('name' => $path, 257 'mime' => $mime, 258 'ext' => $ext), 259 $ns.':'.$id, 260 (($_REQUEST['ow'] == 'checked') ? true : false), 261 $auth, 262 'copy' 263 ); 264 unlink($path); 265 if ($tmp) dir_delete($tmp); 266 if (is_array($res)) { 267 msg($res[0], $res[1]); 268 return false; 269 } 270 return $res; 271} 272 273/** 274 * Handles media file uploads 275 * 276 * @author Andreas Gohr <andi@splitbrain.org> 277 * @author Michael Klier <chi@chimeric.de> 278 * @return mixed false on error, id of the new file on success 279 */ 280function media_upload($ns,$auth,$file=false){ 281 if(!checkSecurityToken()) return false; 282 global $lang; 283 284 // get file and id 285 $id = $_POST['mediaid']; 286 if (!$file) $file = $_FILES['upload']; 287 if(empty($id)) $id = $file['name']; 288 289 // check for errors (messages are done in lib/exe/mediamanager.php) 290 if($file['error']) return false; 291 292 // check extensions 293 list($fext,$fmime,$dl) = mimetype($file['name']); 294 list($iext,$imime,$dl) = mimetype($id); 295 if($fext && !$iext){ 296 // no extension specified in id - read original one 297 $id .= '.'.$fext; 298 $imime = $fmime; 299 }elseif($fext && $fext != $iext){ 300 // extension was changed, print warning 301 msg(sprintf($lang['mediaextchange'],$fext,$iext)); 302 } 303 304 $res = media_save(array('name' => $file['tmp_name'], 305 'mime' => $imime, 306 'ext' => $iext), $ns.':'.$id, 307 $_REQUEST['ow'], $auth, 'move_uploaded_file'); 308 if (is_array($res)) { 309 msg($res[0], $res[1]); 310 return false; 311 } 312 return $res; 313} 314 315/** 316 * This generates an action event and delegates to _media_upload_action(). 317 * Action plugins are allowed to pre/postprocess the uploaded file. 318 * (The triggered event is preventable.) 319 * 320 * Event data: 321 * $data[0] fn_tmp: the temporary file name (read from $_FILES) 322 * $data[1] fn: the file name of the uploaded file 323 * $data[2] id: the future directory id of the uploaded file 324 * $data[3] imime: the mimetype of the uploaded file 325 * $data[4] overwrite: if an existing file is going to be overwritten 326 * 327 * @triggers MEDIA_UPLOAD_FINISH 328 */ 329function media_save($file, $id, $ow, $auth, $move) { 330 if($auth < AUTH_UPLOAD) { 331 return array("You don't have permissions to upload files.", -1); 332 } 333 334 if (!isset($file['mime']) || !isset($file['ext'])) { 335 list($ext, $mime) = mimetype($id); 336 if (!isset($file['mime'])) { 337 $file['mime'] = $mime; 338 } 339 if (!isset($file['ext'])) { 340 $file['ext'] = $ext; 341 } 342 } 343 344 global $lang, $conf; 345 346 // get filename 347 $id = cleanID($id,false,true); 348 $fn = mediaFN($id); 349 350 // get filetype regexp 351 $types = array_keys(getMimeTypes()); 352 $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types); 353 $regex = join('|',$types); 354 355 // because a temp file was created already 356 if(!preg_match('/\.('.$regex.')$/i',$fn)) { 357 return array($lang['uploadwrong'],-1); 358 } 359 360 //check for overwrite 361 $overwrite = @file_exists($fn); 362 $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 363 if($overwrite && (!$ow || $auth < $auth_ow)) { 364 return array($lang['uploadexist'], 0); 365 } 366 // check for valid content 367 $ok = media_contentcheck($file['name'], $file['mime']); 368 if($ok == -1){ 369 return array(sprintf($lang['uploadbadcontent'],'.' . $file['ext']),-1); 370 }elseif($ok == -2){ 371 return array($lang['uploadspam'],-1); 372 }elseif($ok == -3){ 373 return array($lang['uploadxss'],-1); 374 } 375 376 // prepare event data 377 $data[0] = $file['name']; 378 $data[1] = $fn; 379 $data[2] = $id; 380 $data[3] = $file['mime']; 381 $data[4] = $overwrite; 382 $data[5] = $move; 383 384 // trigger event 385 return trigger_event('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); 386} 387 388/** 389 * Callback adapter for media_upload_finish() 390 * @author Michael Klier <chi@chimeric.de> 391 */ 392function _media_upload_action($data) { 393 // fixme do further sanity tests of given data? 394 if(is_array($data) && count($data)===6) { 395 return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 396 } else { 397 return false; //callback error 398 } 399} 400 401/** 402 * Saves an uploaded media file 403 * 404 * @author Andreas Gohr <andi@splitbrain.org> 405 * @author Michael Klier <chi@chimeric.de> 406 * @author Kate Arzamastseva <pshns@ukr.net> 407 */ 408function media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') { 409 global $conf; 410 global $lang; 411 global $REV; 412 413 $old = @filemtime($fn); 414 if(!@file_exists(mediaFN($id, $old)) && @file_exists($fn)) { 415 // add old revision to the attic if missing 416 media_saveOldRevision($id); 417 } 418 419 // prepare directory 420 io_createNamespace($id, 'media'); 421 422 if($move($fn_tmp, $fn)) { 423 @clearstatcache(true,$fn); 424 $new = @filemtime($fn); 425 // Set the correct permission here. 426 // Always chmod media because they may be saved with different permissions than expected from the php umask. 427 // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 428 chmod($fn, $conf['fmode']); 429 msg($lang['uploadsucc'],1); 430 media_notify($id,$fn,$imime,$old); 431 // add a log entry to the media changelog 432 if ($REV){ 433 addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_REVERT, $lang['restored'], $REV); 434 } elseif ($overwrite) { 435 addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT); 436 } else { 437 addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created']); 438 } 439 return $id; 440 }else{ 441 return array($lang['uploadfail'],-1); 442 } 443} 444 445/** 446 * Moves the current version of media file to the media_attic 447 * directory 448 * 449 * @author Kate Arzamastseva <pshns@ukr.net> 450 * @param string $id 451 * @return int - revision date 452 */ 453function media_saveOldRevision($id){ 454 global $conf, $lang; 455 456 $oldf = mediaFN($id); 457 if(!@file_exists($oldf)) return ''; 458 $date = filemtime($oldf); 459 if (!$conf['mediarevisions']) return $date; 460 461 if (!getRevisionInfo($id, $date, 8192, true)) { 462 // there was an external edit, 463 // there is no log entry for current version of file 464 if (!@file_exists(mediaMetaFN($id,'.changes'))) { 465 addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created']); 466 } else { 467 addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT); 468 } 469 } 470 471 $newf = mediaFN($id,$date); 472 io_makeFileDir($newf); 473 if(copy($oldf, $newf)) { 474 // Set the correct permission here. 475 // Always chmod media because they may be saved with different permissions than expected from the php umask. 476 // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 477 chmod($newf, $conf['fmode']); 478 } 479 return $date; 480} 481 482/** 483 * This function checks if the uploaded content is really what the 484 * mimetype says it is. We also do spam checking for text types here. 485 * 486 * We need to do this stuff because we can not rely on the browser 487 * to do this check correctly. Yes, IE is broken as usual. 488 * 489 * @author Andreas Gohr <andi@splitbrain.org> 490 * @link http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting 491 * @fixme check all 26 magic IE filetypes here? 492 */ 493function media_contentcheck($file,$mime){ 494 global $conf; 495 if($conf['iexssprotect']){ 496 $fh = @fopen($file, 'rb'); 497 if($fh){ 498 $bytes = fread($fh, 256); 499 fclose($fh); 500 if(preg_match('/<(script|a|img|html|body|iframe)[\s>]/i',$bytes)){ 501 return -3; 502 } 503 } 504 } 505 if(substr($mime,0,6) == 'image/'){ 506 $info = @getimagesize($file); 507 if($mime == 'image/gif' && $info[2] != 1){ 508 return -1; 509 }elseif($mime == 'image/jpeg' && $info[2] != 2){ 510 return -1; 511 }elseif($mime == 'image/png' && $info[2] != 3){ 512 return -1; 513 } 514 # fixme maybe check other images types as well 515 }elseif(substr($mime,0,5) == 'text/'){ 516 global $TEXT; 517 $TEXT = io_readFile($file); 518 if(checkwordblock()){ 519 return -2; 520 } 521 } 522 return 0; 523} 524 525/** 526 * Send a notify mail on uploads 527 * 528 * @author Andreas Gohr <andi@splitbrain.org> 529 */ 530function media_notify($id,$file,$mime,$old_rev=false){ 531 global $lang; 532 global $conf; 533 global $INFO; 534 if(empty($conf['notify'])) return; //notify enabled? 535 536 $ip = clientIP(); 537 538 $text = rawLocale('uploadmail'); 539 $text = str_replace('@DATE@',dformat(),$text); 540 $text = str_replace('@BROWSER@',$_SERVER['HTTP_USER_AGENT'],$text); 541 $text = str_replace('@IPADDRESS@',$ip,$text); 542 $text = str_replace('@HOSTNAME@',gethostsbyaddrs($ip),$text); 543 $text = str_replace('@DOKUWIKIURL@',DOKU_URL,$text); 544 $text = str_replace('@USER@',$_SERVER['REMOTE_USER'],$text); 545 $text = str_replace('@MIME@',$mime,$text); 546 $text = str_replace('@MEDIA@',ml($id,'',true,'&',true),$text); 547 $text = str_replace('@SIZE@',filesize_h(filesize($file)),$text); 548 if ($old_rev && $conf['mediarevisions']) { 549 $text = str_replace('@OLD@', ml($id, "rev=$old_rev", true, '&', true), $text); 550 } else { 551 $text = str_replace('@OLD@', '', $text); 552 } 553 554 if(empty($conf['mailprefix'])) { 555 $subject = '['.$conf['title'].'] '.$lang['mail_upload'].' '.$id; 556 } else { 557 $subject = '['.$conf['mailprefix'].'] '.$lang['mail_upload'].' '.$id; 558 } 559 560 mail_send($conf['notify'],$subject,$text,$conf['mailfrom']); 561} 562 563/** 564 * List all files in a given Media namespace 565 */ 566function media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=false){ 567 global $conf; 568 global $lang; 569 $ns = cleanID($ns); 570 571 // check auth our self if not given (needed for ajax calls) 572 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 573 574 if (!$fullscreenview) echo '<h1 id="media__ns">:'.hsc($ns).'</h1>'.NL; 575 576 if($auth < AUTH_READ){ 577 // FIXME: print permission warning here instead? 578 echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 579 }else{ 580 if (!$fullscreenview) media_uploadform($ns, $auth); 581 582 $dir = utf8_encodeFN(str_replace(':','/',$ns)); 583 $data = array(); 584 search($data,$conf['mediadir'],'search_media', 585 array('showmsg'=>true,'depth'=>1),$dir,1,$sort); 586 587 if(!count($data)){ 588 echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 589 }else { 590 if ($fullscreenview) { 591 $view = $_REQUEST['view']; 592 if ($view == 'list') { 593 echo '<ul class="mediamanager-list" id="mediamanager__file_list">'; 594 } else { 595 echo '<ul class="mediamanager-thumbs" id="mediamanager__file_list">'; 596 } 597 } 598 foreach($data as $item){ 599 if (!$fullscreenview) { 600 media_printfile($item,$auth,$jump); 601 } else { 602 media_printfile_thumbs($item,$auth,$jump); 603 } 604 } 605 if ($fullscreenview) echo '</ul>'; 606 } 607 } 608 if (!$fullscreenview) media_searchform($ns); 609} 610 611/** 612 * Prints mediamanager tab 613 * 614 * @author Kate Arzamastseva <pshns@ukr.net> 615 * @param string $link - tab href 616 * @param string $class - tab css class 617 * @param string $name - tab caption 618 * @param boolean $selected - is tab selected 619 */ 620function media_tab($link, $class, $name, $selected=false) { 621 if ($selected) $class .= ' selected'; 622 $tab = '<a href="'.$link.'" class="'.$class.'" >'.$name.'</a>'; 623 echo $tab; 624} 625 626/** 627 * Prints tabs for files list actions 628 * 629 * @author Kate Arzamastseva <pshns@ukr.net> 630 * @param string $selected_tab - opened tab 631 */ 632function media_tabs_files($selected_tab = ''){ 633 global $lang; 634 635 echo '<div class="mediamanager-tabs" id="mediamanager__tabs_files">'; 636 637 media_tab(media_managerURL(array('tab_files' => 'files')), 638 'files', $lang['mediaselect'], ($selected_tab == 'files')); 639 media_tab(media_managerURL(array('tab_files' => 'upload')), 640 'upload', $lang['media_uploadtab'], ($selected_tab == 'upload')); 641 media_tab(media_managerURL(array('tab_files' => 'search')), 642 'search', $lang['media_searchtab'], ($selected_tab == 'search')); 643 644 echo '<div class="clearer"></div>'; 645 echo '</div>'; 646} 647 648/** 649 * Prints tabs for files details actions 650 * 651 * @author Kate Arzamastseva <pshns@ukr.net> 652 * @param string $selected_tab - opened tab 653 */ 654function media_tabs_details($image, $selected_tab = ''){ 655 global $lang, $conf; 656 657 echo '<div class="mediamanager-tabs" id="mediamanager__tabs_details">'; 658 659 media_tab(media_managerURL(array('tab_details' => 'view')), 660 'view', $lang['media_viewtab'], ($selected_tab == 'view')); 661 662 list($ext, $mime) = mimetype($image); 663 if ($mime == 'image/jpeg' && @file_exists(mediaFN($image))) { 664 media_tab(media_managerURL(array('tab_details' => 'edit')), 665 'edit', $lang['media_edittab'], ($selected_tab == 'edit')); 666 } 667 if ($conf['mediarevisions']) { 668 media_tab(media_managerURL(array('tab_details' => 'history')), 669 'history', $lang['media_historytab'], ($selected_tab == 'history')); 670 } 671 672 echo '<div class="clearer"></div>'; 673 echo '</div>'; 674} 675 676/** 677 * Prints options for the tab that displays a list of all files 678 * 679 * @author Kate Arzamastseva <pshns@ukr.net> 680 */ 681function media_tab_files_options($ns, $sort){ 682 global $lang; 683 684 echo '<div class="background-container">'; 685 686 echo '<strong class="namespace">'; 687 echo $ns ? $ns : '['.$lang['mediaroot'].']'; 688 echo '</strong>'; 689 690 echo '<div id="mediamanager__tabs_list">'; 691 692 echo '<a href="'.media_managerURL(array('view' => 'thumbs')).'" id="mediamanager__link_thumbs" >'; 693 echo $lang['media_thumbsview']; 694 echo '</a>'; 695 696 echo '<a href="'.media_managerURL(array('view' => 'list')).'" id="mediamanager__link_list" >'; 697 echo $lang['media_listview']; 698 echo '</a>'; 699 700 echo '</div>'; 701 702 echo '<div id="mediamanager__sort">'; 703 $form = new Doku_Form(array('action'=>media_managerURL(array(), '&'), 'id' => 'mediamanager__form_sort')); 704 $form->addElement(form_makeListboxField( 705 'sort', 706 array( 707 'name' => $lang['media_sort_name'], 708 'date' => $lang['media_sort_date']), 709 $sort, 710 $lang['media_sort'])); 711 $form->addElement(form_makeButton('submit', '', $lang['btn_apply'])); 712 $form->printForm(); 713 echo '</div>'; 714 715 echo '<div class="clearer"></div>'; 716 echo '</div>'; 717} 718 719/** 720 * Returns type of sorting for the list of files in media manager 721 * 722 * @author Kate Arzamastseva <pshns@ukr.net> 723 * @return string - sort type 724 */ 725function _media_get_sort_type() { 726 $sort = $_REQUEST['sort']; 727 if (!$sort && (strpos($_COOKIE['DOKU_PREFS'], 'sort') >= 0)) { 728 $parts = explode('#', $_COOKIE['DOKU_PREFS']); 729 for ($i = 0; $i < count($parts); $i+=2){ 730 if ($parts[$i] == 'sort') $sort = $parts[$i+1]; 731 } 732 } 733 return $sort; 734} 735 736/** 737 * Prints tab that displays a list of all files 738 * 739 * @author Kate Arzamastseva <pshns@ukr.net> 740 */ 741function media_tab_files($ns,$auth=null,$jump='') { 742 global $lang; 743 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 744 745 $sort = _media_get_sort_type(); 746 media_tab_files_options($ns, $sort); 747 748 echo '<div class="scroll-container" >'; 749 if($auth < AUTH_READ){ 750 echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 751 }else{ 752 media_filelist($ns,$auth,$jump,true,$sort); 753 } 754 echo '</div>'; 755} 756 757/** 758 * Prints tab that displays uploading form 759 * 760 * @author Kate Arzamastseva <pshns@ukr.net> 761 */ 762function media_tab_upload($ns,$auth=null,$jump='') { 763 global $lang; 764 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 765 766 echo '<div class="background-container">'; 767 echo sprintf($lang['media_upload'], $ns ? $ns : '['.$lang['mediaroot'].']'); 768 echo '</div>'; 769 770 echo '<div class="scroll-container">'; 771 if ($auth >= AUTH_UPLOAD) echo '<div class="upload">' . $lang['mediaupload'] . '</div>'; 772 media_uploadform($ns, $auth, true); 773 echo '</div>'; 774} 775 776/** 777 * Prints tab that displays search form 778 * 779 * @author Kate Arzamastseva <pshns@ukr.net> 780 */ 781function media_tab_search($ns,$auth=null) { 782 global $lang; 783 784 $do = $_REQUEST['mediado']; 785 $query = $_REQUEST['q']; 786 if (!$query) $query = ''; 787 788 $sort = _media_get_sort_type(); 789 media_tab_files_options($ns, $sort); 790 791 echo '<div class="scroll-container">'; 792 media_searchform($ns, $query, true); 793 if ($do == 'searchlist') media_searchlist($query,$ns,$auth,true,$sort); 794 echo '</div>'; 795} 796 797/** 798 * Prints tab that displays mediafile details 799 * 800 * @author Kate Arzamastseva <pshns@ukr.net> 801 */ 802function media_tab_view($image, $ns, $auth=null, $rev=false) { 803 global $lang, $conf; 804 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 805 806 echo '<div class="background-container">'; 807 list($ext,$mime,$dl) = mimetype($image,false); 808 $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext); 809 $class = 'select mediafile mf_'.$class; 810 echo '<span class="'.$class.'" >'.$image.'</span>'; 811 echo '</div>'; 812 813 echo '<div class="scroll-container">'; 814 if ($image && $auth >= AUTH_READ) { 815 $meta = new JpegMeta(mediaFN($image, $rev)); 816 media_preview($image, $auth, $rev, $meta); 817 media_preview_buttons($image, $auth, $rev); 818 media_details($image, $auth, $rev, $meta); 819 820 } else { 821 echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'; 822 } 823 echo '</div>'; 824} 825 826/** 827 * Prints tab that displays form for editing mediafile metadata 828 * 829 * @author Kate Arzamastseva <pshns@ukr.net> 830 */ 831function media_tab_edit($image, $ns, $auth=null) { 832 global $lang; 833 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 834 835 echo '<div class="background-container">'; 836 echo $lang['media_edit']; 837 echo '</div>'; 838 839 echo '<div class="scroll-container">'; 840 if ($image) { 841 list($ext, $mime) = mimetype($image); 842 if ($mime == 'image/jpeg') media_metaform($image,$auth); 843 } 844 echo '</div>'; 845} 846 847/** 848 * Prints tab that displays mediafile revisions 849 * 850 * @author Kate Arzamastseva <pshns@ukr.net> 851 */ 852function media_tab_history($image, $ns, $auth=null) { 853 global $lang; 854 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 855 $do = $_REQUEST['mediado']; 856 857 echo '<div class="background-container">'; 858 echo $lang['media_history']; 859 echo '</div>'; 860 861 echo '<div class="scroll-container">'; 862 if ($auth >= AUTH_READ && $image) { 863 if ($do == 'diff'){ 864 media_diff($image, $ns, $auth); 865 } else { 866 $first = isset($_REQUEST['first']) ? intval($_REQUEST['first']) : 0; 867 html_revisions($first, $image); 868 } 869 } else { 870 echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 871 } 872 echo '</div>'; 873} 874 875/** 876 * Prints mediafile details 877 * 878 * @author Kate Arzamastseva <pshns@ukr.net> 879 */ 880function media_preview($image, $auth, $rev=false, $meta=false) { 881 global $lang; 882 883 echo '<div class="mediamanager__preview">'; 884 885 $size = media_image_preview_size($image, $rev, $meta); 886 887 if ($size) { 888 $more = array(); 889 if ($rev) { 890 $more['rev'] = $rev; 891 } else { 892 $t = @filemtime(mediaFN($image)); 893 $more['t'] = $t; 894 } 895 896 $more['w'] = $size[0]; 897 $more['h'] = $size[1]; 898 $src = ml($image, $more); 899 echo '<img src="'.$src.'" alt="'.$image.'" style="max-width: '.$size[0].'px;" />'; 900 } 901 902 echo '</div>'; 903} 904 905/** 906 * Prints mediafile action buttons 907 * 908 * @author Kate Arzamastseva <pshns@ukr.net> 909 */ 910function media_preview_buttons($image, $auth, $rev=false) { 911 global $lang, $conf; 912 913 echo '<div class="mediamanager__preview_buttons">'; 914 915 $more = ''; 916 if ($rev) { 917 $more = "rev=$rev"; 918 } else { 919 $t = @filemtime(mediaFN($image)); 920 $more = "t=$t"; 921 } 922 $link = ml($image,$more,true,'&'); 923 924 if (@file_exists(mediaFN($image, $rev))) { 925 926 // view original file button 927 $form = new Doku_Form(array('action'=>$link, 'target'=>'_blank')); 928 $form->addElement(form_makeButton('submit','',$lang['mediaview'])); 929 $form->printForm(); 930 } 931 932 if($auth >= AUTH_DELETE && !$rev && @file_exists(mediaFN($image))){ 933 934 // delete button 935 $form = new Doku_Form(array('id' => 'mediamanager__btn_delete', 936 'action'=>media_managerURL(array('delete' => $image), '&'))); 937 $form->addElement(form_makeButton('submit','',$lang['btn_delete'])); 938 $form->printForm(); 939 940 } 941 942 $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 943 if($auth >= $auth_ow && !$rev){ 944 945 // upload new version button 946 $form = new Doku_Form(array('id' => 'mediamanager__btn_update', 947 'action'=>media_managerURL(array('image' => $image, 'mediado' => 'update'), '&'))); 948 $form->addElement(form_makeButton('submit','',$lang['media_update'])); 949 $form->printForm(); 950 } 951 952 if($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && @file_exists(mediaFN($image, $rev))){ 953 954 // restore button 955 $form = new Doku_Form(array('id' => 'mediamanager__btn_restore', 956 'action'=>media_managerURL(array('image' => $image), '&'))); 957 $form->addHidden('mediado','restore'); 958 $form->addHidden('rev',$rev); 959 $form->addElement(form_makeButton('submit','',$lang['media_restore'])); 960 $form->printForm(); 961 } 962 963 echo '</div>'; 964} 965 966/** 967 * Returns image width and height for mediamanager preview panel 968 * 969 * @author Kate Arzamastseva <pshns@ukr.net> 970 * @param string $image 971 * @param int $rev 972 * @param JpegMeta $meta 973 * @return array 974 */ 975function media_image_preview_size($image, $rev, $meta, $size = 500) { 976 if (!preg_match("/\.(jpe?g|gif|png)$/", $image) || !file_exists(mediaFN($image, $rev))) return false; 977 978 $info = getimagesize(mediaFN($image, $rev)); 979 $w = (int) $info[0]; 980 $h = (int) $info[1]; 981 982 if($meta && ($w > $size || $h > $size)){ 983 $ratio = $meta->getResizeRatio($size, $size); 984 $w = floor($w * $ratio); 985 $h = floor($h * $ratio); 986 } 987 return array($w, $h); 988} 989 990/** 991 * Returns the requested EXIF/IPTC tag from the image meta 992 * 993 * @author Kate Arzamastseva <pshns@ukr.net> 994 * @param array $tags 995 * @param JpegMeta $meta 996 * @param string $alt 997 * @return string 998 */ 999function media_getTag($tags,$meta,$alt=''){ 1000 if($meta === false) return $alt; 1001 $info = $meta->getField($tags); 1002 if($info == false) return $alt; 1003 return $info; 1004} 1005 1006/** 1007 * Returns mediafile tags 1008 * 1009 * @author Kate Arzamastseva <pshns@ukr.net> 1010 * @param JpegMeta $meta 1011 * @return array 1012 */ 1013function media_file_tags($meta) { 1014 global $config_cascade; 1015 1016 // load the field descriptions 1017 static $fields = null; 1018 if(is_null($fields)){ 1019 $config_files = getConfigFiles('mediameta'); 1020 foreach ($config_files as $config_file) { 1021 if(@file_exists($config_file)) include($config_file); 1022 } 1023 } 1024 1025 $tags = array(); 1026 1027 foreach($fields as $key => $tag){ 1028 $t = array(); 1029 if (!empty($tag[0])) $t = array($tag[0]); 1030 if(is_array($tag[3])) $t = array_merge($t,$tag[3]); 1031 $value = media_getTag($t, $meta); 1032 $tags[] = array('tag' => $tag, 'value' => $value); 1033 } 1034 1035 return $tags; 1036} 1037 1038/** 1039 * Prints mediafile tags 1040 * 1041 * @author Kate Arzamastseva <pshns@ukr.net> 1042 */ 1043function media_details($image, $auth, $rev=false, $meta=false) { 1044 global $lang; 1045 1046 if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev)); 1047 $tags = media_file_tags($meta); 1048 1049 echo '<dl class="img_tags">'; 1050 foreach($tags as $tag){ 1051 if ($tag['value']) { 1052 $value = cleanText($tag['value']); 1053 echo '<dt>'.$lang[$tag['tag'][1]].':</dt><dd>'; 1054 if ($tag['tag'][2] == 'date') echo dformat($value); 1055 else echo hsc($value); 1056 echo '</dd>'; 1057 } 1058 } 1059 echo '</dl>'; 1060} 1061 1062/** 1063 * Shows difference between two revisions of file 1064 * 1065 * @author Kate Arzamastseva <pshns@ukr.net> 1066 */ 1067function media_diff($image, $ns, $auth, $fromajax = false) { 1068 global $lang; 1069 global $conf; 1070 1071 if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return ''; 1072 1073 $rev1 = (int) $_REQUEST['rev']; 1074 1075 if(is_array($_REQUEST['rev2'])){ 1076 $rev1 = (int) $_REQUEST['rev2'][0]; 1077 $rev2 = (int) $_REQUEST['rev2'][1]; 1078 1079 if(!$rev1){ 1080 $rev1 = $rev2; 1081 unset($rev2); 1082 } 1083 }else{ 1084 $rev2 = (int) $_REQUEST['rev2']; 1085 } 1086 1087 if ($rev1 && !file_exists(mediaFN($image, $rev1))) $rev1 = false; 1088 if ($rev2 && !file_exists(mediaFN($image, $rev2))) $rev2 = false; 1089 1090 if($rev1 && $rev2){ // two specific revisions wanted 1091 // make sure order is correct (older on the left) 1092 if($rev1 < $rev2){ 1093 $l_rev = $rev1; 1094 $r_rev = $rev2; 1095 }else{ 1096 $l_rev = $rev2; 1097 $r_rev = $rev1; 1098 } 1099 }elseif($rev1){ // single revision given, compare to current 1100 $r_rev = ''; 1101 $l_rev = $rev1; 1102 }else{ // no revision was given, compare previous to current 1103 $r_rev = ''; 1104 $revs = getRevisions($image, 0, 1, 8192, true); 1105 if (file_exists(mediaFN($image, $revs[0]))) { 1106 $l_rev = $revs[0]; 1107 } else { 1108 $l_rev = ''; 1109 } 1110 } 1111 1112 // prepare event data 1113 $data[0] = $image; 1114 $data[1] = $l_rev; 1115 $data[2] = $r_rev; 1116 $data[3] = $ns; 1117 $data[4] = $auth; 1118 $data[5] = $fromajax; 1119 1120 // trigger event 1121 return trigger_event('MEDIA_DIFF', $data, '_media_file_diff', true); 1122 1123} 1124 1125function _media_file_diff($data) { 1126 if(is_array($data) && count($data)===6) { 1127 return media_file_diff($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 1128 } else { 1129 return false; 1130 } 1131} 1132 1133/** 1134 * Shows difference between two revisions of image 1135 * 1136 * @author Kate Arzamastseva <pshns@ukr.net> 1137 */ 1138function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax){ 1139 global $lang, $config_cascade; 1140 1141 $l_meta = new JpegMeta(mediaFN($image, $l_rev)); 1142 $r_meta = new JpegMeta(mediaFN($image, $r_rev)); 1143 1144 $is_img = preg_match("/\.(jpe?g|gif|png)$/", $image); 1145 if ($is_img) { 1146 $l_size = media_image_preview_size($image, $l_rev, $l_meta); 1147 $r_size = media_image_preview_size($image, $r_rev, $r_meta); 1148 $is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30)); 1149 1150 $difftype = $_REQUEST['difftype']; 1151 1152 if (!$fromajax) { 1153 $form = new Doku_Form(array('action'=>media_managerURL(array(), '&'), 1154 'id' => 'mediamanager__form_diffview')); 1155 $form->addElement('<input type="hidden" name="rev2[]" value="'.$l_rev.'" ></input>'); 1156 $form->addElement('<input type="hidden" name="rev2[]" value="'.$r_rev.'" ></input>'); 1157 $form->addHidden('mediado', 'diff'); 1158 $form->printForm(); 1159 1160 echo '<div id="mediamanager__diff" >'; 1161 } 1162 1163 if ($difftype == 'opacity' || $difftype == 'portions') { 1164 media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $difftype); 1165 if (!$fromajax) echo '</div>'; 1166 return ''; 1167 } 1168 } 1169 1170 echo '<div class="mediamanager-preview">'; 1171 echo '<ul id="mediamanager__diff_table">'; 1172 1173 echo '<li>'; 1174 media_preview($image, $auth, $l_rev, $l_meta); 1175 echo '</li>'; 1176 1177 echo '<li>'; 1178 media_preview($image, $auth, $r_rev, $r_meta); 1179 echo '</li>'; 1180 1181 echo '<li>'; 1182 media_preview_buttons($image, $auth, $l_rev); 1183 echo '</li>'; 1184 1185 echo '<li>'; 1186 media_preview_buttons($image, $auth, $r_rev); 1187 echo '</li>'; 1188 1189 $l_tags = media_file_tags($l_meta); 1190 $r_tags = media_file_tags($r_meta); 1191 foreach ($l_tags as $key => $l_tag) { 1192 if ($l_tag['value'] != $r_tags[$key]['value']) { 1193 $r_tags[$key]['class'] = 'highlighted'; 1194 $l_tags[$key]['class'] = 'highlighted'; 1195 } else if (!$l_tag['value'] || !$r_tags[$key]['value']) { 1196 unset($r_tags[$key]); 1197 unset($l_tags[$key]); 1198 } 1199 } 1200 1201 foreach(array($l_tags,$r_tags) as $tags){ 1202 echo '<li><div>'; 1203 1204 echo '<dl class="img_tags">'; 1205 foreach($tags as $tag){ 1206 $value = cleanText($tag['value']); 1207 if (!$value) $value = '-'; 1208 echo '<dt>'.$lang[$tag['tag'][1]].':</dt>'; 1209 echo '<dd class="'.$tag['class'].'" >'; 1210 if ($tag['tag'][2] == 'date') echo dformat($value); 1211 else echo hsc($value); 1212 echo '</dd>'; 1213 } 1214 echo '</dl>'; 1215 1216 echo '</div></li>'; 1217 } 1218 1219 echo '</ul>'; 1220 echo '</div>'; 1221 1222 if ($is_img && !$fromajax) echo '</div>'; 1223} 1224 1225/** 1226 * Prints two images side by side 1227 * and slider 1228 * 1229 * @author Kate Arzamastseva <pshns@ukr.net> 1230 * @param string $image 1231 * @param int $l_rev 1232 * @param int $r_rev 1233 * @param array $l_size 1234 * @param array $r_size 1235 * @param string $type 1236 */ 1237function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) { 1238 if ($l_size != $r_size) { 1239 if ($r_size[0] > $l_size[0]) { 1240 $l_size = $r_size; 1241 } 1242 } 1243 1244 echo '<div class="mediamanager-preview">'; 1245 1246 $l_more = array('rev' => $l_rev, 'h' => $l_size[1], 'w' => $l_size[0]); 1247 $r_more = array('rev' => $r_rev, 'h' => $l_size[1], 'w' => $l_size[0]); 1248 1249 $l_src = ml($image, $l_more); 1250 $r_src = ml($image, $r_more); 1251 1252 // slider 1253 echo '<div id="mediamanager__'.$type.'_slider" style="max-width: '.($l_size[0]-20).'px;" ></div>'; 1254 1255 // two image's in div's 1256 echo '<div id="mediamanager__diff_layout">'; 1257 echo '<div id="mediamanager__diff_'.$type.'_image1" style="max-width: '.$l_size[0].'px;">'; 1258 echo '<img src="'.$l_src.'" alt="" />'; 1259 echo '</div>'; 1260 echo '<div id="mediamanager__diff_'.$type.'_image2" style="max-width: '.$l_size[0].'px;">'; 1261 echo '<img src="'.$r_src.'" alt="" />'; 1262 echo '</div>'; 1263 echo '</div>'; 1264 1265 echo '</div>'; 1266} 1267 1268/** 1269 * Restores an old revision of a media file 1270 * 1271 * @param string $image 1272 * @param int $rev 1273 * @param int $auth 1274 * @return string - file's id 1275 * @author Kate Arzamastseva <pshns@ukr.net> 1276 */ 1277function media_restore($image, $rev, $auth){ 1278 global $conf; 1279 if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false; 1280 $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes'))); 1281 if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false; 1282 if (!$rev || !file_exists(mediaFN($image, $rev))) return false; 1283 list($iext,$imime,$dl) = mimetype($image); 1284 $res = media_upload_finish(mediaFN($image, $rev), 1285 mediaFN($image), 1286 $image, 1287 $imime, 1288 true, 1289 'copy'); 1290 if (is_array($res)) { 1291 msg($res[0], $res[1]); 1292 return false; 1293 } 1294 return $res; 1295} 1296 1297/** 1298 * List all files found by the search request 1299 * 1300 * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1301 * @author Andreas Gohr <gohr@cosmocode.de> 1302 * @author Kate Arzamastseva <pshns@ukr.net> 1303 * @triggers MEDIA_SEARCH 1304 */ 1305function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort=''){ 1306 global $conf; 1307 global $lang; 1308 1309 $ns = cleanID($ns); 1310 1311 if ($query) { 1312 $evdata = array( 1313 'ns' => $ns, 1314 'data' => array(), 1315 'query' => $query 1316 ); 1317 $evt = new Doku_Event('MEDIA_SEARCH', $evdata); 1318 if ($evt->advise_before()) { 1319 $dir = utf8_encodeFN(str_replace(':','/',$evdata['ns'])); 1320 $pattern = '/'.preg_quote($evdata['query'],'/').'/i'; 1321 search($evdata['data'], 1322 $conf['mediadir'], 1323 'search_media', 1324 array('showmsg'=>false,'pattern'=>$pattern), 1325 $dir); 1326 } 1327 1328 $data = array(); 1329 foreach ($evdata['data'] as $k => $v) { 1330 $data[$k] = ($sort == 'date') ? $v['mtime'] : $v['id']; 1331 } 1332 array_multisort($data, SORT_DESC, SORT_NUMERIC, $evdata['data']); 1333 1334 $evt->advise_after(); 1335 unset($evt); 1336 } 1337 1338 if (!$fullscreen) { 1339 echo '<h1 id="media__ns">'.sprintf($lang['searchmedia_in'],hsc($ns).':*').'</h1>'.NL; 1340 media_searchform($ns,$query); 1341 } 1342 1343 if(!count($evdata['data'])){ 1344 echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 1345 }else { 1346 if ($fullscreen) { 1347 $view = $_REQUEST['view']; 1348 if ($view == 'list') { 1349 echo '<ul class="mediamanager-list" id="mediamanager__file_list">'; 1350 } else { 1351 echo '<ul class="mediamanager-thumbs" id="mediamanager__file_list">'; 1352 } 1353 } 1354 foreach($evdata['data'] as $item){ 1355 if (!$fullscreen) media_printfile($item,$item['perm'],'',true); 1356 else media_printfile_thumbs($item,$item['perm'],false,true); 1357 } 1358 if ($fullscreen) echo '</ul>'; 1359 } 1360} 1361 1362/** 1363 * Formats and prints one file in the list 1364 */ 1365function media_printfile($item,$auth,$jump,$display_namespace=false){ 1366 global $lang; 1367 global $conf; 1368 1369 // Prepare zebra coloring 1370 // I always wanted to use this variable name :-D 1371 static $twibble = 1; 1372 $twibble *= -1; 1373 $zebra = ($twibble == -1) ? 'odd' : 'even'; 1374 1375 // Automatically jump to recent action 1376 if($jump == $item['id']) { 1377 $jump = ' id="scroll__here" '; 1378 }else{ 1379 $jump = ''; 1380 } 1381 1382 // Prepare fileicons 1383 list($ext,$mime,$dl) = mimetype($item['file'],false); 1384 $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext); 1385 $class = 'select mediafile mf_'.$class; 1386 1387 // Prepare filename 1388 $file = utf8_decodeFN($item['file']); 1389 1390 // Prepare info 1391 $info = ''; 1392 if($item['isimg']){ 1393 $info .= (int) $item['meta']->getField('File.Width'); 1394 $info .= '×'; 1395 $info .= (int) $item['meta']->getField('File.Height'); 1396 $info .= ' '; 1397 } 1398 $info .= '<i>'.dformat($item['mtime']).'</i>'; 1399 $info .= ' '; 1400 $info .= filesize_h($item['size']); 1401 1402 // output 1403 echo '<div class="'.$zebra.'"'.$jump.'>'.NL; 1404 if (!$display_namespace) { 1405 echo '<a name="h_:'.$item['id'].'" class="'.$class.'">'.hsc($file).'</a> '; 1406 } else { 1407 echo '<a name="h_:'.$item['id'].'" class="'.$class.'">'.hsc($item['id']).'</a><br/>'; 1408 } 1409 echo '<span class="info">('.$info.')</span>'.NL; 1410 1411 // view button 1412 $link = ml($item['id'],'',true); 1413 echo ' <a href="'.$link.'" target="_blank"><img src="'.DOKU_BASE.'lib/images/magnifier.png" '. 1414 'alt="'.$lang['mediaview'].'" title="'.$lang['mediaview'].'" class="btn" /></a>'; 1415 1416 echo '<div class="example" id="ex_'.str_replace(':','_',$item['id']).'">'; 1417 echo $lang['mediausage'].' <code>{{:'.$item['id'].'}}</code>'; 1418 echo '</div>'; 1419 if($item['isimg']) media_printimgdetail($item); 1420 echo '<div class="clearer"></div>'.NL; 1421 echo '</div>'.NL; 1422} 1423 1424function media_printicon($filename){ 1425 list($ext,$mime,$dl) = mimetype(mediaFN($filename),false); 1426 1427 if (@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.png')) { 1428 $icon = DOKU_BASE.'lib/images/fileicons/'.$ext.'.png'; 1429 } else { 1430 $icon = DOKU_BASE.'lib/images/fileicons/file.png'; 1431 } 1432 1433 return '<img src="'.$icon.'" alt="'.$filename.'" class="icon" />'; 1434 1435} 1436 1437/** 1438 * Formats and prints one file in the list in the thumbnails view 1439 * 1440 * @author Kate Arzamastseva <pshns@ukr.net> 1441 */ 1442function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false){ 1443 global $lang; 1444 global $conf; 1445 1446 // Prepare filename 1447 $file = utf8_decodeFN($item['file']); 1448 1449 // output 1450 echo '<li><div>'; 1451 1452 if($item['isimg']) { 1453 media_printimgdetail($item, true); 1454 1455 } else { 1456 echo '<a name="d_:'.$item['id'].'" class="image" title="'.$item['id'].'" href="'. 1457 media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']), 1458 'tab_details' => 'view')).'"><span>'; 1459 echo media_printicon($item['id']); 1460 echo '</span></a>'; 1461 } 1462 //echo '<input type=checkbox />'; 1463 if (!$display_namespace) { 1464 $name = hsc($file); 1465 } else { 1466 $name = hsc($item['id']); 1467 } 1468 echo '<a href="'.media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']), 1469 'tab_details' => 'view')).'" name="h_:'.$item['id'].'" class="name">'.$name.'</a>'; 1470 1471 if($item['isimg']){ 1472 $size = ''; 1473 $size .= (int) $item['meta']->getField('File.Width'); 1474 $size .= '×'; 1475 $size .= (int) $item['meta']->getField('File.Height'); 1476 echo '<span class="size">'.$size.'</span>'; 1477 } else { 1478 echo '<span class="size"> </span>'; 1479 } 1480 $date = dformat($item['mtime']); 1481 echo '<span class="date">'.$date.'</span>'; 1482 $filesize = filesize_h($item['size']); 1483 echo '<span class="filesize">'.$filesize.'</span>'; 1484 echo '<div class="clearer"></div>'; 1485 echo '</div></li>'.NL; 1486} 1487 1488/** 1489 * Prints a thumbnail and metainfos 1490 */ 1491function media_printimgdetail($item, $fullscreen=false){ 1492 // prepare thumbnail 1493 if (!$fullscreen) { 1494 $size_array[] = 120; 1495 } else { 1496 $size_array = array(90, 40); 1497 } 1498 foreach ($size_array as $index => $size) { 1499 $w = (int) $item['meta']->getField('File.Width'); 1500 $h = (int) $item['meta']->getField('File.Height'); 1501 if($w>$size || $h>$size){ 1502 if (!$fullscreen) { 1503 $ratio = $item['meta']->getResizeRatio($size); 1504 } else { 1505 $ratio = $item['meta']->getResizeRatio($size,$size); 1506 } 1507 $w = floor($w * $ratio); 1508 $h = floor($h * $ratio); 1509 } 1510 $src = ml($item['id'],array('w'=>$w,'h'=>$h,'t'=>$item['mtime'])); 1511 $p = array(); 1512 if (!$fullscreen) { 1513 $p['width'] = $w; 1514 $p['height'] = $h; 1515 } 1516 $p['alt'] = $item['id']; 1517 $p['class'] = 'thumb'; 1518 $att = buildAttributes($p); 1519 1520 // output 1521 if ($fullscreen) { 1522 echo '<a name="'.($index ? 'd' : 'l').'_:'.$item['id'].'" class="image'.$index.'" title="'.$item['id'].'" href="'. 1523 media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']), 'tab_details' => 'view')).'">'; 1524 echo '<span><img src="'.$src.'" '.$att.' /></span>'; 1525 echo '</a>'; 1526 } 1527 } 1528 1529 if ($fullscreen) return ''; 1530 1531 echo '<div class="detail">'; 1532 echo '<div class="thumb">'; 1533 echo '<a name="d_:'.$item['id'].'" class="select">'; 1534 echo '<img src="'.$src.'" '.$att.' />'; 1535 echo '</a>'; 1536 echo '</div>'; 1537 1538 // read EXIF/IPTC data 1539 $t = $item['meta']->getField(array('IPTC.Headline','xmp.dc:title')); 1540 $d = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment', 1541 'EXIF.TIFFImageDescription', 1542 'EXIF.TIFFUserComment')); 1543 if(utf8_strlen($d) > 250) $d = utf8_substr($d,0,250).'...'; 1544 $k = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category','xmp.dc:subject')); 1545 1546 // print EXIF/IPTC data 1547 if($t || $d || $k ){ 1548 echo '<p>'; 1549 if($t) echo '<strong>'.htmlspecialchars($t).'</strong><br />'; 1550 if($d) echo htmlspecialchars($d).'<br />'; 1551 if($t) echo '<em>'.htmlspecialchars($k).'</em>'; 1552 echo '</p>'; 1553 } 1554 echo '</div>'; 1555} 1556 1557/** 1558 * Build link based on the current, adding/rewriting 1559 * parameters 1560 * 1561 * @author Kate Arzamastseva <pshns@ukr.net> 1562 * @param array $params 1563 * @param string $amp - separator 1564 * @return string - link 1565 */ 1566function media_managerURL($params=false, $amp='&', $abs=false, $params_array=false) { 1567 global $conf; 1568 global $ID; 1569 1570 $gets = array('do' => 'media'); 1571 $media_manager_params = array('tab_files', 'tab_details', 'image', 'ns', 'view'); 1572 foreach ($media_manager_params as $x) { 1573 if (isset($_REQUEST[$x])) $gets[$x] = $_REQUEST[$x]; 1574 } 1575 1576 if ($params) { 1577 foreach ($params as $k => $v) { 1578 $gets[$k] = $v; 1579 } 1580 } 1581 unset($gets['id']); 1582 if ($gets['delete']) { 1583 unset($gets['image']); 1584 unset($gets['tab_details']); 1585 } 1586 1587 if ($params_array) return $gets; 1588 1589 return wl($ID,$gets,$abs,$amp); 1590} 1591 1592/** 1593 * Print the media upload form if permissions are correct 1594 * 1595 * @author Andreas Gohr <andi@splitbrain.org> 1596 * @author Kate Arzamastseva <pshns@ukr.net> 1597 */ 1598function media_uploadform($ns, $auth, $fullscreen = false){ 1599 global $lang, $conf; 1600 1601 if($auth < AUTH_UPLOAD) { 1602 echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL; 1603 return; 1604 } 1605 $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 1606 1607 $update = false; 1608 $id = ''; 1609 if ($auth >= $auth_ow && $fullscreen && $_REQUEST['mediado'] == 'update') { 1610 $update = true; 1611 $id = cleanID($_REQUEST['image']); 1612 } 1613 1614 // The default HTML upload form 1615 $params = array('id' => 'dw__upload', 1616 'enctype' => 'multipart/form-data'); 1617 if (!$fullscreen) { 1618 $params['action'] = DOKU_BASE.'lib/exe/mediamanager.php'; 1619 } else { 1620 $params['action'] = media_managerURL(array('tab_files' => 'files', 1621 'tab_details' => 'view'), '&'); 1622 } 1623 1624 $form = new Doku_Form($params); 1625 if (!$fullscreen) echo '<div class="upload">' . $lang['mediaupload'] . '</div>'; 1626 $form->addElement(formSecurityToken()); 1627 $form->addHidden('ns', hsc($ns)); 1628 $form->addElement(form_makeOpenTag('p')); 1629 $form->addElement(form_makeFileField('upload', $lang['txt_upload'].':', 'upload__file')); 1630 $form->addElement(form_makeCloseTag('p')); 1631 $form->addElement(form_makeOpenTag('p')); 1632 $form->addElement(form_makeTextField('mediaid', noNS($id), $lang['txt_filename'].':', 'upload__name')); 1633 $form->addElement(form_makeButton('submit', '', $lang['btn_upload'])); 1634 $form->addElement(form_makeCloseTag('p')); 1635 1636 if($auth >= $auth_ow){ 1637 $form->addElement(form_makeOpenTag('p')); 1638 $attrs = array(); 1639 if ($update) $attrs['checked'] = 'checked'; 1640 $form->addElement(form_makeCheckboxField('ow', 1, $lang['txt_overwrt'], 'dw__ow', 'check', $attrs)); 1641 $form->addElement(form_makeCloseTag('p')); 1642 } 1643 1644 echo '<div id="mediamanager__uploader">'; 1645 html_form('upload', $form); 1646 echo '</div>'; 1647} 1648 1649/** 1650 * Print the search field form 1651 * 1652 * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1653 * @author Kate Arzamastseva <pshns@ukr.net> 1654 */ 1655function media_searchform($ns,$query='',$fullscreen=false){ 1656 global $lang; 1657 1658 // The default HTML search form 1659 $params = array('id' => 'dw__mediasearch'); 1660 if (!$fullscreen) $params['action'] = DOKU_BASE.'lib/exe/mediamanager.php'; 1661 else $params['action'] = media_managerURL(array(), '&'); 1662 $form = new Doku_Form($params); 1663 if (!$fullscreen) $form->addElement('<div class="upload">' . $lang['mediasearch'] . '</div>'); 1664 $form->addElement(formSecurityToken()); 1665 $form->addHidden('ns', $ns); 1666 if (!$fullscreen) $form->addHidden('do', 'searchlist'); 1667 else $form->addHidden('mediado', 'searchlist'); 1668 $form->addElement(form_makeOpenTag('p')); 1669 $form->addElement(form_makeTextField('q', $query,$lang['searchmedia'],'mediamanager__sort_textfield','',array('title'=>sprintf($lang['searchmedia_in'],hsc($ns).':*')))); 1670 $form->addElement(form_makeButton('submit', '', $lang['btn_search'])); 1671 $form->addElement(form_makeCloseTag('p')); 1672 html_form('searchmedia', $form); 1673} 1674 1675/** 1676 * Build a tree outline of available media namespaces 1677 * 1678 * @author Andreas Gohr <andi@splitbrain.org> 1679 */ 1680function media_nstree($ns){ 1681 global $conf; 1682 global $lang; 1683 1684 // currently selected namespace 1685 $ns = cleanID($ns); 1686 if(empty($ns)){ 1687 global $ID; 1688 $ns = dirname(str_replace(':','/',$ID)); 1689 if($ns == '.') $ns =''; 1690 } 1691 $ns = utf8_encodeFN(str_replace(':','/',$ns)); 1692 1693 $data = array(); 1694 search($data,$conf['mediadir'],'search_index',array('ns' => $ns, 'nofiles' => true)); 1695 1696 // wrap a list with the root level around the other namespaces 1697 array_unshift($data, array('level' => 0, 'id' => '', 'open' =>'true', 1698 'label' => '['.$lang['mediaroot'].']')); 1699 1700 echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li'); 1701} 1702 1703/** 1704 * Userfunction for html_buildlist 1705 * 1706 * Prints a media namespace tree item 1707 * 1708 * @author Andreas Gohr <andi@splitbrain.org> 1709 */ 1710function media_nstree_item($item){ 1711 $pos = strrpos($item['id'], ':'); 1712 $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); 1713 if(!$item['label']) $item['label'] = $label; 1714 1715 $ret = ''; 1716 if (!($_REQUEST['do'] == 'media')) 1717 $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">'; 1718 else $ret .= '<a href="'.media_managerURL(array('ns' => idfilter($item['id']), 'tab_files' => 'files')) 1719 .'" class="idx_dir">'; 1720 $ret .= $item['label']; 1721 $ret .= '</a>'; 1722 return $ret; 1723} 1724 1725/** 1726 * Userfunction for html_buildlist 1727 * 1728 * Prints a media namespace tree item opener 1729 * 1730 * @author Andreas Gohr <andi@splitbrain.org> 1731 */ 1732function media_nstree_li($item){ 1733 $class='media level'.$item['level']; 1734 if($item['open']){ 1735 $class .= ' open'; 1736 $img = DOKU_BASE.'lib/images/minus.gif'; 1737 $alt = '−'; 1738 }else{ 1739 $class .= ' closed'; 1740 $img = DOKU_BASE.'lib/images/plus.gif'; 1741 $alt = '+'; 1742 } 1743 // TODO: only deliver an image if it actually has a subtree... 1744 return '<li class="'.$class.'">'. 1745 '<img src="'.$img.'" alt="'.$alt.'" />'; 1746} 1747 1748/** 1749 * Resizes the given image to the given size 1750 * 1751 * @author Andreas Gohr <andi@splitbrain.org> 1752 */ 1753function media_resize_image($file, $ext, $w, $h=0){ 1754 global $conf; 1755 1756 $info = @getimagesize($file); //get original size 1757 if($info == false) return $file; // that's no image - it's a spaceship! 1758 1759 if(!$h) $h = round(($w * $info[1]) / $info[0]); 1760 1761 // we wont scale up to infinity 1762 if($w > 2000 || $h > 2000) return $file; 1763 1764 //cache 1765 $local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext); 1766 $mtime = @filemtime($local); // 0 if not exists 1767 1768 if( $mtime > filemtime($file) || 1769 media_resize_imageIM($ext,$file,$info[0],$info[1],$local,$w,$h) || 1770 media_resize_imageGD($ext,$file,$info[0],$info[1],$local,$w,$h) ){ 1771 if($conf['fperm']) chmod($local, $conf['fperm']); 1772 return $local; 1773 } 1774 //still here? resizing failed 1775 return $file; 1776} 1777 1778/** 1779 * Crops the given image to the wanted ratio, then calls media_resize_image to scale it 1780 * to the wanted size 1781 * 1782 * Crops are centered horizontally but prefer the upper third of an vertical 1783 * image because most pics are more interesting in that area (rule of thirds) 1784 * 1785 * @author Andreas Gohr <andi@splitbrain.org> 1786 */ 1787function media_crop_image($file, $ext, $w, $h=0){ 1788 global $conf; 1789 1790 if(!$h) $h = $w; 1791 $info = @getimagesize($file); //get original size 1792 if($info == false) return $file; // that's no image - it's a spaceship! 1793 1794 // calculate crop size 1795 $fr = $info[0]/$info[1]; 1796 $tr = $w/$h; 1797 if($tr >= 1){ 1798 if($tr > $fr){ 1799 $cw = $info[0]; 1800 $ch = (int) $info[0]/$tr; 1801 }else{ 1802 $cw = (int) $info[1]*$tr; 1803 $ch = $info[1]; 1804 } 1805 }else{ 1806 if($tr < $fr){ 1807 $cw = (int) $info[1]*$tr; 1808 $ch = $info[1]; 1809 }else{ 1810 $cw = $info[0]; 1811 $ch = (int) $info[0]/$tr; 1812 } 1813 } 1814 // calculate crop offset 1815 $cx = (int) ($info[0]-$cw)/2; 1816 $cy = (int) ($info[1]-$ch)/3; 1817 1818 //cache 1819 $local = getCacheName($file,'.media.'.$cw.'x'.$ch.'.crop.'.$ext); 1820 $mtime = @filemtime($local); // 0 if not exists 1821 1822 if( $mtime > filemtime($file) || 1823 media_crop_imageIM($ext,$file,$info[0],$info[1],$local,$cw,$ch,$cx,$cy) || 1824 media_resize_imageGD($ext,$file,$cw,$ch,$local,$cw,$ch,$cx,$cy) ){ 1825 if($conf['fperm']) chmod($local, $conf['fperm']); 1826 return media_resize_image($local,$ext, $w, $h); 1827 } 1828 1829 //still here? cropping failed 1830 return media_resize_image($file,$ext, $w, $h); 1831} 1832 1833/** 1834 * Download a remote file and return local filename 1835 * 1836 * returns false if download fails. Uses cached file if available and 1837 * wanted 1838 * 1839 * @author Andreas Gohr <andi@splitbrain.org> 1840 * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 1841 */ 1842function media_get_from_URL($url,$ext,$cache){ 1843 global $conf; 1844 1845 // if no cache or fetchsize just redirect 1846 if ($cache==0) return false; 1847 if (!$conf['fetchsize']) return false; 1848 1849 $local = getCacheName(strtolower($url),".media.$ext"); 1850 $mtime = @filemtime($local); // 0 if not exists 1851 1852 //decide if download needed: 1853 if( ($mtime == 0) || // cache does not exist 1854 ($cache != -1 && $mtime < time()-$cache) // 'recache' and cache has expired 1855 ){ 1856 if(media_image_download($url,$local)){ 1857 return $local; 1858 }else{ 1859 return false; 1860 } 1861 } 1862 1863 //if cache exists use it else 1864 if($mtime) return $local; 1865 1866 //else return false 1867 return false; 1868} 1869 1870/** 1871 * Download image files 1872 * 1873 * @author Andreas Gohr <andi@splitbrain.org> 1874 */ 1875function media_image_download($url,$file){ 1876 global $conf; 1877 $http = new DokuHTTPClient(); 1878 $http->max_bodysize = $conf['fetchsize']; 1879 $http->timeout = 25; //max. 25 sec 1880 $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; 1881 1882 $data = $http->get($url); 1883 if(!$data) return false; 1884 1885 $fileexists = @file_exists($file); 1886 $fp = @fopen($file,"w"); 1887 if(!$fp) return false; 1888 fwrite($fp,$data); 1889 fclose($fp); 1890 if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); 1891 1892 // check if it is really an image 1893 $info = @getimagesize($file); 1894 if(!$info){ 1895 @unlink($file); 1896 return false; 1897 } 1898 1899 return true; 1900} 1901 1902/** 1903 * resize images using external ImageMagick convert program 1904 * 1905 * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 1906 * @author Andreas Gohr <andi@splitbrain.org> 1907 */ 1908function media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ 1909 global $conf; 1910 1911 // check if convert is configured 1912 if(!$conf['im_convert']) return false; 1913 1914 // prepare command 1915 $cmd = $conf['im_convert']; 1916 $cmd .= ' -resize '.$to_w.'x'.$to_h.'!'; 1917 if ($ext == 'jpg' || $ext == 'jpeg') { 1918 $cmd .= ' -quality '.$conf['jpg_quality']; 1919 } 1920 $cmd .= " $from $to"; 1921 1922 @exec($cmd,$out,$retval); 1923 if ($retval == 0) return true; 1924 return false; 1925} 1926 1927/** 1928 * crop images using external ImageMagick convert program 1929 * 1930 * @author Andreas Gohr <andi@splitbrain.org> 1931 */ 1932function media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){ 1933 global $conf; 1934 1935 // check if convert is configured 1936 if(!$conf['im_convert']) return false; 1937 1938 // prepare command 1939 $cmd = $conf['im_convert']; 1940 $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y; 1941 if ($ext == 'jpg' || $ext == 'jpeg') { 1942 $cmd .= ' -quality '.$conf['jpg_quality']; 1943 } 1944 $cmd .= " $from $to"; 1945 1946 @exec($cmd,$out,$retval); 1947 if ($retval == 0) return true; 1948 return false; 1949} 1950 1951/** 1952 * resize or crop images using PHP's libGD support 1953 * 1954 * @author Andreas Gohr <andi@splitbrain.org> 1955 * @author Sebastian Wienecke <s_wienecke@web.de> 1956 */ 1957function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){ 1958 global $conf; 1959 1960 if($conf['gdlib'] < 1) return false; //no GDlib available or wanted 1961 1962 // check available memory 1963 if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){ 1964 return false; 1965 } 1966 1967 // create an image of the given filetype 1968 if ($ext == 'jpg' || $ext == 'jpeg'){ 1969 if(!function_exists("imagecreatefromjpeg")) return false; 1970 $image = @imagecreatefromjpeg($from); 1971 }elseif($ext == 'png') { 1972 if(!function_exists("imagecreatefrompng")) return false; 1973 $image = @imagecreatefrompng($from); 1974 1975 }elseif($ext == 'gif') { 1976 if(!function_exists("imagecreatefromgif")) return false; 1977 $image = @imagecreatefromgif($from); 1978 } 1979 if(!$image) return false; 1980 1981 if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){ 1982 $newimg = @imagecreatetruecolor ($to_w, $to_h); 1983 } 1984 if(!$newimg) $newimg = @imagecreate($to_w, $to_h); 1985 if(!$newimg){ 1986 imagedestroy($image); 1987 return false; 1988 } 1989 1990 //keep png alpha channel if possible 1991 if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ 1992 imagealphablending($newimg, false); 1993 imagesavealpha($newimg,true); 1994 } 1995 1996 //keep gif transparent color if possible 1997 if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { 1998 if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { 1999 $transcolorindex = @imagecolortransparent($image); 2000 if($transcolorindex >= 0 ) { //transparent color exists 2001 $transcolor = @imagecolorsforindex($image, $transcolorindex); 2002 $transcolorindex = @imagecolorallocate($newimg, $transcolor['red'], $transcolor['green'], $transcolor['blue']); 2003 @imagefill($newimg, 0, 0, $transcolorindex); 2004 @imagecolortransparent($newimg, $transcolorindex); 2005 }else{ //filling with white 2006 $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 2007 @imagefill($newimg, 0, 0, $whitecolorindex); 2008 } 2009 }else{ //filling with white 2010 $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 2011 @imagefill($newimg, 0, 0, $whitecolorindex); 2012 } 2013 } 2014 2015 //try resampling first 2016 if(function_exists("imagecopyresampled")){ 2017 if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { 2018 imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 2019 } 2020 }else{ 2021 imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 2022 } 2023 2024 $okay = false; 2025 if ($ext == 'jpg' || $ext == 'jpeg'){ 2026 if(!function_exists('imagejpeg')){ 2027 $okay = false; 2028 }else{ 2029 $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); 2030 } 2031 }elseif($ext == 'png') { 2032 if(!function_exists('imagepng')){ 2033 $okay = false; 2034 }else{ 2035 $okay = imagepng($newimg, $to); 2036 } 2037 }elseif($ext == 'gif') { 2038 if(!function_exists('imagegif')){ 2039 $okay = false; 2040 }else{ 2041 $okay = imagegif($newimg, $to); 2042 } 2043 } 2044 2045 // destroy GD image ressources 2046 if($image) imagedestroy($image); 2047 if($newimg) imagedestroy($newimg); 2048 2049 return $okay; 2050} 2051 2052/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 2053