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 echo $ns ? $ns : '['.$lang['mediaroot'].']'; 686 687 echo '<div id="mediamanager__tabs_list">'; 688 689 echo '<a href="'.media_managerURL(array('view' => 'thumbs')).'" id="mediamanager__link_thumbs" >'; 690 echo $lang['media_thumbsview']; 691 echo '</a>'; 692 693 echo '<a href="'.media_managerURL(array('view' => 'list')).'" id="mediamanager__link_list" >'; 694 echo $lang['media_listview']; 695 echo '</a>'; 696 697 echo '</div>'; 698 699 echo '<div id="mediamanager__sort">'; 700 $form = new Doku_Form(array('action'=>media_managerURL(array(), '&'), 'id' => 'mediamanager__form_sort')); 701 $form->addElement(form_makeListboxField( 702 'sort', 703 array( 704 'name' => $lang['media_sort_name'], 705 'date' => $lang['media_sort_date']), 706 $sort, 707 $lang['media_sort'])); 708 $form->addElement(form_makeButton('submit', '', $lang['btn_apply'])); 709 $form->printForm(); 710 echo '</div>'; 711 712 echo '<div class="clearer"></div>'; 713 echo '</div>'; 714} 715 716/** 717 * Returns type of sorting for the list of files in media manager 718 * 719 * @author Kate Arzamastseva <pshns@ukr.net> 720 * @return string - sort type 721 */ 722function _media_get_sort_type() { 723 $sort = $_REQUEST['sort']; 724 if (!$sort && (strpos($_COOKIE['DOKU_PREFS'], 'sort') >= 0)) { 725 $parts = explode('#', $_COOKIE['DOKU_PREFS']); 726 for ($i = 0; $i < count($parts); $i+=2){ 727 if ($parts[$i] == 'sort') $sort = $parts[$i+1]; 728 } 729 } 730 return $sort; 731} 732 733/** 734 * Prints tab that displays a list of all files 735 * 736 * @author Kate Arzamastseva <pshns@ukr.net> 737 */ 738function media_tab_files($ns,$auth=null,$jump='') { 739 global $lang; 740 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 741 742 $sort = _media_get_sort_type(); 743 media_tab_files_options($ns, $sort); 744 745 echo '<div class="scroll-container" >'; 746 if($auth < AUTH_READ){ 747 echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 748 }else{ 749 media_filelist($ns,$auth,$jump,true,$sort); 750 } 751 echo '</div>'; 752} 753 754/** 755 * Prints tab that displays uploading form 756 * 757 * @author Kate Arzamastseva <pshns@ukr.net> 758 */ 759function media_tab_upload($ns,$auth=null,$jump='') { 760 global $lang; 761 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 762 763 echo '<div class="background-container">'; 764 echo sprintf($lang['media_upload'], $ns ? $ns : '['.$lang['mediaroot'].']'); 765 echo '</div>'; 766 767 echo '<div class="scroll-container">'; 768 if ($auth >= AUTH_UPLOAD) echo '<div class="upload">' . $lang['mediaupload'] . '</div>'; 769 media_uploadform($ns, $auth, true); 770 echo '</div>'; 771} 772 773/** 774 * Prints tab that displays search form 775 * 776 * @author Kate Arzamastseva <pshns@ukr.net> 777 */ 778function media_tab_search($ns,$auth=null) { 779 global $lang; 780 781 $do = $_REQUEST['mediado']; 782 $query = $_REQUEST['q']; 783 if (!$query) $query = ''; 784 785 $sort = _media_get_sort_type(); 786 media_tab_files_options($ns, $sort); 787 788 echo '<div class="scroll-container">'; 789 media_searchform($ns, $query, true); 790 if ($do == 'searchlist') media_searchlist($query,$ns,$auth,true,$sort); 791 echo '</div>'; 792} 793 794/** 795 * Prints tab that displays mediafile details 796 * 797 * @author Kate Arzamastseva <pshns@ukr.net> 798 */ 799function media_tab_view($image, $ns, $auth=null, $rev=false) { 800 global $lang, $conf; 801 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 802 803 echo '<div class="background-container">'; 804 list($ext,$mime,$dl) = mimetype($image,false); 805 $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext); 806 $class = 'select mediafile mf_'.$class; 807 echo '<span class="'.$class.'" >'.$image.'</span>'; 808 echo '</div>'; 809 810 echo '<div class="scroll-container">'; 811 if ($image && $auth >= AUTH_READ) { 812 $meta = new JpegMeta(mediaFN($image, $rev)); 813 media_preview($image, $auth, $rev, $meta); 814 media_preview_buttons($image, $auth, $rev); 815 media_details($image, $auth, $rev, $meta); 816 817 } else { 818 echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'; 819 } 820 echo '</div>'; 821} 822 823/** 824 * Prints tab that displays form for editing mediafile metadata 825 * 826 * @author Kate Arzamastseva <pshns@ukr.net> 827 */ 828function media_tab_edit($image, $ns, $auth=null) { 829 global $lang; 830 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 831 832 echo '<div class="background-container">'; 833 echo $lang['media_edit']; 834 echo '</div>'; 835 836 echo '<div class="scroll-container">'; 837 if ($image) { 838 list($ext, $mime) = mimetype($image); 839 if ($mime == 'image/jpeg') media_metaform($image,$auth); 840 } 841 echo '</div>'; 842} 843 844/** 845 * Prints tab that displays mediafile revisions 846 * 847 * @author Kate Arzamastseva <pshns@ukr.net> 848 */ 849function media_tab_history($image, $ns, $auth=null) { 850 global $lang; 851 if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 852 $do = $_REQUEST['mediado']; 853 854 echo '<div class="background-container">'; 855 echo $lang['media_history']; 856 echo '</div>'; 857 858 echo '<div class="scroll-container">'; 859 if ($auth >= AUTH_READ && $image) { 860 if ($do == 'diff'){ 861 media_diff($image, $ns, $auth); 862 } else { 863 $first = isset($_REQUEST['first']) ? intval($_REQUEST['first']) : 0; 864 html_revisions($first, $image); 865 } 866 } else { 867 echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 868 } 869 echo '</div>'; 870} 871 872/** 873 * Prints mediafile details 874 * 875 * @author Kate Arzamastseva <pshns@ukr.net> 876 */ 877function media_preview($image, $auth, $rev=false, $meta=false) { 878 global $lang; 879 880 echo '<div class="mediamanager__preview">'; 881 882 $size = media_image_preview_size($image, $rev, $meta); 883 884 if ($size) { 885 $more = array(); 886 if ($rev) { 887 $more['rev'] = $rev; 888 } else { 889 $t = @filemtime(mediaFN($image)); 890 $more['t'] = $t; 891 } 892 893 $more['w'] = $size[0]; 894 $more['h'] = $size[1]; 895 $src = ml($image, $more); 896 echo '<img src="'.$src.'" alt="'.$image.'" style="max-width: '.$size[0].'px;" />'; 897 } 898 899 echo '</div>'; 900} 901 902/** 903 * Prints mediafile action buttons 904 * 905 * @author Kate Arzamastseva <pshns@ukr.net> 906 */ 907function media_preview_buttons($image, $auth, $rev=false) { 908 global $lang, $conf; 909 910 echo '<div class="mediamanager__preview_buttons">'; 911 912 $more = ''; 913 if ($rev) { 914 $more = "rev=$rev"; 915 } else { 916 $t = @filemtime(mediaFN($image)); 917 $more = "t=$t"; 918 } 919 $link = ml($image,$more,true,'&'); 920 921 if (@file_exists(mediaFN($image, $rev))) { 922 923 // view original file button 924 $form = new Doku_Form(array('action'=>$link, 'target'=>'_blank')); 925 $form->addElement(form_makeButton('submit','',$lang['mediaview'])); 926 $form->printForm(); 927 } 928 929 if($auth >= AUTH_DELETE && !$rev && @file_exists(mediaFN($image))){ 930 931 // delete button 932 $form = new Doku_Form(array('id' => 'mediamanager__btn_delete', 933 'action'=>media_managerURL(array('delete' => $image), '&'))); 934 $form->addElement(form_makeButton('submit','',$lang['btn_delete'])); 935 $form->printForm(); 936 937 } 938 939 $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 940 if($auth >= $auth_ow && !$rev){ 941 942 // upload new version button 943 $form = new Doku_Form(array('id' => 'mediamanager__btn_update', 944 'action'=>media_managerURL(array('image' => $image, 'mediado' => 'update'), '&'))); 945 $form->addElement(form_makeButton('submit','',$lang['media_update'])); 946 $form->printForm(); 947 } 948 949 if($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && @file_exists(mediaFN($image, $rev))){ 950 951 // restore button 952 $form = new Doku_Form(array('id' => 'mediamanager__btn_restore', 953 'action'=>media_managerURL(array('image' => $image), '&'))); 954 $form->addHidden('mediado','restore'); 955 $form->addHidden('rev',$rev); 956 $form->addElement(form_makeButton('submit','',$lang['media_restore'])); 957 $form->printForm(); 958 } 959 960 echo '</div>'; 961} 962 963/** 964 * Returns image width and height for mediamanager preview panel 965 * 966 * @author Kate Arzamastseva <pshns@ukr.net> 967 * @param string $image 968 * @param int $rev 969 * @param JpegMeta $meta 970 * @return array 971 */ 972function media_image_preview_size($image, $rev, $meta, $size = 500) { 973 if (!preg_match("/\.(jpe?g|gif|png)$/", $image) || !file_exists(mediaFN($image, $rev))) return false; 974 975 $info = getimagesize(mediaFN($image, $rev)); 976 $w = (int) $info[0]; 977 $h = (int) $info[1]; 978 979 if($meta && ($w > $size || $h > $size)){ 980 $ratio = $meta->getResizeRatio($size, $size); 981 $w = floor($w * $ratio); 982 $h = floor($h * $ratio); 983 } 984 return array($w, $h); 985} 986 987/** 988 * Returns the requested EXIF/IPTC tag from the image meta 989 * 990 * @author Kate Arzamastseva <pshns@ukr.net> 991 * @param array $tags 992 * @param JpegMeta $meta 993 * @param string $alt 994 * @return string 995 */ 996function media_getTag($tags,$meta,$alt=''){ 997 if($meta === false) return $alt; 998 $info = $meta->getField($tags); 999 if($info == false) return $alt; 1000 return $info; 1001} 1002 1003/** 1004 * Returns mediafile tags 1005 * 1006 * @author Kate Arzamastseva <pshns@ukr.net> 1007 * @param JpegMeta $meta 1008 * @return array 1009 */ 1010function media_file_tags($meta) { 1011 global $config_cascade; 1012 1013 // load the field descriptions 1014 static $fields = null; 1015 if(is_null($fields)){ 1016 $config_files = getConfigFiles('mediameta'); 1017 foreach ($config_files as $config_file) { 1018 if(@file_exists($config_file)) include($config_file); 1019 } 1020 } 1021 1022 $tags = array(); 1023 1024 foreach($fields as $key => $tag){ 1025 $t = array(); 1026 if (!empty($tag[0])) $t = array($tag[0]); 1027 if(is_array($tag[3])) $t = array_merge($t,$tag[3]); 1028 $value = media_getTag($t, $meta); 1029 $tags[] = array('tag' => $tag, 'value' => $value); 1030 } 1031 1032 return $tags; 1033} 1034 1035/** 1036 * Prints mediafile tags 1037 * 1038 * @author Kate Arzamastseva <pshns@ukr.net> 1039 */ 1040function media_details($image, $auth, $rev=false, $meta=false) { 1041 global $lang; 1042 1043 if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev)); 1044 $tags = media_file_tags($meta); 1045 1046 echo '<dl class="img_tags">'; 1047 foreach($tags as $tag){ 1048 if ($tag['value']) { 1049 $value = cleanText($tag['value']); 1050 echo '<dt>'.$lang[$tag['tag'][1]].':</dt><dd>'; 1051 if ($tag['tag'][2] == 'date') echo dformat($value); 1052 else echo hsc($value); 1053 echo '</dd>'; 1054 } 1055 } 1056 echo '</dl>'; 1057} 1058 1059/** 1060 * Shows difference between two revisions of file 1061 * 1062 * @author Kate Arzamastseva <pshns@ukr.net> 1063 */ 1064function media_diff($image, $ns, $auth, $fromajax = false) { 1065 global $lang; 1066 global $conf; 1067 1068 if ($auth < AUTH_READ || !$image || !$conf['mediarevisions']) return ''; 1069 1070 $rev1 = (int) $_REQUEST['rev']; 1071 1072 if(is_array($_REQUEST['rev2'])){ 1073 $rev1 = (int) $_REQUEST['rev2'][0]; 1074 $rev2 = (int) $_REQUEST['rev2'][1]; 1075 1076 if(!$rev1){ 1077 $rev1 = $rev2; 1078 unset($rev2); 1079 } 1080 }else{ 1081 $rev2 = (int) $_REQUEST['rev2']; 1082 } 1083 1084 if ($rev1 && !file_exists(mediaFN($image, $rev1))) $rev1 = false; 1085 if ($rev2 && !file_exists(mediaFN($image, $rev2))) $rev2 = false; 1086 1087 if($rev1 && $rev2){ // two specific revisions wanted 1088 // make sure order is correct (older on the left) 1089 if($rev1 < $rev2){ 1090 $l_rev = $rev1; 1091 $r_rev = $rev2; 1092 }else{ 1093 $l_rev = $rev2; 1094 $r_rev = $rev1; 1095 } 1096 }elseif($rev1){ // single revision given, compare to current 1097 $r_rev = ''; 1098 $l_rev = $rev1; 1099 }else{ // no revision was given, compare previous to current 1100 $r_rev = ''; 1101 $revs = getRevisions($image, 0, 1, 8192, true); 1102 if (file_exists(mediaFN($image, $revs[0]))) { 1103 $l_rev = $revs[0]; 1104 } else { 1105 $l_rev = ''; 1106 } 1107 } 1108 1109 // prepare event data 1110 $data[0] = $image; 1111 $data[1] = $l_rev; 1112 $data[2] = $r_rev; 1113 $data[3] = $ns; 1114 $data[4] = $auth; 1115 $data[5] = $fromajax; 1116 1117 // trigger event 1118 return trigger_event('MEDIA_DIFF', $data, '_media_file_diff', true); 1119 1120} 1121 1122function _media_file_diff($data) { 1123 if(is_array($data) && count($data)===6) { 1124 return media_file_diff($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 1125 } else { 1126 return false; 1127 } 1128} 1129 1130/** 1131 * Shows difference between two revisions of image 1132 * 1133 * @author Kate Arzamastseva <pshns@ukr.net> 1134 */ 1135function media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax){ 1136 global $lang, $config_cascade; 1137 1138 $l_meta = new JpegMeta(mediaFN($image, $l_rev)); 1139 $r_meta = new JpegMeta(mediaFN($image, $r_rev)); 1140 1141 $is_img = preg_match("/\.(jpe?g|gif|png)$/", $image); 1142 if ($is_img) { 1143 $l_size = media_image_preview_size($image, $l_rev, $l_meta); 1144 $r_size = media_image_preview_size($image, $r_rev, $r_meta); 1145 $is_img = ($l_size && $r_size && ($l_size[0] >= 30 || $r_size[0] >= 30)); 1146 1147 $difftype = $_REQUEST['difftype']; 1148 1149 if (!$fromajax) { 1150 $form = new Doku_Form(array('action'=>media_managerURL(array(), '&'), 1151 'id' => 'mediamanager__form_diffview')); 1152 $form->addElement('<input type="hidden" name="rev2[]" value="'.$l_rev.'" ></input>'); 1153 $form->addElement('<input type="hidden" name="rev2[]" value="'.$r_rev.'" ></input>'); 1154 $form->addHidden('mediado', 'diff'); 1155 $form->printForm(); 1156 1157 echo '<div id="mediamanager__diff" >'; 1158 } 1159 1160 if ($difftype == 'opacity' || $difftype == 'portions') { 1161 media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $difftype); 1162 if (!$fromajax) echo '</div>'; 1163 return ''; 1164 } 1165 } 1166 1167 echo '<div class="mediamanager-preview">'; 1168 echo '<ul id="mediamanager__diff_table">'; 1169 1170 echo '<li>'; 1171 media_preview($image, $auth, $l_rev, $l_meta); 1172 echo '</li>'; 1173 1174 echo '<li>'; 1175 media_preview($image, $auth, $r_rev, $r_meta); 1176 echo '</li>'; 1177 1178 echo '<li>'; 1179 media_preview_buttons($image, $auth, $l_rev); 1180 echo '</li>'; 1181 1182 echo '<li>'; 1183 media_preview_buttons($image, $auth, $r_rev); 1184 echo '</li>'; 1185 1186 $l_tags = media_file_tags($l_meta); 1187 $r_tags = media_file_tags($r_meta); 1188 foreach ($l_tags as $key => $l_tag) { 1189 if ($l_tag['value'] != $r_tags[$key]['value']) { 1190 $r_tags[$key]['class'] = 'highlighted'; 1191 $l_tags[$key]['class'] = 'highlighted'; 1192 } else if (!$l_tag['value'] || !$r_tags[$key]['value']) { 1193 unset($r_tags[$key]); 1194 unset($l_tags[$key]); 1195 } 1196 } 1197 1198 foreach(array($l_tags,$r_tags) as $tags){ 1199 echo '<li><div>'; 1200 1201 echo '<dl class="img_tags">'; 1202 foreach($tags as $tag){ 1203 $value = cleanText($tag['value']); 1204 if (!$value) $value = '-'; 1205 echo '<dt>'.$lang[$tag['tag'][1]].':</dt>'; 1206 echo '<dd class="'.$tag['class'].'" >'; 1207 if ($tag['tag'][2] == 'date') echo dformat($value); 1208 else echo hsc($value); 1209 echo '</dd>'; 1210 } 1211 echo '</dl>'; 1212 1213 echo '</div></li>'; 1214 } 1215 1216 echo '</ul>'; 1217 echo '</div>'; 1218 1219 if ($is_img && !$fromajax) echo '</div>'; 1220} 1221 1222/** 1223 * Prints two images side by side 1224 * and slider 1225 * 1226 * @author Kate Arzamastseva <pshns@ukr.net> 1227 * @param string $image 1228 * @param int $l_rev 1229 * @param int $r_rev 1230 * @param array $l_size 1231 * @param array $r_size 1232 * @param string $type 1233 */ 1234function media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) { 1235 if ($l_size != $r_size) { 1236 if ($r_size[0] > $l_size[0]) { 1237 $l_size = $r_size; 1238 } 1239 } 1240 1241 echo '<div class="mediamanager-preview">'; 1242 1243 $l_more = array('rev' => $l_rev, 'h' => $l_size[1], 'w' => $l_size[0]); 1244 $r_more = array('rev' => $r_rev, 'h' => $l_size[1], 'w' => $l_size[0]); 1245 1246 $l_src = ml($image, $l_more); 1247 $r_src = ml($image, $r_more); 1248 1249 // slider 1250 echo '<div id="mediamanager__'.$type.'_slider" style="max-width: '.($l_size[0]-20).'px;" ></div>'; 1251 1252 // two image's in div's 1253 echo '<div id="mediamanager__diff_layout">'; 1254 echo '<div id="mediamanager__diff_'.$type.'_image1" style="max-width: '.$l_size[0].'px;">'; 1255 echo '<img src="'.$l_src.'" alt="" />'; 1256 echo '</div>'; 1257 echo '<div id="mediamanager__diff_'.$type.'_image2" style="max-width: '.$l_size[0].'px;">'; 1258 echo '<img src="'.$r_src.'" alt="" />'; 1259 echo '</div>'; 1260 echo '</div>'; 1261 1262 echo '</div>'; 1263} 1264 1265/** 1266 * Restores an old revision of a media file 1267 * 1268 * @param string $image 1269 * @param int $rev 1270 * @param int $auth 1271 * @return string - file's id 1272 * @author Kate Arzamastseva <pshns@ukr.net> 1273 */ 1274function media_restore($image, $rev, $auth){ 1275 global $conf; 1276 if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false; 1277 $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes'))); 1278 if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false; 1279 if (!$rev || !file_exists(mediaFN($image, $rev))) return false; 1280 list($iext,$imime,$dl) = mimetype($image); 1281 $res = media_upload_finish(mediaFN($image, $rev), 1282 mediaFN($image), 1283 $image, 1284 $imime, 1285 true, 1286 'copy'); 1287 if (is_array($res)) { 1288 msg($res[0], $res[1]); 1289 return false; 1290 } 1291 return $res; 1292} 1293 1294/** 1295 * List all files found by the search request 1296 * 1297 * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1298 * @author Andreas Gohr <gohr@cosmocode.de> 1299 * @author Kate Arzamastseva <pshns@ukr.net> 1300 * @triggers MEDIA_SEARCH 1301 */ 1302function media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort=''){ 1303 global $conf; 1304 global $lang; 1305 1306 $ns = cleanID($ns); 1307 1308 if ($query) { 1309 $evdata = array( 1310 'ns' => $ns, 1311 'data' => array(), 1312 'query' => $query 1313 ); 1314 $evt = new Doku_Event('MEDIA_SEARCH', $evdata); 1315 if ($evt->advise_before()) { 1316 $dir = utf8_encodeFN(str_replace(':','/',$evdata['ns'])); 1317 $pattern = '/'.preg_quote($evdata['query'],'/').'/i'; 1318 search($evdata['data'], 1319 $conf['mediadir'], 1320 'search_media', 1321 array('showmsg'=>false,'pattern'=>$pattern), 1322 $dir); 1323 } 1324 1325 $data = array(); 1326 foreach ($evdata['data'] as $k => $v) { 1327 $data[$k] = ($sort == 'date') ? $v['mtime'] : $v['id']; 1328 } 1329 array_multisort($data, SORT_DESC, SORT_NUMERIC, $evdata['data']); 1330 1331 $evt->advise_after(); 1332 unset($evt); 1333 } 1334 1335 if (!$fullscreen) { 1336 echo '<h1 id="media__ns">'.sprintf($lang['searchmedia_in'],hsc($ns).':*').'</h1>'.NL; 1337 media_searchform($ns,$query); 1338 } 1339 1340 if(!count($evdata['data'])){ 1341 echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 1342 }else { 1343 if ($fullscreen) { 1344 $view = $_REQUEST['view']; 1345 if ($view == 'list') { 1346 echo '<ul class="mediamanager-list" id="mediamanager__file_list">'; 1347 } else { 1348 echo '<ul class="mediamanager-thumbs" id="mediamanager__file_list">'; 1349 } 1350 } 1351 foreach($evdata['data'] as $item){ 1352 if (!$fullscreen) media_printfile($item,$item['perm'],'',true); 1353 else media_printfile_thumbs($item,$item['perm'],false,true); 1354 } 1355 if ($fullscreen) echo '</ul>'; 1356 } 1357} 1358 1359/** 1360 * Formats and prints one file in the list 1361 */ 1362function media_printfile($item,$auth,$jump,$display_namespace=false){ 1363 global $lang; 1364 global $conf; 1365 1366 // Prepare zebra coloring 1367 // I always wanted to use this variable name :-D 1368 static $twibble = 1; 1369 $twibble *= -1; 1370 $zebra = ($twibble == -1) ? 'odd' : 'even'; 1371 1372 // Automatically jump to recent action 1373 if($jump == $item['id']) { 1374 $jump = ' id="scroll__here" '; 1375 }else{ 1376 $jump = ''; 1377 } 1378 1379 // Prepare fileicons 1380 list($ext,$mime,$dl) = mimetype($item['file'],false); 1381 $class = preg_replace('/[^_\-a-z0-9]+/i','_',$ext); 1382 $class = 'select mediafile mf_'.$class; 1383 1384 // Prepare filename 1385 $file = utf8_decodeFN($item['file']); 1386 1387 // Prepare info 1388 $info = ''; 1389 if($item['isimg']){ 1390 $info .= (int) $item['meta']->getField('File.Width'); 1391 $info .= '×'; 1392 $info .= (int) $item['meta']->getField('File.Height'); 1393 $info .= ' '; 1394 } 1395 $info .= '<i>'.dformat($item['mtime']).'</i>'; 1396 $info .= ' '; 1397 $info .= filesize_h($item['size']); 1398 1399 // output 1400 echo '<div class="'.$zebra.'"'.$jump.'>'.NL; 1401 if (!$display_namespace) { 1402 echo '<a name="h_:'.$item['id'].'" class="'.$class.'">'.hsc($file).'</a> '; 1403 } else { 1404 echo '<a name="h_:'.$item['id'].'" class="'.$class.'">'.hsc($item['id']).'</a><br/>'; 1405 } 1406 echo '<span class="info">('.$info.')</span>'.NL; 1407 1408 // view button 1409 $link = ml($item['id'],'',true); 1410 echo ' <a href="'.$link.'" target="_blank"><img src="'.DOKU_BASE.'lib/images/magnifier.png" '. 1411 'alt="'.$lang['mediaview'].'" title="'.$lang['mediaview'].'" class="btn" /></a>'; 1412 1413 echo '<div class="example" id="ex_'.str_replace(':','_',$item['id']).'">'; 1414 echo $lang['mediausage'].' <code>{{:'.$item['id'].'}}</code>'; 1415 echo '</div>'; 1416 if($item['isimg']) media_printimgdetail($item); 1417 echo '<div class="clearer"></div>'.NL; 1418 echo '</div>'.NL; 1419} 1420 1421function media_printicon($filename){ 1422 list($ext,$mime,$dl) = mimetype(mediaFN($filename),false); 1423 1424 if (@file_exists(DOKU_INC.'lib/images/fileicons/'.$ext.'.png')) { 1425 $icon = DOKU_BASE.'lib/images/fileicons/'.$ext.'.png'; 1426 } else { 1427 $icon = DOKU_BASE.'lib/images/fileicons/file.png'; 1428 } 1429 1430 return '<img src="'.$icon.'" alt="'.$filename.'" class="icon" />'; 1431 1432} 1433 1434/** 1435 * Formats and prints one file in the list in the thumbnails view 1436 * 1437 * @author Kate Arzamastseva <pshns@ukr.net> 1438 */ 1439function media_printfile_thumbs($item,$auth,$jump=false,$display_namespace=false){ 1440 global $lang; 1441 global $conf; 1442 1443 // Prepare filename 1444 $file = utf8_decodeFN($item['file']); 1445 1446 // output 1447 echo '<li><div>'; 1448 1449 if($item['isimg']) { 1450 media_printimgdetail($item, true); 1451 1452 } else { 1453 echo '<a name="d_:'.$item['id'].'" class="image" title="'.$item['id'].'" href="'. 1454 media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']), 1455 'tab_details' => 'view')).'"><span>'; 1456 echo media_printicon($item['id']); 1457 echo '</span></a>'; 1458 } 1459 //echo '<input type=checkbox />'; 1460 if (!$display_namespace) { 1461 $name = hsc($file); 1462 } else { 1463 $name = hsc($item['id']); 1464 } 1465 echo '<a href="'.media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']), 1466 'tab_details' => 'view')).'" name="h_:'.$item['id'].'" class="name">'.$name.'</a>'; 1467 1468 if($item['isimg']){ 1469 $size = ''; 1470 $size .= (int) $item['meta']->getField('File.Width'); 1471 $size .= '×'; 1472 $size .= (int) $item['meta']->getField('File.Height'); 1473 echo '<span class="size">'.$size.'</span>'; 1474 } else { 1475 echo '<span class="size"> </span>'; 1476 } 1477 $date = dformat($item['mtime']); 1478 echo '<span class="date">'.$date.'</span>'; 1479 $filesize = filesize_h($item['size']); 1480 echo '<span class="filesize">'.$filesize.'</span>'; 1481 echo '<div class="clearer"></div>'; 1482 echo '</div></li>'.NL; 1483} 1484 1485/** 1486 * Prints a thumbnail and metainfos 1487 */ 1488function media_printimgdetail($item, $fullscreen=false){ 1489 // prepare thumbnail 1490 if (!$fullscreen) { 1491 $size_array[] = 120; 1492 } else { 1493 $size_array = array(90, 40); 1494 } 1495 foreach ($size_array as $index => $size) { 1496 $w = (int) $item['meta']->getField('File.Width'); 1497 $h = (int) $item['meta']->getField('File.Height'); 1498 if($w>$size || $h>$size){ 1499 if (!$fullscreen) { 1500 $ratio = $item['meta']->getResizeRatio($size); 1501 } else { 1502 $ratio = $item['meta']->getResizeRatio($size,$size); 1503 } 1504 $w = floor($w * $ratio); 1505 $h = floor($h * $ratio); 1506 } 1507 $src = ml($item['id'],array('w'=>$w,'h'=>$h,'t'=>$item['mtime'])); 1508 $p = array(); 1509 if (!$fullscreen) { 1510 $p['width'] = $w; 1511 $p['height'] = $h; 1512 } 1513 $p['alt'] = $item['id']; 1514 $p['class'] = 'thumb'; 1515 $att = buildAttributes($p); 1516 1517 // output 1518 if ($fullscreen) { 1519 echo '<a name="'.($index ? 'd' : 'l').'_:'.$item['id'].'" class="image'.$index.'" title="'.$item['id'].'" href="'. 1520 media_managerURL(array('image' => hsc($item['id']), 'ns' => getNS($item['id']), 'tab_details' => 'view')).'">'; 1521 echo '<span><img src="'.$src.'" '.$att.' /></span>'; 1522 echo '</a>'; 1523 } 1524 } 1525 1526 if ($fullscreen) return ''; 1527 1528 echo '<div class="detail">'; 1529 echo '<div class="thumb">'; 1530 echo '<a name="d_:'.$item['id'].'" class="select">'; 1531 echo '<img src="'.$src.'" '.$att.' />'; 1532 echo '</a>'; 1533 echo '</div>'; 1534 1535 // read EXIF/IPTC data 1536 $t = $item['meta']->getField(array('IPTC.Headline','xmp.dc:title')); 1537 $d = $item['meta']->getField(array('IPTC.Caption','EXIF.UserComment', 1538 'EXIF.TIFFImageDescription', 1539 'EXIF.TIFFUserComment')); 1540 if(utf8_strlen($d) > 250) $d = utf8_substr($d,0,250).'...'; 1541 $k = $item['meta']->getField(array('IPTC.Keywords','IPTC.Category','xmp.dc:subject')); 1542 1543 // print EXIF/IPTC data 1544 if($t || $d || $k ){ 1545 echo '<p>'; 1546 if($t) echo '<strong>'.htmlspecialchars($t).'</strong><br />'; 1547 if($d) echo htmlspecialchars($d).'<br />'; 1548 if($t) echo '<em>'.htmlspecialchars($k).'</em>'; 1549 echo '</p>'; 1550 } 1551 echo '</div>'; 1552} 1553 1554/** 1555 * Build link based on the current, adding/rewriting 1556 * parameters 1557 * 1558 * @author Kate Arzamastseva <pshns@ukr.net> 1559 * @param array $params 1560 * @param string $amp - separator 1561 * @return string - link 1562 */ 1563function media_managerURL($params=false, $amp='&', $abs=false, $params_array=false) { 1564 global $conf; 1565 global $ID; 1566 1567 $gets = array('do' => 'media'); 1568 $media_manager_params = array('tab_files', 'tab_details', 'image', 'ns', 'view'); 1569 foreach ($media_manager_params as $x) { 1570 if (isset($_REQUEST[$x])) $gets[$x] = $_REQUEST[$x]; 1571 } 1572 1573 if ($params) { 1574 foreach ($params as $k => $v) { 1575 $gets[$k] = $v; 1576 } 1577 } 1578 unset($gets['id']); 1579 if ($gets['delete']) { 1580 unset($gets['image']); 1581 unset($gets['tab_details']); 1582 } 1583 1584 if ($params_array) return $gets; 1585 1586 return wl($ID,$gets,$abs,$amp); 1587} 1588 1589/** 1590 * Print the media upload form if permissions are correct 1591 * 1592 * @author Andreas Gohr <andi@splitbrain.org> 1593 * @author Kate Arzamastseva <pshns@ukr.net> 1594 */ 1595function media_uploadform($ns, $auth, $fullscreen = false){ 1596 global $lang, $conf; 1597 1598 if($auth < AUTH_UPLOAD) { 1599 echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL; 1600 return; 1601 } 1602 $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 1603 1604 $update = false; 1605 $id = ''; 1606 if ($auth >= $auth_ow && $fullscreen && $_REQUEST['mediado'] == 'update') { 1607 $update = true; 1608 $id = cleanID($_REQUEST['image']); 1609 } 1610 1611 // The default HTML upload form 1612 $params = array('id' => 'dw__upload', 1613 'enctype' => 'multipart/form-data'); 1614 if (!$fullscreen) { 1615 $params['action'] = DOKU_BASE.'lib/exe/mediamanager.php'; 1616 } else { 1617 $params['action'] = media_managerURL(array('tab_files' => 'files', 1618 'tab_details' => 'view'), '&'); 1619 } 1620 1621 $form = new Doku_Form($params); 1622 if (!$fullscreen) echo '<div class="upload">' . $lang['mediaupload'] . '</div>'; 1623 $form->addElement(formSecurityToken()); 1624 $form->addHidden('ns', hsc($ns)); 1625 $form->addElement(form_makeOpenTag('p')); 1626 $form->addElement(form_makeFileField('upload', $lang['txt_upload'].':', 'upload__file')); 1627 $form->addElement(form_makeCloseTag('p')); 1628 $form->addElement(form_makeOpenTag('p')); 1629 $form->addElement(form_makeTextField('mediaid', noNS($id), $lang['txt_filename'].':', 'upload__name')); 1630 $form->addElement(form_makeButton('submit', '', $lang['btn_upload'])); 1631 $form->addElement(form_makeCloseTag('p')); 1632 1633 if($auth >= $auth_ow){ 1634 $form->addElement(form_makeOpenTag('p')); 1635 $attrs = array(); 1636 if ($update) $attrs['checked'] = 'checked'; 1637 $form->addElement(form_makeCheckboxField('ow', 1, $lang['txt_overwrt'], 'dw__ow', 'check', $attrs)); 1638 $form->addElement(form_makeCloseTag('p')); 1639 } 1640 1641 echo '<div id="mediamanager__uploader">'; 1642 html_form('upload', $form); 1643 echo '</div>'; 1644} 1645 1646/** 1647 * Print the search field form 1648 * 1649 * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1650 * @author Kate Arzamastseva <pshns@ukr.net> 1651 */ 1652function media_searchform($ns,$query='',$fullscreen=false){ 1653 global $lang; 1654 1655 // The default HTML search form 1656 $params = array('id' => 'dw__mediasearch'); 1657 if (!$fullscreen) $params['action'] = DOKU_BASE.'lib/exe/mediamanager.php'; 1658 else $params['action'] = media_managerURL(array(), '&'); 1659 $form = new Doku_Form($params); 1660 if (!$fullscreen) $form->addElement('<div class="upload">' . $lang['mediasearch'] . '</div>'); 1661 $form->addElement(formSecurityToken()); 1662 $form->addHidden('ns', $ns); 1663 if (!$fullscreen) $form->addHidden('do', 'searchlist'); 1664 else $form->addHidden('mediado', 'searchlist'); 1665 $form->addElement(form_makeOpenTag('p')); 1666 $form->addElement(form_makeTextField('q', $query,$lang['searchmedia'],'mediamanager__sort_textfield','',array('title'=>sprintf($lang['searchmedia_in'],hsc($ns).':*')))); 1667 $form->addElement(form_makeButton('submit', '', $lang['btn_search'])); 1668 $form->addElement(form_makeCloseTag('p')); 1669 html_form('searchmedia', $form); 1670} 1671 1672/** 1673 * Build a tree outline of available media namespaces 1674 * 1675 * @author Andreas Gohr <andi@splitbrain.org> 1676 */ 1677function media_nstree($ns){ 1678 global $conf; 1679 global $lang; 1680 1681 // currently selected namespace 1682 $ns = cleanID($ns); 1683 if(empty($ns)){ 1684 global $ID; 1685 $ns = dirname(str_replace(':','/',$ID)); 1686 if($ns == '.') $ns =''; 1687 } 1688 $ns = utf8_encodeFN(str_replace(':','/',$ns)); 1689 1690 $data = array(); 1691 search($data,$conf['mediadir'],'search_index',array('ns' => $ns, 'nofiles' => true)); 1692 1693 // wrap a list with the root level around the other namespaces 1694 array_unshift($data, array('level' => 0, 'id' => '', 'open' =>'true', 1695 'label' => '['.$lang['mediaroot'].']')); 1696 1697 echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li'); 1698} 1699 1700/** 1701 * Userfunction for html_buildlist 1702 * 1703 * Prints a media namespace tree item 1704 * 1705 * @author Andreas Gohr <andi@splitbrain.org> 1706 */ 1707function media_nstree_item($item){ 1708 $pos = strrpos($item['id'], ':'); 1709 $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); 1710 if(!$item['label']) $item['label'] = $label; 1711 1712 $ret = ''; 1713 if (!($_REQUEST['do'] == 'media')) 1714 $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">'; 1715 else $ret .= '<a href="'.media_managerURL(array('ns' => idfilter($item['id']), 'tab_files' => 'files')) 1716 .'" class="idx_dir">'; 1717 $ret .= $item['label']; 1718 $ret .= '</a>'; 1719 return $ret; 1720} 1721 1722/** 1723 * Userfunction for html_buildlist 1724 * 1725 * Prints a media namespace tree item opener 1726 * 1727 * @author Andreas Gohr <andi@splitbrain.org> 1728 */ 1729function media_nstree_li($item){ 1730 $class='media level'.$item['level']; 1731 if($item['open']){ 1732 $class .= ' open'; 1733 $img = DOKU_BASE.'lib/images/minus.gif'; 1734 $alt = '−'; 1735 }else{ 1736 $class .= ' closed'; 1737 $img = DOKU_BASE.'lib/images/plus.gif'; 1738 $alt = '+'; 1739 } 1740 // TODO: only deliver an image if it actually has a subtree... 1741 return '<li class="'.$class.'">'. 1742 '<img src="'.$img.'" alt="'.$alt.'" />'; 1743} 1744 1745/** 1746 * Resizes the given image to the given size 1747 * 1748 * @author Andreas Gohr <andi@splitbrain.org> 1749 */ 1750function media_resize_image($file, $ext, $w, $h=0){ 1751 global $conf; 1752 1753 $info = @getimagesize($file); //get original size 1754 if($info == false) return $file; // that's no image - it's a spaceship! 1755 1756 if(!$h) $h = round(($w * $info[1]) / $info[0]); 1757 1758 // we wont scale up to infinity 1759 if($w > 2000 || $h > 2000) return $file; 1760 1761 //cache 1762 $local = getCacheName($file,'.media.'.$w.'x'.$h.'.'.$ext); 1763 $mtime = @filemtime($local); // 0 if not exists 1764 1765 if( $mtime > filemtime($file) || 1766 media_resize_imageIM($ext,$file,$info[0],$info[1],$local,$w,$h) || 1767 media_resize_imageGD($ext,$file,$info[0],$info[1],$local,$w,$h) ){ 1768 if($conf['fperm']) chmod($local, $conf['fperm']); 1769 return $local; 1770 } 1771 //still here? resizing failed 1772 return $file; 1773} 1774 1775/** 1776 * Crops the given image to the wanted ratio, then calls media_resize_image to scale it 1777 * to the wanted size 1778 * 1779 * Crops are centered horizontally but prefer the upper third of an vertical 1780 * image because most pics are more interesting in that area (rule of thirds) 1781 * 1782 * @author Andreas Gohr <andi@splitbrain.org> 1783 */ 1784function media_crop_image($file, $ext, $w, $h=0){ 1785 global $conf; 1786 1787 if(!$h) $h = $w; 1788 $info = @getimagesize($file); //get original size 1789 if($info == false) return $file; // that's no image - it's a spaceship! 1790 1791 // calculate crop size 1792 $fr = $info[0]/$info[1]; 1793 $tr = $w/$h; 1794 if($tr >= 1){ 1795 if($tr > $fr){ 1796 $cw = $info[0]; 1797 $ch = (int) $info[0]/$tr; 1798 }else{ 1799 $cw = (int) $info[1]*$tr; 1800 $ch = $info[1]; 1801 } 1802 }else{ 1803 if($tr < $fr){ 1804 $cw = (int) $info[1]*$tr; 1805 $ch = $info[1]; 1806 }else{ 1807 $cw = $info[0]; 1808 $ch = (int) $info[0]/$tr; 1809 } 1810 } 1811 // calculate crop offset 1812 $cx = (int) ($info[0]-$cw)/2; 1813 $cy = (int) ($info[1]-$ch)/3; 1814 1815 //cache 1816 $local = getCacheName($file,'.media.'.$cw.'x'.$ch.'.crop.'.$ext); 1817 $mtime = @filemtime($local); // 0 if not exists 1818 1819 if( $mtime > filemtime($file) || 1820 media_crop_imageIM($ext,$file,$info[0],$info[1],$local,$cw,$ch,$cx,$cy) || 1821 media_resize_imageGD($ext,$file,$cw,$ch,$local,$cw,$ch,$cx,$cy) ){ 1822 if($conf['fperm']) chmod($local, $conf['fperm']); 1823 return media_resize_image($local,$ext, $w, $h); 1824 } 1825 1826 //still here? cropping failed 1827 return media_resize_image($file,$ext, $w, $h); 1828} 1829 1830/** 1831 * Download a remote file and return local filename 1832 * 1833 * returns false if download fails. Uses cached file if available and 1834 * wanted 1835 * 1836 * @author Andreas Gohr <andi@splitbrain.org> 1837 * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 1838 */ 1839function media_get_from_URL($url,$ext,$cache){ 1840 global $conf; 1841 1842 // if no cache or fetchsize just redirect 1843 if ($cache==0) return false; 1844 if (!$conf['fetchsize']) return false; 1845 1846 $local = getCacheName(strtolower($url),".media.$ext"); 1847 $mtime = @filemtime($local); // 0 if not exists 1848 1849 //decide if download needed: 1850 if( ($mtime == 0) || // cache does not exist 1851 ($cache != -1 && $mtime < time()-$cache) // 'recache' and cache has expired 1852 ){ 1853 if(media_image_download($url,$local)){ 1854 return $local; 1855 }else{ 1856 return false; 1857 } 1858 } 1859 1860 //if cache exists use it else 1861 if($mtime) return $local; 1862 1863 //else return false 1864 return false; 1865} 1866 1867/** 1868 * Download image files 1869 * 1870 * @author Andreas Gohr <andi@splitbrain.org> 1871 */ 1872function media_image_download($url,$file){ 1873 global $conf; 1874 $http = new DokuHTTPClient(); 1875 $http->max_bodysize = $conf['fetchsize']; 1876 $http->timeout = 25; //max. 25 sec 1877 $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; 1878 1879 $data = $http->get($url); 1880 if(!$data) return false; 1881 1882 $fileexists = @file_exists($file); 1883 $fp = @fopen($file,"w"); 1884 if(!$fp) return false; 1885 fwrite($fp,$data); 1886 fclose($fp); 1887 if(!$fileexists and $conf['fperm']) chmod($file, $conf['fperm']); 1888 1889 // check if it is really an image 1890 $info = @getimagesize($file); 1891 if(!$info){ 1892 @unlink($file); 1893 return false; 1894 } 1895 1896 return true; 1897} 1898 1899/** 1900 * resize images using external ImageMagick convert program 1901 * 1902 * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 1903 * @author Andreas Gohr <andi@splitbrain.org> 1904 */ 1905function media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ 1906 global $conf; 1907 1908 // check if convert is configured 1909 if(!$conf['im_convert']) return false; 1910 1911 // prepare command 1912 $cmd = $conf['im_convert']; 1913 $cmd .= ' -resize '.$to_w.'x'.$to_h.'!'; 1914 if ($ext == 'jpg' || $ext == 'jpeg') { 1915 $cmd .= ' -quality '.$conf['jpg_quality']; 1916 } 1917 $cmd .= " $from $to"; 1918 1919 @exec($cmd,$out,$retval); 1920 if ($retval == 0) return true; 1921 return false; 1922} 1923 1924/** 1925 * crop images using external ImageMagick convert program 1926 * 1927 * @author Andreas Gohr <andi@splitbrain.org> 1928 */ 1929function media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){ 1930 global $conf; 1931 1932 // check if convert is configured 1933 if(!$conf['im_convert']) return false; 1934 1935 // prepare command 1936 $cmd = $conf['im_convert']; 1937 $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y; 1938 if ($ext == 'jpg' || $ext == 'jpeg') { 1939 $cmd .= ' -quality '.$conf['jpg_quality']; 1940 } 1941 $cmd .= " $from $to"; 1942 1943 @exec($cmd,$out,$retval); 1944 if ($retval == 0) return true; 1945 return false; 1946} 1947 1948/** 1949 * resize or crop images using PHP's libGD support 1950 * 1951 * @author Andreas Gohr <andi@splitbrain.org> 1952 * @author Sebastian Wienecke <s_wienecke@web.de> 1953 */ 1954function media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){ 1955 global $conf; 1956 1957 if($conf['gdlib'] < 1) return false; //no GDlib available or wanted 1958 1959 // check available memory 1960 if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){ 1961 return false; 1962 } 1963 1964 // create an image of the given filetype 1965 if ($ext == 'jpg' || $ext == 'jpeg'){ 1966 if(!function_exists("imagecreatefromjpeg")) return false; 1967 $image = @imagecreatefromjpeg($from); 1968 }elseif($ext == 'png') { 1969 if(!function_exists("imagecreatefrompng")) return false; 1970 $image = @imagecreatefrompng($from); 1971 1972 }elseif($ext == 'gif') { 1973 if(!function_exists("imagecreatefromgif")) return false; 1974 $image = @imagecreatefromgif($from); 1975 } 1976 if(!$image) return false; 1977 1978 if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){ 1979 $newimg = @imagecreatetruecolor ($to_w, $to_h); 1980 } 1981 if(!$newimg) $newimg = @imagecreate($to_w, $to_h); 1982 if(!$newimg){ 1983 imagedestroy($image); 1984 return false; 1985 } 1986 1987 //keep png alpha channel if possible 1988 if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ 1989 imagealphablending($newimg, false); 1990 imagesavealpha($newimg,true); 1991 } 1992 1993 //keep gif transparent color if possible 1994 if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { 1995 if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { 1996 $transcolorindex = @imagecolortransparent($image); 1997 if($transcolorindex >= 0 ) { //transparent color exists 1998 $transcolor = @imagecolorsforindex($image, $transcolorindex); 1999 $transcolorindex = @imagecolorallocate($newimg, $transcolor['red'], $transcolor['green'], $transcolor['blue']); 2000 @imagefill($newimg, 0, 0, $transcolorindex); 2001 @imagecolortransparent($newimg, $transcolorindex); 2002 }else{ //filling with white 2003 $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 2004 @imagefill($newimg, 0, 0, $whitecolorindex); 2005 } 2006 }else{ //filling with white 2007 $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 2008 @imagefill($newimg, 0, 0, $whitecolorindex); 2009 } 2010 } 2011 2012 //try resampling first 2013 if(function_exists("imagecopyresampled")){ 2014 if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { 2015 imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 2016 } 2017 }else{ 2018 imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 2019 } 2020 2021 $okay = false; 2022 if ($ext == 'jpg' || $ext == 'jpeg'){ 2023 if(!function_exists('imagejpeg')){ 2024 $okay = false; 2025 }else{ 2026 $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); 2027 } 2028 }elseif($ext == 'png') { 2029 if(!function_exists('imagepng')){ 2030 $okay = false; 2031 }else{ 2032 $okay = imagepng($newimg, $to); 2033 } 2034 }elseif($ext == 'gif') { 2035 if(!function_exists('imagegif')){ 2036 $okay = false; 2037 }else{ 2038 $okay = imagegif($newimg, $to); 2039 } 2040 } 2041 2042 // destroy GD image ressources 2043 if($image) imagedestroy($image); 2044 if($newimg) imagedestroy($newimg); 2045 2046 return $okay; 2047} 2048 2049/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 2050