13df72098SAndreas Gohr<?php 23df72098SAndreas Gohr/** 33df72098SAndreas Gohr * All output and handler function needed for the media management popup 43df72098SAndreas Gohr * 53df72098SAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 63df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 73df72098SAndreas Gohr */ 8*24870174SAndreas Gohruse dokuwiki\Ui\MediaRevisions; 9*24870174SAndreas Gohruse dokuwiki\Cache\CacheImageMod; 10*24870174SAndreas Gohruse splitbrain\slika\Exception; 11*24870174SAndreas Gohruse dokuwiki\PassHash; 120c3a5702SAndreas Gohruse dokuwiki\ChangeLog\MediaChangeLog; 13b021f0b4SAndreas Gohruse dokuwiki\Extension\Event; 14b021f0b4SAndreas Gohruse dokuwiki\Form\Form; 155a8d6e48SMichael Großeuse dokuwiki\HTTP\DokuHTTPClient; 1679a2d784SGerrit Uitslaguse dokuwiki\Logger; 17704a815fSMichael Großeuse dokuwiki\Subscriptions\MediaSubscriptionSender; 1879a2d784SGerrit Uitslaguse dokuwiki\Ui\Media\DisplayRow; 1979a2d784SGerrit Uitslaguse dokuwiki\Ui\Media\DisplayTile; 2079a2d784SGerrit Uitslaguse dokuwiki\Ui\MediaDiff; 2179a2d784SGerrit Uitslaguse dokuwiki\Utf8\PhpString; 222d85e841SAndreas Gohruse dokuwiki\Utf8\Sort; 2379a2d784SGerrit Uitslaguse splitbrain\slika\Slika; 240c3a5702SAndreas Gohr 253df72098SAndreas Gohr/** 263df72098SAndreas Gohr * Lists pages which currently use a media file selected for deletion 273df72098SAndreas Gohr * 283df72098SAndreas Gohr * References uses the same visual as search results and share 293df72098SAndreas Gohr * their CSS tags except pagenames won't be links. 303df72098SAndreas Gohr * 313df72098SAndreas Gohr * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 3242ea7f44SGerrit Uitslag * 3342ea7f44SGerrit Uitslag * @param array $data 3442ea7f44SGerrit Uitslag * @param string $id 353df72098SAndreas Gohr */ 363df72098SAndreas Gohrfunction media_filesinuse($data,$id){ 373df72098SAndreas Gohr global $lang; 383df72098SAndreas Gohr echo '<h1>'.$lang['reference'].' <code>'.hsc(noNS($id)).'</code></h1>'; 393df72098SAndreas Gohr echo '<p>'.hsc($lang['ref_inuse']).'</p>'; 403df72098SAndreas Gohr 413df72098SAndreas Gohr $hidden=0; //count of hits without read permission 423df72098SAndreas Gohr foreach($data as $row){ 43a05e297aSAndreas Gohr if(auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)){ 443df72098SAndreas Gohr echo '<div class="search_result">'; 45a05e297aSAndreas Gohr echo '<span class="mediaref_ref">'.hsc($row).'</span>'; 463df72098SAndreas Gohr echo '</div>'; 473df72098SAndreas Gohr }else 483df72098SAndreas Gohr $hidden++; 493df72098SAndreas Gohr } 503df72098SAndreas Gohr if ($hidden){ 513df72098SAndreas Gohr print '<div class="mediaref_hidden">'.$lang['ref_hidden'].'</div>'; 523df72098SAndreas Gohr } 533df72098SAndreas Gohr} 543df72098SAndreas Gohr 553df72098SAndreas Gohr/** 563df72098SAndreas Gohr * Handles the saving of image meta data 573df72098SAndreas Gohr * 583df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 59cf832786SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 60e0c26282SGerrit Uitslag * 61e0c26282SGerrit Uitslag * @param string $id media id 62e0c26282SGerrit Uitslag * @param int $auth permission level 63e0c26282SGerrit Uitslag * @param array $data 6442ea7f44SGerrit Uitslag * @return false|string 653df72098SAndreas Gohr */ 663df72098SAndreas Gohrfunction media_metasave($id,$auth,$data){ 673df72098SAndreas Gohr if($auth < AUTH_UPLOAD) return false; 68f2ea8432SAndreas Gohr if(!checkSecurityToken()) return false; 693df72098SAndreas Gohr global $lang; 700b308644SOtto Vainio global $conf; 713df72098SAndreas Gohr $src = mediaFN($id); 723df72098SAndreas Gohr 733df72098SAndreas Gohr $meta = new JpegMeta($src); 743df72098SAndreas Gohr $meta->_parseAll(); 753df72098SAndreas Gohr 763df72098SAndreas Gohr foreach($data as $key => $val){ 773df72098SAndreas Gohr $val=trim($val); 783df72098SAndreas Gohr if(empty($val)){ 793df72098SAndreas Gohr $meta->deleteField($key); 803df72098SAndreas Gohr }else{ 813df72098SAndreas Gohr $meta->setField($key,$val); 823df72098SAndreas Gohr } 833df72098SAndreas Gohr } 843df72098SAndreas Gohr 85cf832786SKate Arzamastseva $old = @filemtime($src); 8679e79377SAndreas Gohr if(!file_exists(mediaFN($id, $old)) && file_exists($src)) { 87cf832786SKate Arzamastseva // add old revision to the attic 88cf832786SKate Arzamastseva media_saveOldRevision($id); 89cf832786SKate Arzamastseva } 90ac3ed4afSGerrit Uitslag $filesize_old = filesize($src); 913df72098SAndreas Gohr if($meta->save()){ 920b308644SOtto Vainio if($conf['fperm']) chmod($src, $conf['fperm']); 93ac3ed4afSGerrit Uitslag @clearstatcache(true, $src); 94cf832786SKate Arzamastseva $new = @filemtime($src); 95ac3ed4afSGerrit Uitslag $filesize_new = filesize($src); 96ac3ed4afSGerrit Uitslag $sizechange = $filesize_new - $filesize_old; 97ac3ed4afSGerrit Uitslag 98cf832786SKate Arzamastseva // add a log entry to the media changelog 99ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited'], '', null, $sizechange); 100cf832786SKate Arzamastseva 1013df72098SAndreas Gohr msg($lang['metasaveok'],1); 1023df72098SAndreas Gohr return $id; 1033df72098SAndreas Gohr }else{ 1043df72098SAndreas Gohr msg($lang['metasaveerr'],-1); 1053df72098SAndreas Gohr return false; 1063df72098SAndreas Gohr } 1073df72098SAndreas Gohr} 1083df72098SAndreas Gohr 1093df72098SAndreas Gohr/** 110d54f7963SKlap-in * check if a media is external source 111d54f7963SKlap-in * 112d54f7963SKlap-in * @author Gerrit Uitslag <klapinklapin@gmail.com> 11342ea7f44SGerrit Uitslag * 114d54f7963SKlap-in * @param string $id the media ID or URL 115d54f7963SKlap-in * @return bool 116d54f7963SKlap-in */ 117d54f7963SKlap-infunction media_isexternal($id){ 118fe578fe9SElan Ruusamäe if (preg_match('#^(?:https?|ftp)://#i', $id)) return true; 119d54f7963SKlap-in return false; 120d54f7963SKlap-in} 121d54f7963SKlap-in 122d54f7963SKlap-in/** 123add8678fSAndreas Gohr * Check if a media item is public (eg, external URL or readable by @ALL) 124add8678fSAndreas Gohr * 125add8678fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 12642ea7f44SGerrit Uitslag * 127add8678fSAndreas Gohr * @param string $id the media ID or URL 128add8678fSAndreas Gohr * @return bool 129add8678fSAndreas Gohr */ 130add8678fSAndreas Gohrfunction media_ispublic($id){ 131d54f7963SKlap-in if(media_isexternal($id)) return true; 132add8678fSAndreas Gohr $id = cleanID($id); 133*24870174SAndreas Gohr if(auth_aclcheck(getNS($id).':*', '', []) >= AUTH_READ) return true; 134add8678fSAndreas Gohr return false; 135add8678fSAndreas Gohr} 136add8678fSAndreas Gohr 137add8678fSAndreas Gohr/** 1383df72098SAndreas Gohr * Display the form to edit image meta data 1393df72098SAndreas Gohr * 1403df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 141d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 142e0c26282SGerrit Uitslag * 143e0c26282SGerrit Uitslag * @param string $id media id 144e0c26282SGerrit Uitslag * @param int $auth permission level 145e0c26282SGerrit Uitslag * @return bool 1463df72098SAndreas Gohr */ 14730fd72fbSKate Arzamastsevafunction media_metaform($id, $auth) { 148ebc28e69SAndreas Gohr global $lang; 1493df72098SAndreas Gohr 15088a71175SKate Arzamastseva if ($auth < AUTH_UPLOAD) { 151b960c74fSSatoshi Sahara echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.DOKU_LF; 15288a71175SKate Arzamastseva return false; 15388a71175SKate Arzamastseva } 15488a71175SKate Arzamastseva 1553df72098SAndreas Gohr // load the field descriptions 1563df72098SAndreas Gohr static $fields = null; 157b960c74fSSatoshi Sahara if ($fields === null) { 1583e98e685SKate Arzamastseva $config_files = getConfigFiles('mediameta'); 1593e98e685SKate Arzamastseva foreach ($config_files as $config_file) { 16079e79377SAndreas Gohr if (file_exists($config_file)) include($config_file); 1613df72098SAndreas Gohr } 1623df72098SAndreas Gohr } 1633df72098SAndreas Gohr 1643df72098SAndreas Gohr $src = mediaFN($id); 1653df72098SAndreas Gohr 1663df72098SAndreas Gohr // output 167b960c74fSSatoshi Sahara $form = new Form([ 168b960c74fSSatoshi Sahara 'action' => media_managerURL(['tab_details' => 'view'], '&'), 169b960c74fSSatoshi Sahara 'class' => 'meta' 170b960c74fSSatoshi Sahara ]); 171b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 172b960c74fSSatoshi Sahara $form->setHiddenField('img', $id); 173b960c74fSSatoshi Sahara $form->setHiddenField('mediado', 'save'); 1743df72098SAndreas Gohr foreach ($fields as $key => $field) { 1753df72098SAndreas Gohr // get current value 1763e98e685SKate Arzamastseva if (empty($field[0])) continue; 177*24870174SAndreas Gohr $tags = [$field[0]]; 1783df72098SAndreas Gohr if (is_array($field[3])) $tags = array_merge($tags, $field[3]); 1793df72098SAndreas Gohr $value = tpl_img_getTag($tags, '', $src); 180ca6a0701SAndreas Gohr $value = cleanText($value); 1813df72098SAndreas Gohr 1823df72098SAndreas Gohr // prepare attributes 183*24870174SAndreas Gohr $p = [ 184b960c74fSSatoshi Sahara 'class' => 'edit', 185b960c74fSSatoshi Sahara 'id' => 'meta__'.$key, 186*24870174SAndreas Gohr 'name' => 'meta['.$field[0].']' 187*24870174SAndreas Gohr ]; 1883df72098SAndreas Gohr 189b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('row'); 1903df72098SAndreas Gohr if ($field[2] == 'text') { 191bde2a644SSatoshi Sahara $form->addTextInput( 19264159a61SAndreas Gohr $p['name'], 19379a2d784SGerrit Uitslag ($lang[$field[1]] ?: $field[1] . ':') 194b960c74fSSatoshi Sahara )->id($p['id'])->addClass($p['class'])->val($value); 1953df72098SAndreas Gohr } else { 196b960c74fSSatoshi Sahara $form->addTextarea($p['name'], $lang[$field[1]])->id($p['id']) 197b960c74fSSatoshi Sahara ->val(formText($value)) 198b960c74fSSatoshi Sahara ->addClass($p['class']) 199b960c74fSSatoshi Sahara ->attr('rows', '6')->attr('cols', '50'); 2003df72098SAndreas Gohr } 201b960c74fSSatoshi Sahara $form->addTagClose('div'); 2023df72098SAndreas Gohr } 203b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('buttons'); 204b960c74fSSatoshi Sahara $form->addButton('mediado[save]', $lang['btn_save'])->attr('type', 'submit') 205b960c74fSSatoshi Sahara ->attrs(['accesskey' => 's']); 206b960c74fSSatoshi Sahara $form->addTagClose('div'); 207ebc28e69SAndreas Gohr 208b960c74fSSatoshi Sahara $form->addTagClose('div'); 209b960c74fSSatoshi Sahara echo $form->toHTML(); 210ebc28e69SAndreas Gohr return true; 2113df72098SAndreas Gohr} 2123df72098SAndreas Gohr 213666cdec5SMichael Klier/** 21487229c84SAdrian Lang * Convenience function to check if a media file is still in use 215666cdec5SMichael Klier * 216666cdec5SMichael Klier * @author Michael Klier <chi@chimeric.de> 217e0c26282SGerrit Uitslag * 218e0c26282SGerrit Uitslag * @param string $id media id 219e0c26282SGerrit Uitslag * @return array|bool 220666cdec5SMichael Klier */ 221666cdec5SMichael Klierfunction media_inuse($id) { 222666cdec5SMichael Klier global $conf; 223ebc28e69SAndreas Gohr 224666cdec5SMichael Klier if($conf['refcheck']){ 225ffec1009SMichael Hamann $mediareferences = ft_mediause($id,true); 226*24870174SAndreas Gohr if($mediareferences === []) { 2276dae2464SAndreas Gohr return false; 228666cdec5SMichael Klier } else { 229666cdec5SMichael Klier return $mediareferences; 230666cdec5SMichael Klier } 231666cdec5SMichael Klier } else { 232666cdec5SMichael Klier return false; 233666cdec5SMichael Klier } 234666cdec5SMichael Klier} 235a05e297aSAndreas Gohr 2363df72098SAndreas Gohr/** 2373df72098SAndreas Gohr * Handles media file deletions 2383df72098SAndreas Gohr * 2393df72098SAndreas Gohr * If configured, checks for media references before deletion 2403df72098SAndreas Gohr * 2413df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 24242ea7f44SGerrit Uitslag * 243ebc28e69SAndreas Gohr * @param string $id media id 24422db8df7SAndreas Gohr * @param int $auth no longer used 24587229c84SAdrian Lang * @return int One of: 0, 24663703ba5SAndreas Gohr * DOKU_MEDIA_DELETED, 24763703ba5SAndreas Gohr * DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS, 24863703ba5SAndreas Gohr * DOKU_MEDIA_NOT_AUTH, 24963703ba5SAndreas Gohr * DOKU_MEDIA_INUSE 2503df72098SAndreas Gohr */ 2513df72098SAndreas Gohrfunction media_delete($id,$auth){ 2526183fb05SKate Arzamastseva global $lang; 253ff04e8b7SAndreas Gohr $auth = auth_quickaclcheck(ltrim(getNS($id).':*', ':')); 25487229c84SAdrian Lang if($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; 25587229c84SAdrian Lang if(media_inuse($id)) return DOKU_MEDIA_INUSE; 2563df72098SAndreas Gohr 2573df72098SAndreas Gohr $file = mediaFN($id); 2584a961e72SMichal Kolodziejski 2594a961e72SMichal Kolodziejski // trigger an event - MEDIA_DELETE_FILE 260*24870174SAndreas Gohr $data = []; 261666cdec5SMichael Klier $data['id'] = $id; 26279a2d784SGerrit Uitslag $data['name'] = PhpString::basename($file); 2634a961e72SMichal Kolodziejski $data['path'] = $file; 26479e79377SAndreas Gohr $data['size'] = (file_exists($file)) ? filesize($file) : 0; 265666cdec5SMichael Klier 266666cdec5SMichael Klier $data['unl'] = false; 267666cdec5SMichael Klier $data['del'] = false; 268e1d9dcc8SAndreas Gohr $evt = new Event('MEDIA_DELETE_FILE',$data); 2694a961e72SMichal Kolodziejski if ($evt->advise_before()) { 2706183fb05SKate Arzamastseva $old = @filemtime($file); 27179e79377SAndreas Gohr if(!file_exists(mediaFN($id, $old)) && file_exists($file)) { 2726183fb05SKate Arzamastseva // add old revision to the attic 2736183fb05SKate Arzamastseva media_saveOldRevision($id); 2746183fb05SKate Arzamastseva } 2756183fb05SKate Arzamastseva 276666cdec5SMichael Klier $data['unl'] = @unlink($file); 277666cdec5SMichael Klier if($data['unl']) { 278ac3ed4afSGerrit Uitslag $sizechange = 0 - $data['size']; 279ac3ed4afSGerrit Uitslag addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted'], '', null, $sizechange); 280ac3ed4afSGerrit Uitslag 281666cdec5SMichael Klier $data['del'] = io_sweepNS($id, 'mediadir'); 2823df72098SAndreas Gohr } 2834a961e72SMichal Kolodziejski } 2844a961e72SMichal Kolodziejski $evt->advise_after(); 2854a961e72SMichal Kolodziejski unset($evt); 2864a961e72SMichal Kolodziejski 287666cdec5SMichael Klier if($data['unl'] && $data['del']){ 28887229c84SAdrian Lang return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS; 2893df72098SAndreas Gohr } 2903df72098SAndreas Gohr 29187229c84SAdrian Lang return $data['unl'] ? DOKU_MEDIA_DELETED : 0; 2923df72098SAndreas Gohr} 2933df72098SAndreas Gohr 2943df72098SAndreas Gohr/** 2952d6cc64fSKate Arzamastseva * Handle file uploads via XMLHttpRequest 2962d6cc64fSKate Arzamastseva * 297ebc28e69SAndreas Gohr * @param string $ns target namespace 298ebc28e69SAndreas Gohr * @param int $auth current auth check result 29942ea7f44SGerrit Uitslag * @return false|string false on error, id of the new file on success 3002d6cc64fSKate Arzamastseva */ 3012d6cc64fSKate Arzamastsevafunction media_upload_xhr($ns,$auth){ 302da45d883SKate Arzamastseva if(!checkSecurityToken()) return false; 3038108113cSTom N Harris global $INPUT; 304da45d883SKate Arzamastseva 3058108113cSTom N Harris $id = $INPUT->get->str('qqfile'); 306*24870174SAndreas Gohr [$ext, $mime] = mimetype($id); 3072d6cc64fSKate Arzamastseva $input = fopen("php://input", "r"); 3082d6cc64fSKate Arzamastseva if (!($tmp = io_mktmpdir())) return false; 30962231793SKate Arzamastseva $path = $tmp.'/'.md5($id); 3102d6cc64fSKate Arzamastseva $target = fopen($path, "w"); 311063fb5b5SAndreas Gohr $realSize = stream_copy_to_stream($input, $target); 3122d6cc64fSKate Arzamastseva fclose($target); 313063fb5b5SAndreas Gohr fclose($input); 3142b9be456SAndreas Gohr if ($INPUT->server->has('CONTENT_LENGTH') && ($realSize != $INPUT->server->int('CONTENT_LENGTH'))) { 315063fb5b5SAndreas Gohr unlink($path); 316063fb5b5SAndreas Gohr return false; 317063fb5b5SAndreas Gohr } 318063fb5b5SAndreas Gohr 3192d6cc64fSKate Arzamastseva $res = media_save( 320*24870174SAndreas Gohr ['name' => $path, 'mime' => $mime, 'ext' => $ext], 3212d6cc64fSKate Arzamastseva $ns.':'.$id, 32279a2d784SGerrit Uitslag ($INPUT->get->str('ow') == 'true'), 3232d6cc64fSKate Arzamastseva $auth, 3242d6cc64fSKate Arzamastseva 'copy' 3252d6cc64fSKate Arzamastseva ); 3262d6cc64fSKate Arzamastseva unlink($path); 327900a9e9eSGerrit Uitslag if ($tmp) io_rmdir($tmp, true); 3282d6cc64fSKate Arzamastseva if (is_array($res)) { 3292d6cc64fSKate Arzamastseva msg($res[0], $res[1]); 3302d6cc64fSKate Arzamastseva return false; 3312d6cc64fSKate Arzamastseva } 3322d6cc64fSKate Arzamastseva return $res; 3332d6cc64fSKate Arzamastseva} 3342d6cc64fSKate Arzamastseva 3352d6cc64fSKate Arzamastseva/** 3363df72098SAndreas Gohr * Handles media file uploads 3373df72098SAndreas Gohr * 3383df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 33911d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 34042ea7f44SGerrit Uitslag * 341ebc28e69SAndreas Gohr * @param string $ns target namespace 342ebc28e69SAndreas Gohr * @param int $auth current auth check result 343ebc28e69SAndreas Gohr * @param bool|array $file $_FILES member, $_FILES['upload'] if false 34442ea7f44SGerrit Uitslag * @return false|string false on error, id of the new file on success 3453df72098SAndreas Gohr */ 3462d6cc64fSKate Arzamastsevafunction media_upload($ns,$auth,$file=false){ 347f2ea8432SAndreas Gohr if(!checkSecurityToken()) return false; 3483df72098SAndreas Gohr global $lang; 3498108113cSTom N Harris global $INPUT; 3503df72098SAndreas Gohr 35144409c3dSAndreas Gohr // get file and id 3528108113cSTom N Harris $id = $INPUT->post->str('mediaid'); 3532d6cc64fSKate Arzamastseva if (!$file) $file = $_FILES['upload']; 3543df72098SAndreas Gohr if(empty($id)) $id = $file['name']; 35544409c3dSAndreas Gohr 35699766eefSAndreas Gohr // check for errors (messages are done in lib/exe/mediamanager.php) 35799766eefSAndreas Gohr if($file['error']) return false; 3589676dc23SAndreas Gohr 35944409c3dSAndreas Gohr // check extensions 360*24870174SAndreas Gohr [$fext, $fmime] = mimetype($file['name']); 361*24870174SAndreas Gohr [$iext, $imime] = mimetype($id); 36244409c3dSAndreas Gohr if($fext && !$iext){ 3638cb1eb01SAndreas Gohr // no extension specified in id - read original one 36444409c3dSAndreas Gohr $id .= '.'.$fext; 3658cb1eb01SAndreas Gohr $imime = $fmime; 36644409c3dSAndreas Gohr }elseif($fext && $fext != $iext){ 36744409c3dSAndreas Gohr // extension was changed, print warning 36844409c3dSAndreas Gohr msg(sprintf($lang['mediaextchange'],$fext,$iext)); 36944409c3dSAndreas Gohr } 37044409c3dSAndreas Gohr 371*24870174SAndreas Gohr $res = media_save( 372*24870174SAndreas Gohr [ 373*24870174SAndreas Gohr 'name' => $file['tmp_name'], 374ffb291f2SAdrian Lang 'mime' => $imime, 375*24870174SAndreas Gohr 'ext' => $iext 376*24870174SAndreas Gohr ], 377*24870174SAndreas Gohr $ns . ':' . $id, 378*24870174SAndreas Gohr $INPUT->post->bool('ow'), 379*24870174SAndreas Gohr $auth, 380*24870174SAndreas Gohr 'copy_uploaded_file' 381*24870174SAndreas Gohr ); 382ffb291f2SAdrian Lang if (is_array($res)) { 383ffb291f2SAdrian Lang msg($res[0], $res[1]); 384ffb291f2SAdrian Lang return false; 385ffb291f2SAdrian Lang } 386ffb291f2SAdrian Lang return $res; 387ffb291f2SAdrian Lang} 388ffb291f2SAdrian Lang 389ffb291f2SAdrian Lang/** 39071f17ac4SAndreas Gohr * An alternative to move_uploaded_file that copies 39171f17ac4SAndreas Gohr * 39271f17ac4SAndreas Gohr * Using copy, makes sure any setgid bits on the media directory are honored 39371f17ac4SAndreas Gohr * 39471f17ac4SAndreas Gohr * @see move_uploaded_file() 39542ea7f44SGerrit Uitslag * 39671f17ac4SAndreas Gohr * @param string $from 39771f17ac4SAndreas Gohr * @param string $to 39871f17ac4SAndreas Gohr * @return bool 39971f17ac4SAndreas Gohr */ 40071f17ac4SAndreas Gohrfunction copy_uploaded_file($from, $to){ 40171f17ac4SAndreas Gohr if(!is_uploaded_file($from)) return false; 40271f17ac4SAndreas Gohr $ok = copy($from, $to); 40371f17ac4SAndreas Gohr @unlink($from); 40471f17ac4SAndreas Gohr return $ok; 40571f17ac4SAndreas Gohr} 40671f17ac4SAndreas Gohr 40771f17ac4SAndreas Gohr/** 408ffb291f2SAdrian Lang * This generates an action event and delegates to _media_upload_action(). 409ffb291f2SAdrian Lang * Action plugins are allowed to pre/postprocess the uploaded file. 410ffb291f2SAdrian Lang * (The triggered event is preventable.) 411ffb291f2SAdrian Lang * 412ffb291f2SAdrian Lang * Event data: 413ffb291f2SAdrian Lang * $data[0] fn_tmp: the temporary file name (read from $_FILES) 414ffb291f2SAdrian Lang * $data[1] fn: the file name of the uploaded file 415ffb291f2SAdrian Lang * $data[2] id: the future directory id of the uploaded file 416ffb291f2SAdrian Lang * $data[3] imime: the mimetype of the uploaded file 417ffb291f2SAdrian Lang * $data[4] overwrite: if an existing file is going to be overwritten 41852a281e8SGerrit Uitslag * $data[5] move: name of function that performs move/copy/.. 419ffb291f2SAdrian Lang * 420ffb291f2SAdrian Lang * @triggers MEDIA_UPLOAD_FINISH 42142ea7f44SGerrit Uitslag * 422e0c26282SGerrit Uitslag * @param array $file 42352a281e8SGerrit Uitslag * @param string $id media id 42442ea7f44SGerrit Uitslag * @param bool $ow overwrite? 425e0c26282SGerrit Uitslag * @param int $auth permission level 42652a281e8SGerrit Uitslag * @param string $move name of functions that performs move/copy/.. 42742ea7f44SGerrit Uitslag * @return false|array|string 428e0c26282SGerrit Uitslag */ 429ffb291f2SAdrian Langfunction media_save($file, $id, $ow, $auth, $move) { 430ffb291f2SAdrian Lang if($auth < AUTH_UPLOAD) { 431*24870174SAndreas Gohr return ["You don't have permissions to upload files.", -1]; 432ffb291f2SAdrian Lang } 433ffb291f2SAdrian Lang 434ffb291f2SAdrian Lang if (!isset($file['mime']) || !isset($file['ext'])) { 435*24870174SAndreas Gohr [$ext, $mime] = mimetype($id); 436ffb291f2SAdrian Lang if (!isset($file['mime'])) { 437ffb291f2SAdrian Lang $file['mime'] = $mime; 438ffb291f2SAdrian Lang } 439ffb291f2SAdrian Lang if (!isset($file['ext'])) { 440ffb291f2SAdrian Lang $file['ext'] = $ext; 441ffb291f2SAdrian Lang } 442ffb291f2SAdrian Lang } 443ffb291f2SAdrian Lang 44492cac9a9SKate Arzamastseva global $lang, $conf; 445ffb291f2SAdrian Lang 4463df72098SAndreas Gohr // get filename 4473543c6deSAndreas Gohr $id = cleanID($id); 4483df72098SAndreas Gohr $fn = mediaFN($id); 4493df72098SAndreas Gohr 4503df72098SAndreas Gohr // get filetype regexp 4513df72098SAndreas Gohr $types = array_keys(getMimeTypes()); 452bad6fc0dSAndreas Gohr $types = array_map( 453*24870174SAndreas Gohr static fn($q) => preg_quote($q, "/"), 454bad6fc0dSAndreas Gohr $types 455bad6fc0dSAndreas Gohr ); 456*24870174SAndreas Gohr $regex = implode('|',$types); 4573df72098SAndreas Gohr 4583df72098SAndreas Gohr // because a temp file was created already 459ffb291f2SAdrian Lang if(!preg_match('/\.('.$regex.')$/i',$fn)) { 460*24870174SAndreas Gohr return [$lang['uploadwrong'], -1]; 461ffb291f2SAdrian Lang } 462ffb291f2SAdrian Lang 4633df72098SAndreas Gohr //check for overwrite 46479e79377SAndreas Gohr $overwrite = file_exists($fn); 465e5d185e1SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 466e5d185e1SKate Arzamastseva if($overwrite && (!$ow || $auth < $auth_ow)) { 467*24870174SAndreas Gohr return [$lang['uploadexist'], 0]; 4683df72098SAndreas Gohr } 4698cb1eb01SAndreas Gohr // check for valid content 470ffb291f2SAdrian Lang $ok = media_contentcheck($file['name'], $file['mime']); 4718cb1eb01SAndreas Gohr if($ok == -1){ 472*24870174SAndreas Gohr return [sprintf($lang['uploadbadcontent'],'.' . $file['ext']), -1]; 4738cb1eb01SAndreas Gohr }elseif($ok == -2){ 474*24870174SAndreas Gohr return [$lang['uploadspam'], -1]; 47526ceae18SAndreas Gohr }elseif($ok == -3){ 476*24870174SAndreas Gohr return [$lang['uploadxss'], -1]; 4778cb1eb01SAndreas Gohr } 4788cb1eb01SAndreas Gohr 47911d9dfa5SMichael Klier // prepare event data 480*24870174SAndreas Gohr $data = []; 481ffb291f2SAdrian Lang $data[0] = $file['name']; 48211d9dfa5SMichael Klier $data[1] = $fn; 48311d9dfa5SMichael Klier $data[2] = $id; 484ffb291f2SAdrian Lang $data[3] = $file['mime']; 48599c8d7f2Smichael $data[4] = $overwrite; 486ffb291f2SAdrian Lang $data[5] = $move; 48711d9dfa5SMichael Klier 48811d9dfa5SMichael Klier // trigger event 489cbb44eabSAndreas Gohr return Event::createAndTrigger('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); 49011d9dfa5SMichael Klier} 49111d9dfa5SMichael Klier 49211d9dfa5SMichael Klier/** 49342ea7f44SGerrit Uitslag * Callback adapter for media_upload_finish() triggered by MEDIA_UPLOAD_FINISH 49442ea7f44SGerrit Uitslag * 49511d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 49642ea7f44SGerrit Uitslag * 49742ea7f44SGerrit Uitslag * @param array $data event data 49842ea7f44SGerrit Uitslag * @return false|array|string 49911d9dfa5SMichael Klier */ 50011d9dfa5SMichael Klierfunction _media_upload_action($data) { 50111d9dfa5SMichael Klier // fixme do further sanity tests of given data? 502ffb291f2SAdrian Lang if(is_array($data) && count($data)===6) { 503ffb291f2SAdrian Lang return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 50411d9dfa5SMichael Klier } else { 50511d9dfa5SMichael Klier return false; //callback error 50611d9dfa5SMichael Klier } 50711d9dfa5SMichael Klier} 50811d9dfa5SMichael Klier 50911d9dfa5SMichael Klier/** 51011d9dfa5SMichael Klier * Saves an uploaded media file 51111d9dfa5SMichael Klier * 51211d9dfa5SMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 51311d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 514cbe26ad6SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 51542ea7f44SGerrit Uitslag * 51642ea7f44SGerrit Uitslag * @param string $fn_tmp 51742ea7f44SGerrit Uitslag * @param string $fn 51842ea7f44SGerrit Uitslag * @param string $id media id 51942ea7f44SGerrit Uitslag * @param string $imime mime type 52042ea7f44SGerrit Uitslag * @param bool $overwrite overwrite existing? 52142ea7f44SGerrit Uitslag * @param string $move function name 52242ea7f44SGerrit Uitslag * @return array|string 52311d9dfa5SMichael Klier */ 524ffb291f2SAdrian Langfunction media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') { 52511d9dfa5SMichael Klier global $conf; 52611d9dfa5SMichael Klier global $lang; 5279c1bd4bcSKate Arzamastseva global $REV; 52811d9dfa5SMichael Klier 529e4f389efSKate Arzamastseva $old = @filemtime($fn); 53079e79377SAndreas Gohr if(!file_exists(mediaFN($id, $old)) && file_exists($fn)) { 531e4f389efSKate Arzamastseva // add old revision to the attic if missing 532cbe26ad6SKate Arzamastseva media_saveOldRevision($id); 533e4f389efSKate Arzamastseva } 534e4f389efSKate Arzamastseva 5353df72098SAndreas Gohr // prepare directory 536cc7d0c94SBen Coburn io_createNamespace($id, 'media'); 53711d9dfa5SMichael Klier 538ac3ed4afSGerrit Uitslag $filesize_old = file_exists($fn) ? filesize($fn) : 0; 539ac3ed4afSGerrit Uitslag 540ffb291f2SAdrian Lang if($move($fn_tmp, $fn)) { 54123846a98SKate Arzamastseva @clearstatcache(true,$fn); 542dad6764eSKate Arzamastseva $new = @filemtime($fn); 54374400ea5SBen Coburn // Set the correct permission here. 54474400ea5SBen Coburn // Always chmod media because they may be saved with different permissions than expected from the php umask. 54574400ea5SBen Coburn // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 54674400ea5SBen Coburn chmod($fn, $conf['fmode']); 5473df72098SAndreas Gohr msg($lang['uploadsucc'],1); 54883734cddSPhy media_notify($id,$fn,$imime,$old,$new); 54999c8d7f2Smichael // add a log entry to the media changelog 550ac3ed4afSGerrit Uitslag $filesize_new = filesize($fn); 551ac3ed4afSGerrit Uitslag $sizechange = $filesize_new - $filesize_old; 5529c1bd4bcSKate Arzamastseva if($REV) { 55364159a61SAndreas Gohr addMediaLogEntry( 55464159a61SAndreas Gohr $new, 55564159a61SAndreas Gohr $id, 55664159a61SAndreas Gohr DOKU_CHANGE_TYPE_REVERT, 55764159a61SAndreas Gohr sprintf($lang['restored'], dformat($REV)), 55864159a61SAndreas Gohr $REV, 55964159a61SAndreas Gohr null, 56064159a61SAndreas Gohr $sizechange 56164159a61SAndreas Gohr ); 5629c1bd4bcSKate Arzamastseva } elseif($overwrite) { 563ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); 56499c8d7f2Smichael } else { 565ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); 56699c8d7f2Smichael } 5673df72098SAndreas Gohr return $id; 5683df72098SAndreas Gohr }else{ 569*24870174SAndreas Gohr return [$lang['uploadfail'], -1]; 5703df72098SAndreas Gohr } 5713df72098SAndreas Gohr} 5723df72098SAndreas Gohr 5738cb1eb01SAndreas Gohr/** 574cbe26ad6SKate Arzamastseva * Moves the current version of media file to the media_attic 575cbe26ad6SKate Arzamastseva * directory 576cbe26ad6SKate Arzamastseva * 577cbe26ad6SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 57842ea7f44SGerrit Uitslag * 579cbe26ad6SKate Arzamastseva * @param string $id 580cbe26ad6SKate Arzamastseva * @return int - revision date 581e4f389efSKate Arzamastseva */ 582cbe26ad6SKate Arzamastsevafunction media_saveOldRevision($id) { 583dbf57c96SKate Arzamastseva global $conf, $lang; 584dbf57c96SKate Arzamastseva 585e4f389efSKate Arzamastseva $oldf = mediaFN($id); 58679e79377SAndreas Gohr if (!file_exists($oldf)) return ''; 587e4f389efSKate Arzamastseva $date = filemtime($oldf); 588e5d185e1SKate Arzamastseva if (!$conf['mediarevisions']) return $date; 589e5d185e1SKate Arzamastseva 590047bad06SGerrit Uitslag $medialog = new MediaChangeLog($id); 591047bad06SGerrit Uitslag if (!$medialog->getRevisionInfo($date)) { 592dbf57c96SKate Arzamastseva // there was an external edit, 593dbf57c96SKate Arzamastseva // there is no log entry for current version of file 594ac3ed4afSGerrit Uitslag $sizechange = filesize($oldf); 59579e79377SAndreas Gohr if(!file_exists(mediaMetaFN($id, '.changes'))) { 596ac3ed4afSGerrit Uitslag addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); 597dbf57c96SKate Arzamastseva } else { 598ac3ed4afSGerrit Uitslag $oldRev = $medialog->getRevisions(-1, 1); // from changelog 599ac3ed4afSGerrit Uitslag $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]); 600ac3ed4afSGerrit Uitslag $filesize_old = filesize(mediaFN($id, $oldRev)); 601*24870174SAndreas Gohr $sizechange -= $filesize_old; 602ac3ed4afSGerrit Uitslag 603ac3ed4afSGerrit Uitslag addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); 604dbf57c96SKate Arzamastseva } 605dbf57c96SKate Arzamastseva } 606dbf57c96SKate Arzamastseva 607e4f389efSKate Arzamastseva $newf = mediaFN($id, $date); 608e4f389efSKate Arzamastseva io_makeFileDir($newf); 609cbe26ad6SKate Arzamastseva if (copy($oldf, $newf)) { 610e4f389efSKate Arzamastseva // Set the correct permission here. 611e4f389efSKate Arzamastseva // Always chmod media because they may be saved with different permissions than expected from the php umask. 612e4f389efSKate Arzamastseva // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 613e4f389efSKate Arzamastseva chmod($newf, $conf['fmode']); 614e4f389efSKate Arzamastseva } 615e4f389efSKate Arzamastseva return $date; 616e4f389efSKate Arzamastseva} 617e4f389efSKate Arzamastseva 618e4f389efSKate Arzamastseva/** 6198cb1eb01SAndreas Gohr * This function checks if the uploaded content is really what the 62026ceae18SAndreas Gohr * mimetype says it is. We also do spam checking for text types here. 6218cb1eb01SAndreas Gohr * 6228cb1eb01SAndreas Gohr * We need to do this stuff because we can not rely on the browser 6238cb1eb01SAndreas Gohr * to do this check correctly. Yes, IE is broken as usual. 6248cb1eb01SAndreas Gohr * 6258cb1eb01SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 62626ceae18SAndreas Gohr * @link http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting 6278cb1eb01SAndreas Gohr * @fixme check all 26 magic IE filetypes here? 62842ea7f44SGerrit Uitslag * 62942ea7f44SGerrit Uitslag * @param string $file path to file 63042ea7f44SGerrit Uitslag * @param string $mime mimetype 63142ea7f44SGerrit Uitslag * @return int 6328cb1eb01SAndreas Gohr */ 6338cb1eb01SAndreas Gohrfunction media_contentcheck($file,$mime){ 63426ceae18SAndreas Gohr global $conf; 63526ceae18SAndreas Gohr if($conf['iexssprotect']){ 63626ceae18SAndreas Gohr $fh = @fopen($file, 'rb'); 63726ceae18SAndreas Gohr if($fh){ 63826ceae18SAndreas Gohr $bytes = fread($fh, 256); 63926ceae18SAndreas Gohr fclose($fh); 64026ceae18SAndreas Gohr if(preg_match('/<(script|a|img|html|body|iframe)[\s>]/i',$bytes)){ 64142ea7f44SGerrit Uitslag return -3; //XSS: possibly malicious content 64226ceae18SAndreas Gohr } 64326ceae18SAndreas Gohr } 64426ceae18SAndreas Gohr } 6458cb1eb01SAndreas Gohr if(substr($mime,0,6) == 'image/'){ 6468cb1eb01SAndreas Gohr $info = @getimagesize($file); 6478cb1eb01SAndreas Gohr if($mime == 'image/gif' && $info[2] != 1){ 64842ea7f44SGerrit Uitslag return -1; // uploaded content did not match the file extension 6498cb1eb01SAndreas Gohr }elseif($mime == 'image/jpeg' && $info[2] != 2){ 6508cb1eb01SAndreas Gohr return -1; 6518cb1eb01SAndreas Gohr }elseif($mime == 'image/png' && $info[2] != 3){ 6528cb1eb01SAndreas Gohr return -1; 6538cb1eb01SAndreas Gohr } 6548cb1eb01SAndreas Gohr # fixme maybe check other images types as well 6558cb1eb01SAndreas Gohr }elseif(substr($mime,0,5) == 'text/'){ 6568cb1eb01SAndreas Gohr global $TEXT; 6578cb1eb01SAndreas Gohr $TEXT = io_readFile($file); 6588cb1eb01SAndreas Gohr if(checkwordblock()){ 65942ea7f44SGerrit Uitslag return -2; //blocked by the spam blacklist 6608cb1eb01SAndreas Gohr } 6618cb1eb01SAndreas Gohr } 6628cb1eb01SAndreas Gohr return 0; 6638cb1eb01SAndreas Gohr} 6643df72098SAndreas Gohr 6653df72098SAndreas Gohr/** 66675030359SAndreas Gohr * Send a notify mail on uploads 66775030359SAndreas Gohr * 66875030359SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 66942ea7f44SGerrit Uitslag * 67042ea7f44SGerrit Uitslag * @param string $id media id 67142ea7f44SGerrit Uitslag * @param string $file path to file 67242ea7f44SGerrit Uitslag * @param string $mime mime type 67342ea7f44SGerrit Uitslag * @param bool|int $old_rev revision timestamp or false 67475030359SAndreas Gohr */ 67583734cddSPhyfunction media_notify($id,$file,$mime,$old_rev=false,$current_rev=false){ 67675030359SAndreas Gohr global $conf; 67779a2d784SGerrit Uitslag if(empty($conf['notify'])) return; //notify enabled? 67875030359SAndreas Gohr 679704a815fSMichael Große $subscription = new MediaSubscriptionSender(); 68079a2d784SGerrit Uitslag $subscription->sendMediaDiff($conf['notify'], 'uploadmail', $id, $old_rev, $current_rev); 68175030359SAndreas Gohr} 68275030359SAndreas Gohr 68375030359SAndreas Gohr/** 6843df72098SAndreas Gohr * List all files in a given Media namespace 68542ea7f44SGerrit Uitslag * 68621d806cdSGerrit Uitslag * @param string $ns namespace 68742ea7f44SGerrit Uitslag * @param null|int $auth permission level 68842ea7f44SGerrit Uitslag * @param string $jump id 68942ea7f44SGerrit Uitslag * @param bool $fullscreenview 6908702de7fSGerrit Uitslag * @param bool|string $sort sorting order, false skips sorting 6913df72098SAndreas Gohr */ 692abc306f4SKate Arzamastsevafunction media_filelist($ns,$auth=null,$jump='',$fullscreenview=false,$sort=false){ 6933df72098SAndreas Gohr global $conf; 6943df72098SAndreas Gohr global $lang; 6953df72098SAndreas Gohr $ns = cleanID($ns); 6963df72098SAndreas Gohr 6973df72098SAndreas Gohr // check auth our self if not given (needed for ajax calls) 6983df72098SAndreas Gohr if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 6993df72098SAndreas Gohr 700d9162c6cSKate Arzamastseva if (!$fullscreenview) echo '<h1 id="media__ns">:'.hsc($ns).'</h1>'.NL; 7013df72098SAndreas Gohr 7023df72098SAndreas Gohr if($auth < AUTH_READ){ 7033df72098SAndreas Gohr // FIXME: print permission warning here instead? 7043df72098SAndreas Gohr echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 70556fe6664SAndreas Gohr }else{ 70689274c0dSChristopher Smith if (!$fullscreenview) { 70789274c0dSChristopher Smith media_uploadform($ns, $auth); 70889274c0dSChristopher Smith media_searchform($ns); 70989274c0dSChristopher Smith } 7103df72098SAndreas Gohr 7113df72098SAndreas Gohr $dir = utf8_encodeFN(str_replace(':','/',$ns)); 712*24870174SAndreas Gohr $data = []; 7134f33babfSAndreas Gohr search($data,$conf['mediadir'],'search_mediafiles', 714*24870174SAndreas Gohr ['showmsg'=>true, 'depth'=>1],$dir,1,$sort); 7153df72098SAndreas Gohr 7163df72098SAndreas Gohr if(!count($data)){ 7173df72098SAndreas Gohr echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 7185b9353faSKate Arzamastseva }else { 7195b9353faSKate Arzamastseva if ($fullscreenview) { 720554a8c9fSAdrian Lang echo '<ul class="' . _media_get_list_type() . '">'; 7215b9353faSKate Arzamastseva } 7225b9353faSKate Arzamastseva foreach($data as $item){ 7235b9353faSKate Arzamastseva if (!$fullscreenview) { 7244f33babfSAndreas Gohr //FIXME old call: media_printfile($item,$auth,$jump); 72579a2d784SGerrit Uitslag $display = new DisplayRow($item); 7269453716dSAndreas Gohr $display->scrollIntoView($jump == $item->getID()); 7274f33babfSAndreas Gohr $display->show(); 7285b9353faSKate Arzamastseva } else { 7294f33babfSAndreas Gohr //FIXME old call: media_printfile_thumbs($item,$auth,$jump); 7304f33babfSAndreas Gohr echo '<li>'; 73179a2d784SGerrit Uitslag $display = new DisplayTile($item); 7329453716dSAndreas Gohr $display->scrollIntoView($jump == $item->getID()); 7334f33babfSAndreas Gohr $display->show(); 7344f33babfSAndreas Gohr echo '</li>'; 7355b9353faSKate Arzamastseva } 7365b9353faSKate Arzamastseva } 73794add303SAnika Henke if ($fullscreenview) echo '</ul>'.NL; 7383df72098SAndreas Gohr } 73956fe6664SAndreas Gohr } 740d9162c6cSKate Arzamastseva} 741d9162c6cSKate Arzamastseva 742d9162c6cSKate Arzamastseva/** 743d9162c6cSKate Arzamastseva * Prints tabs for files list actions 744d9162c6cSKate Arzamastseva * 745d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 74695b451bcSAdrian Lang * @author Adrian Lang <mail@adrianlang.de> 74795b451bcSAdrian Lang * 748035e07f1SKate Arzamastseva * @param string $selected_tab - opened tab 749d9162c6cSKate Arzamastseva */ 75095b451bcSAdrian Lang 751035e07f1SKate Arzamastsevafunction media_tabs_files($selected_tab = ''){ 752d9162c6cSKate Arzamastseva global $lang; 753*24870174SAndreas Gohr $tabs = []; 754*24870174SAndreas Gohr foreach([ 755*24870174SAndreas Gohr 'files' => 'mediaselect', 75695b451bcSAdrian Lang 'upload' => 'media_uploadtab', 757*24870174SAndreas Gohr 'search' => 'media_searchtab' 758*24870174SAndreas Gohr ] as $tab => $caption) { 759*24870174SAndreas Gohr $tabs[$tab] = [ 760*24870174SAndreas Gohr 'href' => media_managerURL(['tab_files' => $tab], '&'), 761*24870174SAndreas Gohr 'caption' => $lang[$caption] 762*24870174SAndreas Gohr ]; 76395b451bcSAdrian Lang } 764d9162c6cSKate Arzamastseva 76595b451bcSAdrian Lang html_tabs($tabs, $selected_tab); 766d9162c6cSKate Arzamastseva} 767d9162c6cSKate Arzamastseva 768d9162c6cSKate Arzamastseva/** 769d9162c6cSKate Arzamastseva * Prints tabs for files details actions 770d9162c6cSKate Arzamastseva * 771d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 772ebc28e69SAndreas Gohr * @param string $image filename of the current image 773ebc28e69SAndreas Gohr * @param string $selected_tab opened tab 774d9162c6cSKate Arzamastseva */ 775035e07f1SKate Arzamastsevafunction media_tabs_details($image, $selected_tab = '') { 776e5d185e1SKate Arzamastseva global $lang, $conf; 777d9162c6cSKate Arzamastseva 778*24870174SAndreas Gohr $tabs = []; 779*24870174SAndreas Gohr $tabs['view'] = [ 780*24870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'view'], '&'), 781*24870174SAndreas Gohr 'caption' => $lang['media_viewtab'] 782*24870174SAndreas Gohr ]; 783d9162c6cSKate Arzamastseva 784*24870174SAndreas Gohr [, $mime] = mimetype($image); 78579e79377SAndreas Gohr if ($mime == 'image/jpeg' && file_exists(mediaFN($image))) { 786*24870174SAndreas Gohr $tabs['edit'] = [ 787*24870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'edit'], '&'), 788*24870174SAndreas Gohr 'caption' => $lang['media_edittab'] 789*24870174SAndreas Gohr ]; 790dd9ba38eSKate Arzamastseva } 791e5d185e1SKate Arzamastseva if ($conf['mediarevisions']) { 792*24870174SAndreas Gohr $tabs['history'] = [ 793*24870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'history'], '&'), 794*24870174SAndreas Gohr 'caption' => $lang['media_historytab'] 795*24870174SAndreas Gohr ]; 796e5d185e1SKate Arzamastseva } 797d9162c6cSKate Arzamastseva 79895b451bcSAdrian Lang html_tabs($tabs, $selected_tab); 799d9162c6cSKate Arzamastseva} 800d9162c6cSKate Arzamastseva 801d9162c6cSKate Arzamastseva/** 802d9162c6cSKate Arzamastseva * Prints options for the tab that displays a list of all files 803d9162c6cSKate Arzamastseva * 804d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 805d9162c6cSKate Arzamastseva */ 80695b451bcSAdrian Langfunction media_tab_files_options() { 8078108113cSTom N Harris global $lang; 8088108113cSTom N Harris global $INPUT; 809b7e5821dSAndreas Gohr global $ID; 810b960c74fSSatoshi Sahara 811b960c74fSSatoshi Sahara $form = new Form([ 812b960c74fSSatoshi Sahara 'method' => 'get', 813b960c74fSSatoshi Sahara 'action' => wl($ID), 814b960c74fSSatoshi Sahara 'class' => 'options' 815b960c74fSSatoshi Sahara ]); 816b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 817b960c74fSSatoshi Sahara $form->setHiddenField('sectok', null); 818b960c74fSSatoshi Sahara $media_manager_params = media_managerURL([], '', false, true); 81938b2bf35SAnika Henke foreach ($media_manager_params as $pKey => $pVal) { 820b960c74fSSatoshi Sahara $form->setHiddenField($pKey, $pVal); 82138b2bf35SAnika Henke } 8228108113cSTom N Harris if ($INPUT->has('q')) { 823b960c74fSSatoshi Sahara $form->setHiddenField('q', $INPUT->str('q')); 824554a8c9fSAdrian Lang } 825b960c74fSSatoshi Sahara $form->addHTML('<ul>'.NL); 826*24870174SAndreas Gohr foreach ([ 827*24870174SAndreas Gohr 'list' => ['listType', ['thumbs', 'rows']], 828*24870174SAndreas Gohr 'sort' => ['sortBy', ['name', 'date']] 829*24870174SAndreas Gohr ] as $group => $content) { 830ec88e837SAndreas Gohr $checked = "_media_get_{$group}_type"; 831554a8c9fSAdrian Lang $checked = $checked(); 832d9162c6cSKate Arzamastseva 833b960c74fSSatoshi Sahara $form->addHTML('<li class="'. $content[0] .'">'); 83495b451bcSAdrian Lang foreach ($content[1] as $option) { 835*24870174SAndreas Gohr $attrs = []; 836554a8c9fSAdrian Lang if ($checked == $option) { 83795b451bcSAdrian Lang $attrs['checked'] = 'checked'; 83895b451bcSAdrian Lang } 839b960c74fSSatoshi Sahara $radio = $form->addRadioButton( 840b960c74fSSatoshi Sahara $group.'_dwmedia', 841b960c74fSSatoshi Sahara $lang['media_'.$group.'_'.$option] 842b960c74fSSatoshi Sahara )->val($option)->id($content[0].'__'.$option)->addClass($option); 843b960c74fSSatoshi Sahara $radio->attrs($attrs); 84495b451bcSAdrian Lang } 845b960c74fSSatoshi Sahara $form->addHTML('</li>'.NL); 84695b451bcSAdrian Lang } 847b960c74fSSatoshi Sahara $form->addHTML('<li>'); 848b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_apply'])->attr('type', 'submit'); 849b960c74fSSatoshi Sahara $form->addHTML('</li>'.NL); 850b960c74fSSatoshi Sahara $form->addHTML('</ul>'.NL); 851b960c74fSSatoshi Sahara $form->addTagClose('div'); 852b960c74fSSatoshi Sahara print $form->toHTML(); 853d9162c6cSKate Arzamastseva} 854d9162c6cSKate Arzamastseva 855d9162c6cSKate Arzamastseva/** 85687deddfaSKate Arzamastseva * Returns type of sorting for the list of files in media manager 85787deddfaSKate Arzamastseva * 85887deddfaSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 85942ea7f44SGerrit Uitslag * 86087deddfaSKate Arzamastseva * @return string - sort type 86187deddfaSKate Arzamastseva */ 86287deddfaSKate Arzamastsevafunction _media_get_sort_type() { 863*24870174SAndreas Gohr return _media_get_display_param('sort', ['default' => 'name', 'date']); 86487deddfaSKate Arzamastseva} 865554a8c9fSAdrian Lang 8666ffaeda9SGerrit Uitslag/** 8676ffaeda9SGerrit Uitslag * Returns type of listing for the list of files in media manager 8686ffaeda9SGerrit Uitslag * 8696ffaeda9SGerrit Uitslag * @author Kate Arzamastseva <pshns@ukr.net> 87042ea7f44SGerrit Uitslag * 8716ffaeda9SGerrit Uitslag * @return string - list type 8726ffaeda9SGerrit Uitslag */ 873554a8c9fSAdrian Langfunction _media_get_list_type() { 874*24870174SAndreas Gohr return _media_get_display_param('list', ['default' => 'thumbs', 'rows']); 87587deddfaSKate Arzamastseva} 876554a8c9fSAdrian Lang 8776ffaeda9SGerrit Uitslag/** 8786ffaeda9SGerrit Uitslag * Get display parameters 8796ffaeda9SGerrit Uitslag * 8806ffaeda9SGerrit Uitslag * @param string $param name of parameter 8816ffaeda9SGerrit Uitslag * @param array $values allowed values, where default value has index key 'default' 8826ffaeda9SGerrit Uitslag * @return string the parameter value 8836ffaeda9SGerrit Uitslag */ 884554a8c9fSAdrian Langfunction _media_get_display_param($param, $values) { 8858108113cSTom N Harris global $INPUT; 8868108113cSTom N Harris if (in_array($INPUT->str($param), $values)) { 887554a8c9fSAdrian Lang // FIXME: Set cookie 8888108113cSTom N Harris return $INPUT->str($param); 889554a8c9fSAdrian Lang } else { 8903629bc8cSAdrian Lang $val = get_doku_pref($param, $values['default']); 8913629bc8cSAdrian Lang if (!in_array($val, $values)) { 8923629bc8cSAdrian Lang $val = $values['default']; 8933629bc8cSAdrian Lang } 8943629bc8cSAdrian Lang return $val; 895554a8c9fSAdrian Lang } 89687deddfaSKate Arzamastseva} 89787deddfaSKate Arzamastseva 89887deddfaSKate Arzamastseva/** 899d9162c6cSKate Arzamastseva * Prints tab that displays a list of all files 900d9162c6cSKate Arzamastseva * 901d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 90242ea7f44SGerrit Uitslag * 90342ea7f44SGerrit Uitslag * @param string $ns 90442ea7f44SGerrit Uitslag * @param null|int $auth permission level 90542ea7f44SGerrit Uitslag * @param string $jump item id 906d9162c6cSKate Arzamastseva */ 907d9162c6cSKate Arzamastsevafunction media_tab_files($ns,$auth=null,$jump='') { 908d9162c6cSKate Arzamastseva global $lang; 909d9162c6cSKate Arzamastseva if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 910d9162c6cSKate Arzamastseva 911d9162c6cSKate Arzamastseva if($auth < AUTH_READ){ 91288a71175SKate Arzamastseva echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 913d9162c6cSKate Arzamastseva }else{ 91495b451bcSAdrian Lang media_filelist($ns,$auth,$jump,true,_media_get_sort_type()); 915d9162c6cSKate Arzamastseva } 916d9162c6cSKate Arzamastseva} 917d9162c6cSKate Arzamastseva 918d9162c6cSKate Arzamastseva/** 919d9162c6cSKate Arzamastseva * Prints tab that displays uploading form 920d9162c6cSKate Arzamastseva * 921d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 92242ea7f44SGerrit Uitslag * 92342ea7f44SGerrit Uitslag * @param string $ns 92442ea7f44SGerrit Uitslag * @param null|int $auth permission level 92542ea7f44SGerrit Uitslag * @param string $jump item id 926d9162c6cSKate Arzamastseva */ 927d9162c6cSKate Arzamastsevafunction media_tab_upload($ns,$auth=null,$jump='') { 928d9162c6cSKate Arzamastseva global $lang; 929d9162c6cSKate Arzamastseva if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 930d9162c6cSKate Arzamastseva 93194add303SAnika Henke echo '<div class="upload">'.NL; 93295b451bcSAdrian Lang if ($auth >= AUTH_UPLOAD) { 93395b451bcSAdrian Lang echo '<p>' . $lang['mediaupload'] . '</p>'; 93495b451bcSAdrian Lang } 935d9162c6cSKate Arzamastseva media_uploadform($ns, $auth, true); 93694add303SAnika Henke echo '</div>'.NL; 937d9162c6cSKate Arzamastseva} 938d9162c6cSKate Arzamastseva 939d9162c6cSKate Arzamastseva/** 940d9162c6cSKate Arzamastseva * Prints tab that displays search form 941d9162c6cSKate Arzamastseva * 942d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 94342ea7f44SGerrit Uitslag * 94442ea7f44SGerrit Uitslag * @param string $ns 94542ea7f44SGerrit Uitslag * @param null|int $auth permission level 946d9162c6cSKate Arzamastseva */ 947d9162c6cSKate Arzamastsevafunction media_tab_search($ns,$auth=null) { 9488108113cSTom N Harris global $INPUT; 949d9162c6cSKate Arzamastseva 9508108113cSTom N Harris $do = $INPUT->str('mediado'); 9518108113cSTom N Harris $query = $INPUT->str('q'); 95294add303SAnika Henke echo '<div class="search">'.NL; 953d9162c6cSKate Arzamastseva 954d9162c6cSKate Arzamastseva media_searchform($ns, $query, true); 9552dba8df4SAdrian Lang if ($do == 'searchlist' || $query) { 95695b451bcSAdrian Lang media_searchlist($query,$ns,$auth,true,_media_get_sort_type()); 95795b451bcSAdrian Lang } 95894add303SAnika Henke echo '</div>'.NL; 959d9162c6cSKate Arzamastseva} 960d9162c6cSKate Arzamastseva 961d9162c6cSKate Arzamastseva/** 962d9162c6cSKate Arzamastseva * Prints tab that displays mediafile details 963d9162c6cSKate Arzamastseva * 964d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 965e0c26282SGerrit Uitslag * 966e0c26282SGerrit Uitslag * @param string $image media id 967e0c26282SGerrit Uitslag * @param string $ns 968e0c26282SGerrit Uitslag * @param null|int $auth permission level 96942ea7f44SGerrit Uitslag * @param string|int $rev revision timestamp or empty string 970d9162c6cSKate Arzamastseva */ 971e0c26282SGerrit Uitslagfunction media_tab_view($image, $ns, $auth=null, $rev='') { 972ebc28e69SAndreas Gohr global $lang; 973d9162c6cSKate Arzamastseva if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 974d9162c6cSKate Arzamastseva 975e136d6ccSKate Arzamastseva if ($image && $auth >= AUTH_READ) { 976dd9ba38eSKate Arzamastseva $meta = new JpegMeta(mediaFN($image, $rev)); 977dd9ba38eSKate Arzamastseva media_preview($image, $auth, $rev, $meta); 978e136d6ccSKate Arzamastseva media_preview_buttons($image, $auth, $rev); 979dd9ba38eSKate Arzamastseva media_details($image, $auth, $rev, $meta); 980e136d6ccSKate Arzamastseva 981e136d6ccSKate Arzamastseva } else { 98294add303SAnika Henke echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 983e136d6ccSKate Arzamastseva } 984d9162c6cSKate Arzamastseva} 985d9162c6cSKate Arzamastseva 986d9162c6cSKate Arzamastseva/** 987d9162c6cSKate Arzamastseva * Prints tab that displays form for editing mediafile metadata 988d9162c6cSKate Arzamastseva * 989d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 990e0c26282SGerrit Uitslag * 991e0c26282SGerrit Uitslag * @param string $image media id 992e0c26282SGerrit Uitslag * @param string $ns 993e0c26282SGerrit Uitslag * @param null|int $auth permission level 994d9162c6cSKate Arzamastseva */ 995d9162c6cSKate Arzamastsevafunction media_tab_edit($image, $ns, $auth=null) { 996d9162c6cSKate Arzamastseva if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 997d9162c6cSKate Arzamastseva 9981eeeced2SKate Arzamastseva if ($image) { 999*24870174SAndreas Gohr [, $mime] = mimetype($image); 100030fd72fbSKate Arzamastseva if ($mime == 'image/jpeg') media_metaform($image,$auth); 10011eeeced2SKate Arzamastseva } 1002d9162c6cSKate Arzamastseva} 1003d9162c6cSKate Arzamastseva 1004d9162c6cSKate Arzamastseva/** 1005d9162c6cSKate Arzamastseva * Prints tab that displays mediafile revisions 1006d9162c6cSKate Arzamastseva * 1007d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1008e0c26282SGerrit Uitslag * 1009e0c26282SGerrit Uitslag * @param string $image media id 1010e0c26282SGerrit Uitslag * @param string $ns 1011e0c26282SGerrit Uitslag * @param null|int $auth permission level 1012d9162c6cSKate Arzamastseva */ 1013d9162c6cSKate Arzamastsevafunction media_tab_history($image, $ns, $auth=null) { 1014d9162c6cSKate Arzamastseva global $lang; 10158108113cSTom N Harris global $INPUT; 10168108113cSTom N Harris 1017d9162c6cSKate Arzamastseva if(is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 10188108113cSTom N Harris $do = $INPUT->str('mediado'); 1019d9162c6cSKate Arzamastseva 10202e55802cSKate Arzamastseva if ($auth >= AUTH_READ && $image) { 10212e55802cSKate Arzamastseva if ($do == 'diff'){ 1022*24870174SAndreas Gohr (new MediaDiff($image))->show(); //media_diff($image, $ns, $auth); 10232e55802cSKate Arzamastseva } else { 1024a46cc3dcSAndreas Gohr $first = $INPUT->int('first',-1); 1025*24870174SAndreas Gohr (new MediaRevisions($image))->show($first); 10262e55802cSKate Arzamastseva } 102788a71175SKate Arzamastseva } else { 102888a71175SKate Arzamastseva echo '<div class="nothing">'.$lang['media_perm_read'].'</div>'.NL; 10292e55802cSKate Arzamastseva } 10303df72098SAndreas Gohr} 10313df72098SAndreas Gohr 10323df72098SAndreas Gohr/** 10331eeeced2SKate Arzamastseva * Prints mediafile details 10341eeeced2SKate Arzamastseva * 10356ffaeda9SGerrit Uitslag * @param string $image media id 1036e0c26282SGerrit Uitslag * @param int $auth permission level 103759bc3b48SGerrit Uitslag * @param int|string $rev revision timestamp or empty string 10386ffaeda9SGerrit Uitslag * @param JpegMeta|bool $meta 103942ea7f44SGerrit Uitslag * 10401eeeced2SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 10411eeeced2SKate Arzamastseva */ 104259bc3b48SGerrit Uitslagfunction media_preview($image, $auth, $rev = '', $meta = false) { 1043e136d6ccSKate Arzamastseva 1044e136d6ccSKate Arzamastseva $size = media_image_preview_size($image, $rev, $meta); 1045e136d6ccSKate Arzamastseva 1046e136d6ccSKate Arzamastseva if ($size) { 104759f3611bSAnika Henke global $lang; 104894add303SAnika Henke echo '<div class="image">'; 104994add303SAnika Henke 1050*24870174SAndreas Gohr $more = []; 1051e136d6ccSKate Arzamastseva if ($rev) { 10525b9353faSKate Arzamastseva $more['rev'] = $rev; 1053e136d6ccSKate Arzamastseva } else { 1054e136d6ccSKate Arzamastseva $t = @filemtime(mediaFN($image)); 10555b9353faSKate Arzamastseva $more['t'] = $t; 105688a71175SKate Arzamastseva } 105723786fd7SKate Arzamastseva 10585b9353faSKate Arzamastseva $more['w'] = $size[0]; 10595b9353faSKate Arzamastseva $more['h'] = $size[1]; 1060e136d6ccSKate Arzamastseva $src = ml($image, $more); 106159f3611bSAnika Henke 106259f3611bSAnika Henke echo '<a href="'.$src.'" target="_blank" title="'.$lang['mediaview'].'">'; 106395b451bcSAdrian Lang echo '<img src="'.$src.'" alt="" style="max-width: '.$size[0].'px;" />'; 106459f3611bSAnika Henke echo '</a>'; 1065e136d6ccSKate Arzamastseva 1066871895a7SSatoshi Sahara echo '</div>'; 106794add303SAnika Henke } 1068e136d6ccSKate Arzamastseva} 1069e136d6ccSKate Arzamastseva 1070e136d6ccSKate Arzamastseva/** 1071e136d6ccSKate Arzamastseva * Prints mediafile action buttons 1072e136d6ccSKate Arzamastseva * 1073e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1074e0c26282SGerrit Uitslag * 1075e0c26282SGerrit Uitslag * @param string $image media id 1076e0c26282SGerrit Uitslag * @param int $auth permission level 1077871895a7SSatoshi Sahara * @param int|string $rev revision timestamp, or empty string 1078e136d6ccSKate Arzamastseva */ 1079e0c26282SGerrit Uitslagfunction media_preview_buttons($image, $auth, $rev = '') { 1080e5d185e1SKate Arzamastseva global $lang, $conf; 1081e136d6ccSKate Arzamastseva 1082871895a7SSatoshi Sahara echo '<ul class="actions">'; 10831eeeced2SKate Arzamastseva 108479e79377SAndreas Gohr if ($auth >= AUTH_DELETE && !$rev && file_exists(mediaFN($image))) { 1085e136d6ccSKate Arzamastseva 1086e136d6ccSKate Arzamastseva // delete button 1087b960c74fSSatoshi Sahara $form = new Form([ 1088b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_delete', 1089b960c74fSSatoshi Sahara 'action' => media_managerURL(['delete' => $image], '&'), 1090b960c74fSSatoshi Sahara ]); 1091b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1092b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_delete'])->attr('type', 'submit'); 1093b960c74fSSatoshi Sahara $form->addTagClose('div'); 109495b451bcSAdrian Lang echo '<li>'; 1095b960c74fSSatoshi Sahara echo $form->toHTML(); 1096871895a7SSatoshi Sahara echo '</li>'; 1097e5d185e1SKate Arzamastseva } 1098e5d185e1SKate Arzamastseva 1099e5d185e1SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 1100e5d185e1SKate Arzamastseva if ($auth >= $auth_ow && !$rev) { 1101e5d185e1SKate Arzamastseva 1102e136d6ccSKate Arzamastseva // upload new version button 1103b960c74fSSatoshi Sahara $form = new Form([ 1104b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_update', 1105b960c74fSSatoshi Sahara 'action' => media_managerURL(['image' => $image, 'mediado' => 'update'], '&'), 1106b960c74fSSatoshi Sahara ]); 1107b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1108b960c74fSSatoshi Sahara $form->addButton('', $lang['media_update'])->attr('type', 'submit'); 1109b960c74fSSatoshi Sahara $form->addTagClose('div'); 111095b451bcSAdrian Lang echo '<li>'; 1111b960c74fSSatoshi Sahara echo $form->toHTML(); 1112871895a7SSatoshi Sahara echo '</li>'; 111370c3cc9aSKate Arzamastseva } 1114e136d6ccSKate Arzamastseva 111579e79377SAndreas Gohr if ($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && file_exists(mediaFN($image, $rev))) { 1116e136d6ccSKate Arzamastseva 1117e136d6ccSKate Arzamastseva // restore button 1118b960c74fSSatoshi Sahara $form = new Form([ 1119b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_restore', 1120b960c74fSSatoshi Sahara 'action'=>media_managerURL(['image' => $image], '&'), 1121b960c74fSSatoshi Sahara ]); 1122b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1123b960c74fSSatoshi Sahara $form->setHiddenField('mediado', 'restore'); 1124b960c74fSSatoshi Sahara $form->setHiddenField('rev', $rev); 1125b960c74fSSatoshi Sahara $form->addButton('', $lang['media_restore'])->attr('type', 'submit'); 1126b960c74fSSatoshi Sahara $form->addTagClose('div'); 112795b451bcSAdrian Lang echo '<li>'; 1128b960c74fSSatoshi Sahara echo $form->toHTML(); 1129871895a7SSatoshi Sahara echo '</li>'; 11309c1bd4bcSKate Arzamastseva } 1131e136d6ccSKate Arzamastseva 1132871895a7SSatoshi Sahara echo '</ul>'; 11332e55802cSKate Arzamastseva} 11342e55802cSKate Arzamastseva 11352e55802cSKate Arzamastseva/** 1136fa8e5c77SKate Arzamastseva * Returns image width and height for mediamanager preview panel 1137fa8e5c77SKate Arzamastseva * 1138fa8e5c77SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1139fa8e5c77SKate Arzamastseva * @param string $image 1140e0c26282SGerrit Uitslag * @param int|string $rev 114159bc3b48SGerrit Uitslag * @param JpegMeta|bool $meta 1142ebc28e69SAndreas Gohr * @param int $size 1143871895a7SSatoshi Sahara * @return array 1144fa8e5c77SKate Arzamastseva */ 1145871895a7SSatoshi Saharafunction media_image_preview_size($image, $rev, $meta = false, $size = 500) { 1146871895a7SSatoshi Sahara if (!preg_match("/\.(jpe?g|gif|png)$/", $image) 1147871895a7SSatoshi Sahara || !file_exists($filename = mediaFN($image, $rev)) 1148*24870174SAndreas Gohr ) return []; 1149fa8e5c77SKate Arzamastseva 1150871895a7SSatoshi Sahara $info = getimagesize($filename); 1151*24870174SAndreas Gohr $w = $info[0]; 1152*24870174SAndreas Gohr $h = $info[1]; 1153fa8e5c77SKate Arzamastseva 1154fa8e5c77SKate Arzamastseva if ($meta && ($w > $size || $h > $size)) { 1155fa8e5c77SKate Arzamastseva $ratio = $meta->getResizeRatio($size, $size); 1156fa8e5c77SKate Arzamastseva $w = floor($w * $ratio); 1157fa8e5c77SKate Arzamastseva $h = floor($h * $ratio); 1158fa8e5c77SKate Arzamastseva } 1159*24870174SAndreas Gohr return [$w, $h]; 1160fa8e5c77SKate Arzamastseva} 1161fa8e5c77SKate Arzamastseva 1162fa8e5c77SKate Arzamastseva/** 1163fa8e5c77SKate Arzamastseva * Returns the requested EXIF/IPTC tag from the image meta 1164fa8e5c77SKate Arzamastseva * 1165fa8e5c77SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1166e0c26282SGerrit Uitslag * 116742ea7f44SGerrit Uitslag * @param array $tags array with tags, first existing is returned 1168fa8e5c77SKate Arzamastseva * @param JpegMeta $meta 116942ea7f44SGerrit Uitslag * @param string $alt alternative value 1170fa8e5c77SKate Arzamastseva * @return string 1171fa8e5c77SKate Arzamastseva */ 1172871895a7SSatoshi Saharafunction media_getTag($tags, $meta = false, $alt = '') { 1173871895a7SSatoshi Sahara if (!$meta) return $alt; 1174fa8e5c77SKate Arzamastseva $info = $meta->getField($tags); 1175871895a7SSatoshi Sahara if (!$info) return $alt; 1176fa8e5c77SKate Arzamastseva return $info; 1177fa8e5c77SKate Arzamastseva} 1178fa8e5c77SKate Arzamastseva 1179fa8e5c77SKate Arzamastseva/** 1180e136d6ccSKate Arzamastseva * Returns mediafile tags 11812e55802cSKate Arzamastseva * 11822e55802cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1183e0c26282SGerrit Uitslag * 1184e136d6ccSKate Arzamastseva * @param JpegMeta $meta 118542ea7f44SGerrit Uitslag * @return array list of tags of the mediafile 11862e55802cSKate Arzamastseva */ 1187e136d6ccSKate Arzamastsevafunction media_file_tags($meta) { 1188532850edSKate Arzamastseva // load the field descriptions 11893e98e685SKate Arzamastseva static $fields = null; 11903e98e685SKate Arzamastseva if (is_null($fields)) { 11913e98e685SKate Arzamastseva $config_files = getConfigFiles('mediameta'); 11923e98e685SKate Arzamastseva foreach ($config_files as $config_file) { 119379e79377SAndreas Gohr if (file_exists($config_file)) include($config_file); 1194532850edSKate Arzamastseva } 1195532850edSKate Arzamastseva } 11961eeeced2SKate Arzamastseva 1197*24870174SAndreas Gohr $tags = []; 1198dd9ba38eSKate Arzamastseva 1199*24870174SAndreas Gohr foreach ($fields as $tag) { 1200*24870174SAndreas Gohr $t = []; 1201*24870174SAndreas Gohr if (!empty($tag[0])) $t = [$tag[0]]; 12020e80bb5eSChristopher Smith if (isset($tag[3]) && is_array($tag[3])) $t = array_merge($t,$tag[3]); 1203e136d6ccSKate Arzamastseva $value = media_getTag($t, $meta); 1204*24870174SAndreas Gohr $tags[] = ['tag' => $tag, 'value' => $value]; 1205e136d6ccSKate Arzamastseva } 1206e136d6ccSKate Arzamastseva 1207e136d6ccSKate Arzamastseva return $tags; 1208e136d6ccSKate Arzamastseva} 1209e136d6ccSKate Arzamastseva 1210e136d6ccSKate Arzamastseva/** 1211e136d6ccSKate Arzamastseva * Prints mediafile tags 1212e136d6ccSKate Arzamastseva * 1213e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 121442ea7f44SGerrit Uitslag * 1215e0c26282SGerrit Uitslag * @param string $image image id 1216e0c26282SGerrit Uitslag * @param int $auth permission level 1217e0c26282SGerrit Uitslag * @param string|int $rev revision timestamp, or empty string 1218e0c26282SGerrit Uitslag * @param bool|JpegMeta $meta image object, or create one if false 1219e0c26282SGerrit Uitslag */ 1220e0c26282SGerrit Uitslagfunction media_details($image, $auth, $rev='', $meta=false) { 1221e136d6ccSKate Arzamastseva global $lang; 1222e136d6ccSKate Arzamastseva 1223e136d6ccSKate Arzamastseva if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev)); 1224e136d6ccSKate Arzamastseva $tags = media_file_tags($meta); 1225e136d6ccSKate Arzamastseva 122694add303SAnika Henke echo '<dl>'.NL; 1227e136d6ccSKate Arzamastseva foreach($tags as $tag){ 1228e136d6ccSKate Arzamastseva if ($tag['value']) { 1229e136d6ccSKate Arzamastseva $value = cleanText($tag['value']); 1230fde860beSGerrit Uitslag echo '<dt>'.$lang[$tag['tag'][1]].'</dt><dd>'; 1231e136d6ccSKate Arzamastseva if ($tag['tag'][2] == 'date') echo dformat($value); 12323e98e685SKate Arzamastseva else echo hsc($value); 123394add303SAnika Henke echo '</dd>'.NL; 12341eeeced2SKate Arzamastseva } 1235e136d6ccSKate Arzamastseva } 123694add303SAnika Henke echo '</dl>'.NL; 123722e68399Sflammy echo '<dl>'.NL; 123822e68399Sflammy echo '<dt>'.$lang['reference'].':</dt>'; 123922e68399Sflammy $media_usage = ft_mediause($image,true); 1240*24870174SAndreas Gohr if($media_usage !== []){ 124122e68399Sflammy foreach($media_usage as $path){ 124222e68399Sflammy echo '<dd>'.html_wikilink($path).'</dd>'; 124322e68399Sflammy } 124422e68399Sflammy }else{ 124522e68399Sflammy echo '<dd>'.$lang['nothingfound'].'</dd>'; 124622e68399Sflammy } 124722e68399Sflammy echo '</dl>'.NL; 124822e68399Sflammy 12491eeeced2SKate Arzamastseva} 12502e55802cSKate Arzamastseva 12512e55802cSKate Arzamastseva/** 12522e55802cSKate Arzamastseva * Shows difference between two revisions of file 12532e55802cSKate Arzamastseva * 12542e55802cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 125542ea7f44SGerrit Uitslag * 1256e0c26282SGerrit Uitslag * @param string $image image id 1257e0c26282SGerrit Uitslag * @param string $ns 1258e0c26282SGerrit Uitslag * @param int $auth permission level 1259e0c26282SGerrit Uitslag * @param bool $fromajax 126079a2d784SGerrit Uitslag * 1261297071beSSatoshi Sahara * @deprecated 2020-12-31 1262e0c26282SGerrit Uitslag */ 1263b4b31bacSKate Arzamastsevafunction media_diff($image, $ns, $auth, $fromajax = false) { 126479a2d784SGerrit Uitslag dbg_deprecated('see '. MediaDiff::class .'::show()'); 126559e81a43SKate Arzamastseva} 126659e81a43SKate Arzamastseva 12676ffaeda9SGerrit Uitslag/** 12686ffaeda9SGerrit Uitslag * Callback for media file diff 12696ffaeda9SGerrit Uitslag * 127042ea7f44SGerrit Uitslag * @param array $data event data 127179a2d784SGerrit Uitslag * 1272297071beSSatoshi Sahara * @deprecated 2020-12-31 12736ffaeda9SGerrit Uitslag */ 1274fa8e5c77SKate Arzamastsevafunction _media_file_diff($data) { 127579a2d784SGerrit Uitslag dbg_deprecated('see '. MediaDiff::class .'::show()'); 127659e81a43SKate Arzamastseva} 127759e81a43SKate Arzamastseva 127859e81a43SKate Arzamastseva/** 127959e81a43SKate Arzamastseva * Shows difference between two revisions of image 128059e81a43SKate Arzamastseva * 128159e81a43SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1282e0c26282SGerrit Uitslag * 1283e0c26282SGerrit Uitslag * @param string $image 1284e0c26282SGerrit Uitslag * @param string|int $l_rev revision timestamp, or empty string 1285e0c26282SGerrit Uitslag * @param string|int $r_rev revision timestamp, or empty string 1286e0c26282SGerrit Uitslag * @param string $ns 1287e0c26282SGerrit Uitslag * @param int $auth permission level 1288e0c26282SGerrit Uitslag * @param bool $fromajax 1289297071beSSatoshi Sahara * @deprecated 2020-12-31 129059e81a43SKate Arzamastseva */ 1291b4b31bacSKate Arzamastsevafunction media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) { 129279a2d784SGerrit Uitslag dbg_deprecated('see '. MediaDiff::class .'::showFileDiff()'); 1293e136d6ccSKate Arzamastseva} 1294e136d6ccSKate Arzamastseva 1295e136d6ccSKate Arzamastseva/** 1296e136d6ccSKate Arzamastseva * Prints two images side by side 1297fa8e5c77SKate Arzamastseva * and slider 1298e136d6ccSKate Arzamastseva * 1299e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 130042ea7f44SGerrit Uitslag * 130142ea7f44SGerrit Uitslag * @param string $image image id 1302e0c26282SGerrit Uitslag * @param int $l_rev revision timestamp, or empty string 1303e0c26282SGerrit Uitslag * @param int $r_rev revision timestamp, or empty string 130442ea7f44SGerrit Uitslag * @param array $l_size array with width and height 130542ea7f44SGerrit Uitslag * @param array $r_size array with width and height 130650fc55feSKate Arzamastseva * @param string $type 1307297071beSSatoshi Sahara * @deprecated 2020-12-31 1308e136d6ccSKate Arzamastseva */ 130950fc55feSKate Arzamastsevafunction media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) { 131079a2d784SGerrit Uitslag dbg_deprecated('see '. MediaDiff::class .'::showImageDiff()'); 13111eeeced2SKate Arzamastseva} 13121eeeced2SKate Arzamastseva 13131eeeced2SKate Arzamastseva/** 13149c1bd4bcSKate Arzamastseva * Restores an old revision of a media file 13159c1bd4bcSKate Arzamastseva * 131642ea7f44SGerrit Uitslag * @param string $image media id 131742ea7f44SGerrit Uitslag * @param int $rev revision timestamp or empty string 13189c1bd4bcSKate Arzamastseva * @param int $auth 13199c1bd4bcSKate Arzamastseva * @return string - file's id 132042ea7f44SGerrit Uitslag * 13219c1bd4bcSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 13229c1bd4bcSKate Arzamastseva */ 13239c1bd4bcSKate Arzamastsevafunction media_restore($image, $rev, $auth){ 1324e5d185e1SKate Arzamastseva global $conf; 132580525638SKate Arzamastseva if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false; 132692cac9a9SKate Arzamastseva $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes'))); 132792cac9a9SKate Arzamastseva if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false; 13289c1bd4bcSKate Arzamastseva if (!$rev || !file_exists(mediaFN($image, $rev))) return false; 1329*24870174SAndreas Gohr [, $imime, ] = mimetype($image); 13309c1bd4bcSKate Arzamastseva $res = media_upload_finish(mediaFN($image, $rev), 13319c1bd4bcSKate Arzamastseva mediaFN($image), 13329c1bd4bcSKate Arzamastseva $image, 13339c1bd4bcSKate Arzamastseva $imime, 13349c1bd4bcSKate Arzamastseva true, 13359c1bd4bcSKate Arzamastseva 'copy'); 13369c1bd4bcSKate Arzamastseva if (is_array($res)) { 13379c1bd4bcSKate Arzamastseva msg($res[0], $res[1]); 13389c1bd4bcSKate Arzamastseva return false; 13399c1bd4bcSKate Arzamastseva } 13409c1bd4bcSKate Arzamastseva return $res; 13419c1bd4bcSKate Arzamastseva} 13429c1bd4bcSKate Arzamastseva 13439c1bd4bcSKate Arzamastseva/** 1344bf1f3ac4Ssarnowski * List all files found by the search request 1345c9f56829SAndreas Gohr * 1346c9f56829SAndreas Gohr * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1347c9f56829SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 1348d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1349c9f56829SAndreas Gohr * @triggers MEDIA_SEARCH 1350e0c26282SGerrit Uitslag * 1351e0c26282SGerrit Uitslag * @param string $query 1352e0c26282SGerrit Uitslag * @param string $ns 1353e0c26282SGerrit Uitslag * @param null|int $auth 1354e0c26282SGerrit Uitslag * @param bool $fullscreen 1355e0c26282SGerrit Uitslag * @param string $sort 1356bf1f3ac4Ssarnowski */ 135700e3e394SChristopher Smithfunction media_searchlist($query,$ns,$auth=null,$fullscreen=false,$sort='natural'){ 1358bf1f3ac4Ssarnowski global $conf; 1359bf1f3ac4Ssarnowski global $lang; 13608e69fd30SKate Arzamastseva 1361bf1f3ac4Ssarnowski $ns = cleanID($ns); 1362*24870174SAndreas Gohr $evdata = [ 136356fe6664SAndreas Gohr 'ns' => $ns, 1364*24870174SAndreas Gohr 'data' => [], 136556fe6664SAndreas Gohr 'query' => $query 1366*24870174SAndreas Gohr ]; 13677ed31746SSzymon Olewniczak if (!blank($query)) { 1368e1d9dcc8SAndreas Gohr $evt = new Event('MEDIA_SEARCH', $evdata); 1369bf1f3ac4Ssarnowski if ($evt->advise_before()) { 137056fe6664SAndreas Gohr $dir = utf8_encodeFN(str_replace(':','/',$evdata['ns'])); 137176472096SSzymon Olewniczak $quoted = preg_quote($evdata['query'],'/'); 137276472096SSzymon Olewniczak //apply globbing 1373*24870174SAndreas Gohr $quoted = str_replace(['\*', '\?'], ['.*', '.'], $quoted, $count); 137423e31e76SSzymon Olewniczak 137523e31e76SSzymon Olewniczak //if we use globbing file name must match entirely but may be preceded by arbitrary namespace 137623e31e76SSzymon Olewniczak if ($count > 0) $quoted = '^([^:]*:)*'.$quoted.'$'; 137723e31e76SSzymon Olewniczak 137876472096SSzymon Olewniczak $pattern = '/'.$quoted.'/i'; 137956fe6664SAndreas Gohr search($evdata['data'], 138056fe6664SAndreas Gohr $conf['mediadir'], 13814f33babfSAndreas Gohr 'search_mediafiles', 1382*24870174SAndreas Gohr ['showmsg'=>false, 'pattern'=>$pattern], 138300e3e394SChristopher Smith $dir, 138400e3e394SChristopher Smith 1, 138500e3e394SChristopher Smith $sort); 1386bf1f3ac4Ssarnowski } 1387bf1f3ac4Ssarnowski $evt->advise_after(); 1388bf1f3ac4Ssarnowski unset($evt); 138956fe6664SAndreas Gohr } 1390bf1f3ac4Ssarnowski 1391d9162c6cSKate Arzamastseva if (!$fullscreen) { 139256fe6664SAndreas Gohr echo '<h1 id="media__ns">'.sprintf($lang['searchmedia_in'],hsc($ns).':*').'</h1>'.NL; 139356fe6664SAndreas Gohr media_searchform($ns,$query); 1394d9162c6cSKate Arzamastseva } 139556fe6664SAndreas Gohr 139656fe6664SAndreas Gohr if(!count($evdata['data'])){ 1397bf1f3ac4Ssarnowski echo '<div class="nothing">'.$lang['nothingfound'].'</div>'.NL; 13985b9353faSKate Arzamastseva }else { 13995b9353faSKate Arzamastseva if ($fullscreen) { 1400554a8c9fSAdrian Lang echo '<ul class="' . _media_get_list_type() . '">'; 14015b9353faSKate Arzamastseva } 14025b9353faSKate Arzamastseva foreach($evdata['data'] as $item){ 14034f33babfSAndreas Gohr if (!$fullscreen) { 14044f33babfSAndreas Gohr // FIXME old call: media_printfile($item,$item['perm'],'',true); 140579a2d784SGerrit Uitslag $display = new DisplayRow($item); 140679b00823SAndreas Gohr $display->relativeDisplay($ns); 14074f33babfSAndreas Gohr $display->show(); 14084f33babfSAndreas Gohr } else { 14094f33babfSAndreas Gohr // FIXME old call: media_printfile_thumbs($item,$item['perm'],false,true); 141079a2d784SGerrit Uitslag $display = new DisplayTile($item); 141179b00823SAndreas Gohr $display->relativeDisplay($ns); 14124f33babfSAndreas Gohr echo '<li>'; 14134f33babfSAndreas Gohr $display->show(); 14144f33babfSAndreas Gohr echo '</li>'; 14154f33babfSAndreas Gohr } 1416bf1f3ac4Ssarnowski } 141794add303SAnika Henke if ($fullscreen) echo '</ul>'.NL; 14185b9353faSKate Arzamastseva } 1419bf1f3ac4Ssarnowski} 1420bf1f3ac4Ssarnowski 1421bf1f3ac4Ssarnowski/** 1422c6571d58SAndreas Gohr * Display a media icon 1423c6571d58SAndreas Gohr * 142442ea7f44SGerrit Uitslag * @param string $filename media id 1425c6571d58SAndreas Gohr * @param string $size the size subfolder, if not specified 16x16 is used 142642ea7f44SGerrit Uitslag * @return string html 1427c6571d58SAndreas Gohr */ 1428c6571d58SAndreas Gohrfunction media_printicon($filename, $size=''){ 1429*24870174SAndreas Gohr [$ext] = mimetype(mediaFN($filename),false); 143023786fd7SKate Arzamastseva 143179e79377SAndreas Gohr if (file_exists(DOKU_INC.'lib/images/fileicons/'.$size.'/'.$ext.'.png')) { 1432c6571d58SAndreas Gohr $icon = DOKU_BASE.'lib/images/fileicons/'.$size.'/'.$ext.'.png'; 143323786fd7SKate Arzamastseva } else { 1434c6571d58SAndreas Gohr $icon = DOKU_BASE.'lib/images/fileicons/'.$size.'/file.png'; 143523786fd7SKate Arzamastseva } 143623786fd7SKate Arzamastseva 1437421ec38eSKate Arzamastseva return '<img src="'.$icon.'" alt="'.$filename.'" class="icon" />'; 143823786fd7SKate Arzamastseva} 143923786fd7SKate Arzamastseva 14403df72098SAndreas Gohr/** 144142ea7f44SGerrit Uitslag * Build link based on the current, adding/rewriting parameters 1442d9162c6cSKate Arzamastseva * 1443d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 144442ea7f44SGerrit Uitslag * 1445ebc28e69SAndreas Gohr * @param array|bool $params 144642ea7f44SGerrit Uitslag * @param string $amp separator 144742ea7f44SGerrit Uitslag * @param bool $abs absolute url? 144842ea7f44SGerrit Uitslag * @param bool $params_array return the parmeters array? 144942ea7f44SGerrit Uitslag * @return string|array - link or link parameters 1450d9162c6cSKate Arzamastseva */ 1451035e07f1SKate Arzamastsevafunction media_managerURL($params = false, $amp = '&', $abs = false, $params_array = false) { 1452d9162c6cSKate Arzamastseva global $ID; 14538108113cSTom N Harris global $INPUT; 1454d9162c6cSKate Arzamastseva 1455*24870174SAndreas Gohr $gets = ['do' => 'media']; 1456*24870174SAndreas Gohr $media_manager_params = ['tab_files', 'tab_details', 'image', 'ns', 'list', 'sort']; 145723846a98SKate Arzamastseva foreach ($media_manager_params as $x) { 14588108113cSTom N Harris if ($INPUT->has($x)) $gets[$x] = $INPUT->str($x); 145923846a98SKate Arzamastseva } 1460d9162c6cSKate Arzamastseva 1461d9162c6cSKate Arzamastseva if ($params) { 1462554a8c9fSAdrian Lang $gets = $params + $gets; 1463d9162c6cSKate Arzamastseva } 1464d9162c6cSKate Arzamastseva unset($gets['id']); 1465554a8c9fSAdrian Lang if (isset($gets['delete'])) { 14661eeeced2SKate Arzamastseva unset($gets['image']); 14671eeeced2SKate Arzamastseva unset($gets['tab_details']); 14681eeeced2SKate Arzamastseva } 1469d9162c6cSKate Arzamastseva 1470035e07f1SKate Arzamastseva if ($params_array) return $gets; 1471035e07f1SKate Arzamastseva 14726dd095f5SKate Arzamastseva return wl($ID,$gets,$abs,$amp); 1473d9162c6cSKate Arzamastseva} 1474d9162c6cSKate Arzamastseva 1475d9162c6cSKate Arzamastseva/** 14763df72098SAndreas Gohr * Print the media upload form if permissions are correct 14773df72098SAndreas Gohr * 14783df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1479d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1480e0c26282SGerrit Uitslag * 1481e0c26282SGerrit Uitslag * @param string $ns 1482e0c26282SGerrit Uitslag * @param int $auth permission level 1483e0c26282SGerrit Uitslag * @param bool $fullscreen 14843df72098SAndreas Gohr */ 1485d9162c6cSKate Arzamastsevafunction media_uploadform($ns, $auth, $fullscreen = false) { 14868108113cSTom N Harris global $lang; 14878108113cSTom N Harris global $conf; 14888108113cSTom N Harris global $INPUT; 14893df72098SAndreas Gohr 149088a71175SKate Arzamastseva if ($auth < AUTH_UPLOAD) { 149188a71175SKate Arzamastseva echo '<div class="nothing">'.$lang['media_perm_upload'].'</div>'.NL; 149288a71175SKate Arzamastseva return; 149388a71175SKate Arzamastseva } 149492cac9a9SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 14953df72098SAndreas Gohr 149670c3cc9aSKate Arzamastseva $update = false; 149770c3cc9aSKate Arzamastseva $id = ''; 14988108113cSTom N Harris if ($auth >= $auth_ow && $fullscreen && $INPUT->str('mediado') == 'update') { 149970c3cc9aSKate Arzamastseva $update = true; 15008108113cSTom N Harris $id = cleanID($INPUT->str('image')); 150170c3cc9aSKate Arzamastseva } 150270c3cc9aSKate Arzamastseva 1503d00ec455SAndreas Gohr // The default HTML upload form 1504b960c74fSSatoshi Sahara $form = new Form([ 1505b960c74fSSatoshi Sahara 'id' => 'dw__upload', 1506b960c74fSSatoshi Sahara 'enctype' => 'multipart/form-data', 1507b960c74fSSatoshi Sahara 'action' => ($fullscreen) 1508b960c74fSSatoshi Sahara ? media_managerURL(['tab_files' => 'files', 'tab_details' => 'view'], '&') 1509b960c74fSSatoshi Sahara : DOKU_BASE.'lib/exe/mediamanager.php', 1510b960c74fSSatoshi Sahara ]); 1511b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1512b960c74fSSatoshi Sahara $form->setHiddenField('ns', hsc($ns)); // FIXME hsc required? 1513b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1514b960c74fSSatoshi Sahara $form->addTextInput('upload', $lang['txt_upload'])->id('upload__file') 1515b960c74fSSatoshi Sahara ->attrs(['type' => 'file']); 1516b960c74fSSatoshi Sahara $form->addTagClose('p'); 1517b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1518b960c74fSSatoshi Sahara $form->addTextInput('mediaid', $lang['txt_filename'])->id('upload__name') 1519b960c74fSSatoshi Sahara ->val(noNS($id)); 1520b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_upload'])->attr('type', 'submit'); 1521b960c74fSSatoshi Sahara $form->addTagClose('p'); 152292cac9a9SKate Arzamastseva if ($auth >= $auth_ow){ 1523b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1524*24870174SAndreas Gohr $attrs = []; 152570c3cc9aSKate Arzamastseva if ($update) $attrs['checked'] = 'checked'; 1526b960c74fSSatoshi Sahara $form->addCheckbox('ow', $lang['txt_overwrt'])->id('dw__ow')->val('1') 1527b960c74fSSatoshi Sahara ->addClass('check')->attrs($attrs); 1528b960c74fSSatoshi Sahara $form->addTagClose('p'); 1529b960c74fSSatoshi Sahara } 1530b960c74fSSatoshi Sahara $form->addTagClose('div'); 1531b960c74fSSatoshi Sahara 1532b960c74fSSatoshi Sahara if (!$fullscreen) { 1533b960c74fSSatoshi Sahara echo '<div class="upload">'. $lang['mediaupload'] .'</div>'.DOKU_LF; 1534b960c74fSSatoshi Sahara } else { 1535b960c74fSSatoshi Sahara echo DOKU_LF; 15363df72098SAndreas Gohr } 1537c472bad9SKate Arzamastseva 1538b960c74fSSatoshi Sahara echo '<div id="mediamanager__uploader">'.DOKU_LF; 1539c6977b3aSSatoshi Sahara echo $form->toHTML('Upload'); 1540b960c74fSSatoshi Sahara echo '</div>'.DOKU_LF; 1541f940e4a0SAndreas Gohr 1542f940e4a0SAndreas Gohr echo '<p class="maxsize">'; 1543f940e4a0SAndreas Gohr printf($lang['maxuploadsize'], filesize_h(media_getuploadsize())); 154456fc6b15SAnna Dabrowska echo ' <a class="allowedmime" href="#">'. $lang['allowedmime'] .'</a>'; 1545499d9bcdSAndreas Gohr echo ' <span>'. implode(', ', array_keys(getMimeTypes())) .'</span>'; 1546b960c74fSSatoshi Sahara echo '</p>'.DOKU_LF; 1547f940e4a0SAndreas Gohr} 1548f940e4a0SAndreas Gohr 1549f940e4a0SAndreas Gohr/** 1550f940e4a0SAndreas Gohr * Returns the size uploaded files may have 1551f940e4a0SAndreas Gohr * 1552f940e4a0SAndreas Gohr * This uses a conservative approach using the lowest number found 1553f940e4a0SAndreas Gohr * in any of the limiting ini settings 1554f940e4a0SAndreas Gohr * 1555f940e4a0SAndreas Gohr * @returns int size in bytes 1556f940e4a0SAndreas Gohr */ 1557f940e4a0SAndreas Gohrfunction media_getuploadsize(){ 1558f940e4a0SAndreas Gohr $okay = 0; 1559f940e4a0SAndreas Gohr 1560*24870174SAndreas Gohr $post = php_to_byte(@ini_get('post_max_size')); 1561*24870174SAndreas Gohr $suho = php_to_byte(@ini_get('suhosin.post.max_value_length')); 1562*24870174SAndreas Gohr $upld = php_to_byte(@ini_get('upload_max_filesize')); 1563f940e4a0SAndreas Gohr 1564*24870174SAndreas Gohr if($post && ($post < $okay || $okay === 0)) $okay = $post; 1565f940e4a0SAndreas Gohr if($suho && ($suho < $okay || $okay == 0)) $okay = $suho; 1566f940e4a0SAndreas Gohr if($upld && ($upld < $okay || $okay == 0)) $okay = $upld; 1567f940e4a0SAndreas Gohr 1568f940e4a0SAndreas Gohr return $okay; 15699f5dde7fSMichael Klier} 15703df72098SAndreas Gohr 15713df72098SAndreas Gohr/** 1572bf1f3ac4Ssarnowski * Print the search field form 1573bf1f3ac4Ssarnowski * 1574bf1f3ac4Ssarnowski * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1575d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1576e0c26282SGerrit Uitslag * 1577e0c26282SGerrit Uitslag * @param string $ns 1578e0c26282SGerrit Uitslag * @param string $query 1579e0c26282SGerrit Uitslag * @param bool $fullscreen 1580bf1f3ac4Ssarnowski */ 1581d9162c6cSKate Arzamastsevafunction media_searchform($ns, $query = '', $fullscreen = false) { 1582bf1f3ac4Ssarnowski global $lang; 1583bf1f3ac4Ssarnowski 1584bf1f3ac4Ssarnowski // The default HTML search form 1585b960c74fSSatoshi Sahara $form = new Form([ 1586b960c74fSSatoshi Sahara 'id' => 'dw__mediasearch', 1587b960c74fSSatoshi Sahara 'action' => ($fullscreen) 1588b960c74fSSatoshi Sahara ? media_managerURL([], '&') 1589b960c74fSSatoshi Sahara : DOKU_BASE.'lib/exe/mediamanager.php', 1590b960c74fSSatoshi Sahara ]); 1591b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1592b960c74fSSatoshi Sahara $form->setHiddenField('ns', $ns); 1593b960c74fSSatoshi Sahara $form->setHiddenField($fullscreen ? 'mediado' : 'do', 'searchlist'); 1594554a8c9fSAdrian Lang 1595b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1596bde2a644SSatoshi Sahara $form->addTextInput('q', $lang['searchmedia']) 1597b960c74fSSatoshi Sahara ->attr('title', sprintf($lang['searchmedia_in'], hsc($ns) .':*')) 1598b960c74fSSatoshi Sahara ->val($query); 1599bde2a644SSatoshi Sahara $form->addHTML(' '); 1600b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_search'])->attr('type', 'submit'); 1601b960c74fSSatoshi Sahara $form->addTagClose('p'); 1602b960c74fSSatoshi Sahara $form->addTagClose('div'); 1603c6977b3aSSatoshi Sahara print $form->toHTML('SearchMedia'); 1604bf1f3ac4Ssarnowski} 1605bf1f3ac4Ssarnowski 1606bf1f3ac4Ssarnowski/** 16073df72098SAndreas Gohr * Build a tree outline of available media namespaces 16083df72098SAndreas Gohr * 16093df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1610e0c26282SGerrit Uitslag * 1611e0c26282SGerrit Uitslag * @param string $ns 16123df72098SAndreas Gohr */ 16133df72098SAndreas Gohrfunction media_nstree($ns){ 16143df72098SAndreas Gohr global $conf; 1615256ca81eSAndreas Gohr global $lang; 16163df72098SAndreas Gohr 16173df72098SAndreas Gohr // currently selected namespace 16183df72098SAndreas Gohr $ns = cleanID($ns); 16193df72098SAndreas Gohr if(empty($ns)){ 1620de3eb1d7SAdrian Lang global $ID; 1621dd90013aSMichael Hamann $ns = (string)getNS($ID); 16223df72098SAndreas Gohr } 1623dd90013aSMichael Hamann 1624dd90013aSMichael Hamann $ns_dir = utf8_encodeFN(str_replace(':','/',$ns)); 16253df72098SAndreas Gohr 1626*24870174SAndreas Gohr $data = []; 1627*24870174SAndreas Gohr search($data,$conf['mediadir'],'search_index',['ns' => $ns_dir, 'nofiles' => true]); 16283df72098SAndreas Gohr 16293df72098SAndreas Gohr // wrap a list with the root level around the other namespaces 1630*24870174SAndreas Gohr array_unshift($data, ['level' => 0, 'id' => '', 'open' =>'true', 'label' => '['.$lang['mediaroot'].']']); 16313df72098SAndreas Gohr 1632dd90013aSMichael Hamann // insert the current ns into the hierarchy if it isn't already part of it 1633dd90013aSMichael Hamann $ns_parts = explode(':', $ns); 1634dd90013aSMichael Hamann $tmp_ns = ''; 1635dd90013aSMichael Hamann $pos = 0; 1636dd90013aSMichael Hamann foreach ($ns_parts as $level => $part) { 1637dd90013aSMichael Hamann if ($tmp_ns) $tmp_ns .= ':'.$part; 1638dd90013aSMichael Hamann else $tmp_ns = $part; 1639dd90013aSMichael Hamann 1640dd90013aSMichael Hamann // find the namespace parts or insert them 1641dd90013aSMichael Hamann while ($data[$pos]['id'] != $tmp_ns) { 164264159a61SAndreas Gohr if ( 164364159a61SAndreas Gohr $pos >= count($data) || 16442d85e841SAndreas Gohr ($data[$pos]['level'] <= $level+1 && Sort::strcmp($data[$pos]['id'], $tmp_ns) > 0) 164564159a61SAndreas Gohr ) { 1646*24870174SAndreas Gohr array_splice($data, $pos, 0, [['level' => $level+1, 'id' => $tmp_ns, 'open' => 'true']]); 1647dd90013aSMichael Hamann break; 1648dd90013aSMichael Hamann } 1649dd90013aSMichael Hamann ++$pos; 1650dd90013aSMichael Hamann } 1651dd90013aSMichael Hamann } 1652dd90013aSMichael Hamann 16533df72098SAndreas Gohr echo html_buildlist($data,'idx','media_nstree_item','media_nstree_li'); 16543df72098SAndreas Gohr} 16553df72098SAndreas Gohr 16563df72098SAndreas Gohr/** 16573df72098SAndreas Gohr * Userfunction for html_buildlist 16583df72098SAndreas Gohr * 16593df72098SAndreas Gohr * Prints a media namespace tree item 16603df72098SAndreas Gohr * 16613df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 166242ea7f44SGerrit Uitslag * 166342ea7f44SGerrit Uitslag * @param array $item 166442ea7f44SGerrit Uitslag * @return string html 16653df72098SAndreas Gohr */ 16663df72098SAndreas Gohrfunction media_nstree_item($item){ 16678108113cSTom N Harris global $INPUT; 16683df72098SAndreas Gohr $pos = strrpos($item['id'], ':'); 16693df72098SAndreas Gohr $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); 16700e80bb5eSChristopher Smith if(empty($item['label'])) $item['label'] = $label; 16713df72098SAndreas Gohr 16723df72098SAndreas Gohr $ret = ''; 1673*24870174SAndreas Gohr if ($INPUT->str('do') != 'media') 16743df72098SAndreas Gohr $ret .= '<a href="'.DOKU_BASE.'lib/exe/mediamanager.php?ns='.idfilter($item['id']).'" class="idx_dir">'; 1675b960c74fSSatoshi Sahara else $ret .= '<a href="'.media_managerURL(['ns' => idfilter($item['id'], false), 'tab_files' => 'files']) 167623846a98SKate Arzamastseva .'" class="idx_dir">'; 16773df72098SAndreas Gohr $ret .= $item['label']; 16783df72098SAndreas Gohr $ret .= '</a>'; 16793df72098SAndreas Gohr return $ret; 16803df72098SAndreas Gohr} 16813df72098SAndreas Gohr 16823df72098SAndreas Gohr/** 16833df72098SAndreas Gohr * Userfunction for html_buildlist 16843df72098SAndreas Gohr * 16853df72098SAndreas Gohr * Prints a media namespace tree item opener 16863df72098SAndreas Gohr * 16873df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 168842ea7f44SGerrit Uitslag * 168942ea7f44SGerrit Uitslag * @param array $item 169042ea7f44SGerrit Uitslag * @return string html 16913df72098SAndreas Gohr */ 16923df72098SAndreas Gohrfunction media_nstree_li($item){ 16933df72098SAndreas Gohr $class='media level'.$item['level']; 16943df72098SAndreas Gohr if($item['open']){ 16953df72098SAndreas Gohr $class .= ' open'; 16963df72098SAndreas Gohr $img = DOKU_BASE.'lib/images/minus.gif'; 1697e260f93bSAnika Henke $alt = '−'; 16983df72098SAndreas Gohr }else{ 16993df72098SAndreas Gohr $class .= ' closed'; 17003df72098SAndreas Gohr $img = DOKU_BASE.'lib/images/plus.gif'; 17017af1b404SAnika Henke $alt = '+'; 17023df72098SAndreas Gohr } 1703231b8c34SPierre Spring // TODO: only deliver an image if it actually has a subtree... 17043df72098SAndreas Gohr return '<li class="'.$class.'">'. 17057af1b404SAnika Henke '<img src="'.$img.'" alt="'.$alt.'" />'; 17063df72098SAndreas Gohr} 170713c08e2fSMichael Klier 170813c08e2fSMichael Klier/** 1709b021f0b4SAndreas Gohr * Resizes or crop the given image to the given size 1710b021f0b4SAndreas Gohr * 1711b021f0b4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1712b021f0b4SAndreas Gohr * 1713b021f0b4SAndreas Gohr * @param string $file filename, path to file 1714b021f0b4SAndreas Gohr * @param string $ext extension 1715b021f0b4SAndreas Gohr * @param int $w desired width 1716b021f0b4SAndreas Gohr * @param int $h desired height 1717b021f0b4SAndreas Gohr * @param bool $crop should a center crop be used? 1718b021f0b4SAndreas Gohr * @return string path to resized or original size if failed 1719b021f0b4SAndreas Gohr */ 1720b021f0b4SAndreas Gohrfunction media_mod_image($file, $ext, $w, $h=0, $crop=false) 1721b021f0b4SAndreas Gohr{ 1722b021f0b4SAndreas Gohr global $conf; 1723d967ecd8SAndreas Gohr if(!$h) $h = 0; 1724b021f0b4SAndreas Gohr // we wont scale up to infinity 1725b021f0b4SAndreas Gohr if($w > 2000 || $h > 2000) return $file; 1726b021f0b4SAndreas Gohr 1727b021f0b4SAndreas Gohr $operation = $crop ? 'crop' : 'resize'; 1728b021f0b4SAndreas Gohr 1729b021f0b4SAndreas Gohr $options = [ 1730b021f0b4SAndreas Gohr 'quality' => $conf['jpg_quality'], 1731b021f0b4SAndreas Gohr 'imconvert' => $conf['im_convert'], 1732b021f0b4SAndreas Gohr ]; 1733b021f0b4SAndreas Gohr 1734*24870174SAndreas Gohr $cache = new CacheImageMod($file, $w, $h, $ext, $crop); 1735b021f0b4SAndreas Gohr if(!$cache->useCache()) { 1736b021f0b4SAndreas Gohr try { 1737b021f0b4SAndreas Gohr Slika::run($file, $options) 1738b021f0b4SAndreas Gohr ->autorotate() 1739b021f0b4SAndreas Gohr ->$operation($w, $h) 1740b021f0b4SAndreas Gohr ->save($cache->cache, $ext); 1741b021f0b4SAndreas Gohr if($conf['fperm']) @chmod($cache->cache, $conf['fperm']); 1742*24870174SAndreas Gohr } catch (Exception $e) { 1743b021f0b4SAndreas Gohr Logger::debug($e->getMessage()); 1744b021f0b4SAndreas Gohr return $file; 1745b021f0b4SAndreas Gohr } 1746b021f0b4SAndreas Gohr } 1747b021f0b4SAndreas Gohr 1748b021f0b4SAndreas Gohr return $cache->cache; 1749b021f0b4SAndreas Gohr} 1750b021f0b4SAndreas Gohr 1751b021f0b4SAndreas Gohr/** 175213c08e2fSMichael Klier * Resizes the given image to the given size 175313c08e2fSMichael Klier * 175413c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 175542ea7f44SGerrit Uitslag * 175642ea7f44SGerrit Uitslag * @param string $file filename, path to file 175742ea7f44SGerrit Uitslag * @param string $ext extension 175842ea7f44SGerrit Uitslag * @param int $w desired width 175942ea7f44SGerrit Uitslag * @param int $h desired height 176042ea7f44SGerrit Uitslag * @return string path to resized or original size if failed 176113c08e2fSMichael Klier */ 1762b021f0b4SAndreas Gohrfunction media_resize_image($file, $ext, $w, $h = 0) 1763b021f0b4SAndreas Gohr{ 1764b021f0b4SAndreas Gohr return media_mod_image($file, $ext, $w, $h, false); 1765d2bd34a5SAndreas Gohr} 176613c08e2fSMichael Klier 176713c08e2fSMichael Klier/** 1768d2bd34a5SAndreas Gohr * Center crops the given image to the wanted size 176913c08e2fSMichael Klier * 177013c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 177142ea7f44SGerrit Uitslag * 177242ea7f44SGerrit Uitslag * @param string $file filename, path to file 177342ea7f44SGerrit Uitslag * @param string $ext extension 177442ea7f44SGerrit Uitslag * @param int $w desired width 177542ea7f44SGerrit Uitslag * @param int $h desired height 177642ea7f44SGerrit Uitslag * @return string path to resized or original size if failed 177713c08e2fSMichael Klier */ 1778b021f0b4SAndreas Gohrfunction media_crop_image($file, $ext, $w, $h = 0) 1779b021f0b4SAndreas Gohr{ 1780b021f0b4SAndreas Gohr return media_mod_image($file, $ext, $w, $h, true); 178113c08e2fSMichael Klier} 178213c08e2fSMichael Klier 178313c08e2fSMichael Klier/** 17840f4e0092SChristopher Smith * Calculate a token to be used to verify fetch requests for resized or 17850f4e0092SChristopher Smith * cropped images have been internally generated - and prevent external 17860f4e0092SChristopher Smith * DDOS attacks via fetch 17870f4e0092SChristopher Smith * 17883c124064SAndreas Gohr * @author Christopher Smith <chris@jalakai.co.uk> 17893c124064SAndreas Gohr * 17900f4e0092SChristopher Smith * @param string $id id of the image 17910f4e0092SChristopher Smith * @param int $w resize/crop width 17920f4e0092SChristopher Smith * @param int $h resize/crop height 179342ea7f44SGerrit Uitslag * @return string token or empty string if no token required 17940f4e0092SChristopher Smith */ 17950f4e0092SChristopher Smithfunction media_get_token($id,$w,$h){ 17960f4e0092SChristopher Smith // token is only required for modified images 1797cc036f74SKlap-in if ($w || $h || media_isexternal($id)) { 17983c124064SAndreas Gohr $token = $id; 17990f4e0092SChristopher Smith if ($w) $token .= '.'.$w; 18000f4e0092SChristopher Smith if ($h) $token .= '.'.$h; 18010f4e0092SChristopher Smith 1802*24870174SAndreas Gohr return substr(PassHash::hmac('md5', $token, auth_cookiesalt()),0,6); 18030f4e0092SChristopher Smith } 18040f4e0092SChristopher Smith 18050f4e0092SChristopher Smith return ''; 18060f4e0092SChristopher Smith} 18070f4e0092SChristopher Smith 18080f4e0092SChristopher Smith/** 180913c08e2fSMichael Klier * Download a remote file and return local filename 181013c08e2fSMichael Klier * 181113c08e2fSMichael Klier * returns false if download fails. Uses cached file if available and 181213c08e2fSMichael Klier * wanted 181313c08e2fSMichael Klier * 181413c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 181513c08e2fSMichael Klier * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 181642ea7f44SGerrit Uitslag * 181742ea7f44SGerrit Uitslag * @param string $url 181842ea7f44SGerrit Uitslag * @param string $ext extension 181942ea7f44SGerrit Uitslag * @param int $cache cachetime in seconds 182042ea7f44SGerrit Uitslag * @return false|string path to cached file 182113c08e2fSMichael Klier */ 182213c08e2fSMichael Klierfunction media_get_from_URL($url,$ext,$cache){ 182313c08e2fSMichael Klier global $conf; 182413c08e2fSMichael Klier 182513c08e2fSMichael Klier // if no cache or fetchsize just redirect 182613c08e2fSMichael Klier if ($cache==0) return false; 182713c08e2fSMichael Klier if (!$conf['fetchsize']) return false; 182813c08e2fSMichael Klier 182913c08e2fSMichael Klier $local = getCacheName(strtolower($url),".media.$ext"); 183013c08e2fSMichael Klier $mtime = @filemtime($local); // 0 if not exists 183113c08e2fSMichael Klier 183213c08e2fSMichael Klier //decide if download needed: 183313c08e2fSMichael Klier if(($mtime == 0) || // cache does not exist 183413c08e2fSMichael Klier ($cache != -1 && $mtime < time() - $cache) // 'recache' and cache has expired 183513c08e2fSMichael Klier ) { 183613c08e2fSMichael Klier if(media_image_download($url, $local)) { 183713c08e2fSMichael Klier return $local; 183813c08e2fSMichael Klier } else { 183913c08e2fSMichael Klier return false; 184013c08e2fSMichael Klier } 184113c08e2fSMichael Klier } 184213c08e2fSMichael Klier 184313c08e2fSMichael Klier //if cache exists use it else 184413c08e2fSMichael Klier if($mtime) return $local; 184513c08e2fSMichael Klier 184613c08e2fSMichael Klier //else return false 184713c08e2fSMichael Klier return false; 184813c08e2fSMichael Klier} 184913c08e2fSMichael Klier 185013c08e2fSMichael Klier/** 185113c08e2fSMichael Klier * Download image files 185213c08e2fSMichael Klier * 185313c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 185442ea7f44SGerrit Uitslag * 185542ea7f44SGerrit Uitslag * @param string $url 185642ea7f44SGerrit Uitslag * @param string $file path to file in which to put the downloaded content 185742ea7f44SGerrit Uitslag * @return bool 185813c08e2fSMichael Klier */ 185913c08e2fSMichael Klierfunction media_image_download($url,$file){ 186013c08e2fSMichael Klier global $conf; 186113c08e2fSMichael Klier $http = new DokuHTTPClient(); 1862a5951419SAndreas Gohr $http->keep_alive = false; // we do single ops here, no need for keep-alive 1863a5951419SAndreas Gohr 186413c08e2fSMichael Klier $http->max_bodysize = $conf['fetchsize']; 186513c08e2fSMichael Klier $http->timeout = 25; //max. 25 sec 186613c08e2fSMichael Klier $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; 186713c08e2fSMichael Klier 186813c08e2fSMichael Klier $data = $http->get($url); 186913c08e2fSMichael Klier if(!$data) return false; 187013c08e2fSMichael Klier 187179e79377SAndreas Gohr $fileexists = file_exists($file); 187213c08e2fSMichael Klier $fp = @fopen($file,"w"); 187313c08e2fSMichael Klier if(!$fp) return false; 187413c08e2fSMichael Klier fwrite($fp,$data); 187513c08e2fSMichael Klier fclose($fp); 1876*24870174SAndreas Gohr if(!$fileexists && $conf['fperm']) chmod($file, $conf['fperm']); 187713c08e2fSMichael Klier 187813c08e2fSMichael Klier // check if it is really an image 187913c08e2fSMichael Klier $info = @getimagesize($file); 188013c08e2fSMichael Klier if(!$info){ 188113c08e2fSMichael Klier @unlink($file); 188213c08e2fSMichael Klier return false; 188313c08e2fSMichael Klier } 188413c08e2fSMichael Klier 188513c08e2fSMichael Klier return true; 188613c08e2fSMichael Klier} 188713c08e2fSMichael Klier 188813c08e2fSMichael Klier/** 188913c08e2fSMichael Klier * resize images using external ImageMagick convert program 189013c08e2fSMichael Klier * 189113c08e2fSMichael Klier * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 189213c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 189342ea7f44SGerrit Uitslag * 189442ea7f44SGerrit Uitslag * @param string $ext extension 189542ea7f44SGerrit Uitslag * @param string $from filename path to file 189642ea7f44SGerrit Uitslag * @param int $from_w original width 189742ea7f44SGerrit Uitslag * @param int $from_h original height 189842ea7f44SGerrit Uitslag * @param string $to path to resized file 189942ea7f44SGerrit Uitslag * @param int $to_w desired width 190042ea7f44SGerrit Uitslag * @param int $to_h desired height 190142ea7f44SGerrit Uitslag * @return bool 190213c08e2fSMichael Klier */ 190313c08e2fSMichael Klierfunction media_resize_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){ 190413c08e2fSMichael Klier global $conf; 190513c08e2fSMichael Klier 190613c08e2fSMichael Klier // check if convert is configured 190713c08e2fSMichael Klier if(!$conf['im_convert']) return false; 190813c08e2fSMichael Klier 190913c08e2fSMichael Klier // prepare command 191013c08e2fSMichael Klier $cmd = $conf['im_convert']; 191113c08e2fSMichael Klier $cmd .= ' -resize '.$to_w.'x'.$to_h.'!'; 191213c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 191313c08e2fSMichael Klier $cmd .= ' -quality '.$conf['jpg_quality']; 191413c08e2fSMichael Klier } 191513c08e2fSMichael Klier $cmd .= " $from $to"; 191613c08e2fSMichael Klier 191713c08e2fSMichael Klier @exec($cmd,$out,$retval); 191813c08e2fSMichael Klier if ($retval == 0) return true; 191913c08e2fSMichael Klier return false; 192013c08e2fSMichael Klier} 192113c08e2fSMichael Klier 192213c08e2fSMichael Klier/** 192313c08e2fSMichael Klier * crop images using external ImageMagick convert program 192413c08e2fSMichael Klier * 192513c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 192642ea7f44SGerrit Uitslag * 192742ea7f44SGerrit Uitslag * @param string $ext extension 192842ea7f44SGerrit Uitslag * @param string $from filename path to file 192942ea7f44SGerrit Uitslag * @param int $from_w original width 193042ea7f44SGerrit Uitslag * @param int $from_h original height 193142ea7f44SGerrit Uitslag * @param string $to path to resized file 193242ea7f44SGerrit Uitslag * @param int $to_w desired width 193342ea7f44SGerrit Uitslag * @param int $to_h desired height 193442ea7f44SGerrit Uitslag * @param int $ofs_x offset of crop centre 193542ea7f44SGerrit Uitslag * @param int $ofs_y offset of crop centre 193642ea7f44SGerrit Uitslag * @return bool 1937d2bd34a5SAndreas Gohr * @deprecated 2020-09-01 193813c08e2fSMichael Klier */ 193913c08e2fSMichael Klierfunction media_crop_imageIM($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x,$ofs_y){ 194013c08e2fSMichael Klier global $conf; 1941d2bd34a5SAndreas Gohr dbg_deprecated('splitbrain\\Slika'); 194213c08e2fSMichael Klier 194313c08e2fSMichael Klier // check if convert is configured 194413c08e2fSMichael Klier if(!$conf['im_convert']) return false; 194513c08e2fSMichael Klier 194613c08e2fSMichael Klier // prepare command 194713c08e2fSMichael Klier $cmd = $conf['im_convert']; 194813c08e2fSMichael Klier $cmd .= ' -crop '.$to_w.'x'.$to_h.'+'.$ofs_x.'+'.$ofs_y; 194913c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 195013c08e2fSMichael Klier $cmd .= ' -quality '.$conf['jpg_quality']; 195113c08e2fSMichael Klier } 195213c08e2fSMichael Klier $cmd .= " $from $to"; 195313c08e2fSMichael Klier 195413c08e2fSMichael Klier @exec($cmd,$out,$retval); 195513c08e2fSMichael Klier if ($retval == 0) return true; 195613c08e2fSMichael Klier return false; 195713c08e2fSMichael Klier} 195813c08e2fSMichael Klier 195913c08e2fSMichael Klier/** 196013c08e2fSMichael Klier * resize or crop images using PHP's libGD support 196113c08e2fSMichael Klier * 196213c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 196313c08e2fSMichael Klier * @author Sebastian Wienecke <s_wienecke@web.de> 196442ea7f44SGerrit Uitslag * 196542ea7f44SGerrit Uitslag * @param string $ext extension 196642ea7f44SGerrit Uitslag * @param string $from filename path to file 196742ea7f44SGerrit Uitslag * @param int $from_w original width 196842ea7f44SGerrit Uitslag * @param int $from_h original height 196942ea7f44SGerrit Uitslag * @param string $to path to resized file 197042ea7f44SGerrit Uitslag * @param int $to_w desired width 197142ea7f44SGerrit Uitslag * @param int $to_h desired height 197242ea7f44SGerrit Uitslag * @param int $ofs_x offset of crop centre 197342ea7f44SGerrit Uitslag * @param int $ofs_y offset of crop centre 197442ea7f44SGerrit Uitslag * @return bool 1975d2bd34a5SAndreas Gohr * @deprecated 2020-09-01 197613c08e2fSMichael Klier */ 197713c08e2fSMichael Klierfunction media_resize_imageGD($ext,$from,$from_w,$from_h,$to,$to_w,$to_h,$ofs_x=0,$ofs_y=0){ 197813c08e2fSMichael Klier global $conf; 1979d2bd34a5SAndreas Gohr dbg_deprecated('splitbrain\\Slika'); 198013c08e2fSMichael Klier 198113c08e2fSMichael Klier if($conf['gdlib'] < 1) return false; //no GDlib available or wanted 198213c08e2fSMichael Klier 198313c08e2fSMichael Klier // check available memory 198413c08e2fSMichael Klier if(!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))){ 198513c08e2fSMichael Klier return false; 198613c08e2fSMichael Klier } 198713c08e2fSMichael Klier 198813c08e2fSMichael Klier // create an image of the given filetype 198959bc3b48SGerrit Uitslag $image = false; 199013c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg'){ 199113c08e2fSMichael Klier if(!function_exists("imagecreatefromjpeg")) return false; 199213c08e2fSMichael Klier $image = @imagecreatefromjpeg($from); 199313c08e2fSMichael Klier }elseif($ext == 'png') { 199413c08e2fSMichael Klier if(!function_exists("imagecreatefrompng")) return false; 199513c08e2fSMichael Klier $image = @imagecreatefrompng($from); 199613c08e2fSMichael Klier 199713c08e2fSMichael Klier }elseif($ext == 'gif') { 199813c08e2fSMichael Klier if(!function_exists("imagecreatefromgif")) return false; 199913c08e2fSMichael Klier $image = @imagecreatefromgif($from); 200013c08e2fSMichael Klier } 200113c08e2fSMichael Klier if(!$image) return false; 200213c08e2fSMichael Klier 200359bc3b48SGerrit Uitslag $newimg = false; 200413c08e2fSMichael Klier if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor") && $ext != 'gif'){ 200513c08e2fSMichael Klier $newimg = @imagecreatetruecolor ($to_w, $to_h); 200613c08e2fSMichael Klier } 200713c08e2fSMichael Klier if(!$newimg) $newimg = @imagecreate($to_w, $to_h); 200813c08e2fSMichael Klier if(!$newimg){ 200913c08e2fSMichael Klier imagedestroy($image); 201013c08e2fSMichael Klier return false; 201113c08e2fSMichael Klier } 201213c08e2fSMichael Klier 201313c08e2fSMichael Klier //keep png alpha channel if possible 201413c08e2fSMichael Klier if($ext == 'png' && $conf['gdlib']>1 && function_exists('imagesavealpha')){ 201513c08e2fSMichael Klier imagealphablending($newimg, false); 201613c08e2fSMichael Klier imagesavealpha($newimg,true); 201713c08e2fSMichael Klier } 201813c08e2fSMichael Klier 201913c08e2fSMichael Klier //keep gif transparent color if possible 202013c08e2fSMichael Klier if($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { 202113c08e2fSMichael Klier if(function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { 202213c08e2fSMichael Klier $transcolorindex = @imagecolortransparent($image); 202313c08e2fSMichael Klier if($transcolorindex >= 0 ) { //transparent color exists 202413c08e2fSMichael Klier $transcolor = @imagecolorsforindex($image, $transcolorindex); 202564159a61SAndreas Gohr $transcolorindex = @imagecolorallocate( 202664159a61SAndreas Gohr $newimg, 202764159a61SAndreas Gohr $transcolor['red'], 202864159a61SAndreas Gohr $transcolor['green'], 202964159a61SAndreas Gohr $transcolor['blue'] 203064159a61SAndreas Gohr ); 203113c08e2fSMichael Klier @imagefill($newimg, 0, 0, $transcolorindex); 203213c08e2fSMichael Klier @imagecolortransparent($newimg, $transcolorindex); 203313c08e2fSMichael Klier }else{ //filling with white 203413c08e2fSMichael Klier $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 203513c08e2fSMichael Klier @imagefill($newimg, 0, 0, $whitecolorindex); 203613c08e2fSMichael Klier } 203713c08e2fSMichael Klier }else{ //filling with white 203813c08e2fSMichael Klier $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 203913c08e2fSMichael Klier @imagefill($newimg, 0, 0, $whitecolorindex); 204013c08e2fSMichael Klier } 204113c08e2fSMichael Klier } 204213c08e2fSMichael Klier 204313c08e2fSMichael Klier //try resampling first 204413c08e2fSMichael Klier if(function_exists("imagecopyresampled")){ 204513c08e2fSMichael Klier if(!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { 204613c08e2fSMichael Klier imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 204713c08e2fSMichael Klier } 204813c08e2fSMichael Klier }else{ 204913c08e2fSMichael Klier imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 205013c08e2fSMichael Klier } 205113c08e2fSMichael Klier 205213c08e2fSMichael Klier $okay = false; 205313c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg'){ 205413c08e2fSMichael Klier if(!function_exists('imagejpeg')){ 205513c08e2fSMichael Klier $okay = false; 205613c08e2fSMichael Klier }else{ 205713c08e2fSMichael Klier $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); 205813c08e2fSMichael Klier } 205913c08e2fSMichael Klier }elseif($ext == 'png') { 206013c08e2fSMichael Klier if(!function_exists('imagepng')){ 206113c08e2fSMichael Klier $okay = false; 206213c08e2fSMichael Klier }else{ 206313c08e2fSMichael Klier $okay = imagepng($newimg, $to); 206413c08e2fSMichael Klier } 206513c08e2fSMichael Klier }elseif($ext == 'gif') { 206613c08e2fSMichael Klier if(!function_exists('imagegif')){ 206713c08e2fSMichael Klier $okay = false; 206813c08e2fSMichael Klier }else{ 206913c08e2fSMichael Klier $okay = imagegif($newimg, $to); 207013c08e2fSMichael Klier } 207113c08e2fSMichael Klier } 207213c08e2fSMichael Klier 207379a2d784SGerrit Uitslag // destroy GD image resources 207479a2d784SGerrit Uitslag imagedestroy($image); 207579a2d784SGerrit Uitslag imagedestroy($newimg); 207613c08e2fSMichael Klier 207713c08e2fSMichael Klier return $okay; 207813c08e2fSMichael Klier} 207913c08e2fSMichael Klier 20803d7a9e0aSAnika Henke/** 20813d7a9e0aSAnika Henke * Return other media files with the same base name 208279e53fe5SAnika Henke * but different extensions. 20833d7a9e0aSAnika Henke * 20843d7a9e0aSAnika Henke * @param string $src - ID of media file 208542ea7f44SGerrit Uitslag * @param string[] $exts - alternative extensions to find other files for 208642ea7f44SGerrit Uitslag * @return array - array(mime type => file ID) 20873d7a9e0aSAnika Henke * 20883d7a9e0aSAnika Henke * @author Anika Henke <anika@selfthinker.org> 20893d7a9e0aSAnika Henke */ 209079e53fe5SAnika Henkefunction media_alternativefiles($src, $exts){ 20913d7a9e0aSAnika Henke 2092*24870174SAndreas Gohr $files = []; 2093*24870174SAndreas Gohr [$srcExt, ] = mimetype($src); 20943d7a9e0aSAnika Henke $filebase = substr($src, 0, -1 * (strlen($srcExt)+1)); 20953d7a9e0aSAnika Henke 20963d7a9e0aSAnika Henke foreach($exts as $ext) { 20973d7a9e0aSAnika Henke $fileid = $filebase.'.'.$ext; 20983d7a9e0aSAnika Henke $file = mediaFN($fileid); 20993d7a9e0aSAnika Henke if(file_exists($file)) { 2100*24870174SAndreas Gohr [, $fileMime] = mimetype($file); 210179e53fe5SAnika Henke $files[$fileMime] = $fileid; 210299f943f6SAnika Henke } 21033d7a9e0aSAnika Henke } 21043d7a9e0aSAnika Henke return $files; 21053d7a9e0aSAnika Henke} 21063d7a9e0aSAnika Henke 2107f50634f0SAnika Henke/** 2108f50634f0SAnika Henke * Check if video/audio is supported to be embedded. 2109f50634f0SAnika Henke * 2110b83a74f1SAnika Henke * @param string $mime - mimetype of media file 211142ea7f44SGerrit Uitslag * @param string $type - type of media files to check ('video', 'audio', or null for all) 2112f50634f0SAnika Henke * @return boolean 2113f50634f0SAnika Henke * 2114f50634f0SAnika Henke * @author Anika Henke <anika@selfthinker.org> 2115f50634f0SAnika Henke */ 2116f50634f0SAnika Henkefunction media_supportedav($mime, $type=NULL){ 2117*24870174SAndreas Gohr $supportedAudio = [ 2118f50634f0SAnika Henke 'ogg' => 'audio/ogg', 2119f50634f0SAnika Henke 'mp3' => 'audio/mpeg', 2120*24870174SAndreas Gohr 'wav' => 'audio/wav' 2121*24870174SAndreas Gohr ]; 2122*24870174SAndreas Gohr $supportedVideo = [ 2123f50634f0SAnika Henke 'webm' => 'video/webm', 2124f50634f0SAnika Henke 'ogv' => 'video/ogg', 2125*24870174SAndreas Gohr 'mp4' => 'video/mp4' 2126*24870174SAndreas Gohr ]; 2127f50634f0SAnika Henke if ($type == 'audio') { 2128f50634f0SAnika Henke $supportedAv = $supportedAudio; 2129f50634f0SAnika Henke } elseif ($type == 'video') { 2130f50634f0SAnika Henke $supportedAv = $supportedVideo; 2131f50634f0SAnika Henke } else { 2132f50634f0SAnika Henke $supportedAv = array_merge($supportedAudio, $supportedVideo); 2133f50634f0SAnika Henke } 2134f50634f0SAnika Henke return in_array($mime, $supportedAv); 2135f50634f0SAnika Henke} 2136f50634f0SAnika Henke 21370877a1f1SSchplurtz le Déboulonné/** 21380877a1f1SSchplurtz le Déboulonné * Return track media files with the same base name 21390877a1f1SSchplurtz le Déboulonné * but extensions that indicate kind and lang. 21400877a1f1SSchplurtz le Déboulonné * ie for foo.webm search foo.sub.lang.vtt, foo.cap.lang.vtt... 21410877a1f1SSchplurtz le Déboulonné * 21420877a1f1SSchplurtz le Déboulonné * @param string $src - ID of media file 214301299338SSchplurtz le Déboulonné * @return array - array(mediaID => array( kind, srclang )) 21440877a1f1SSchplurtz le Déboulonné * 21450877a1f1SSchplurtz le Déboulonné * @author Schplurtz le Déboulonné <Schplurtz@laposte.net> 21460877a1f1SSchplurtz le Déboulonné */ 21470877a1f1SSchplurtz le Déboulonnéfunction media_trackfiles($src){ 2148*24870174SAndreas Gohr $kinds=[ 21490877a1f1SSchplurtz le Déboulonné 'sub' => 'subtitles', 21500877a1f1SSchplurtz le Déboulonné 'cap' => 'captions', 21510877a1f1SSchplurtz le Déboulonné 'des' => 'descriptions', 21520877a1f1SSchplurtz le Déboulonné 'cha' => 'chapters', 21530877a1f1SSchplurtz le Déboulonné 'met' => 'metadata' 2154*24870174SAndreas Gohr ]; 21550877a1f1SSchplurtz le Déboulonné 2156*24870174SAndreas Gohr $files = []; 21570877a1f1SSchplurtz le Déboulonné $re='/\\.(sub|cap|des|cha|met)\\.([^.]+)\\.vtt$/'; 21580877a1f1SSchplurtz le Déboulonné $baseid=pathinfo($src, PATHINFO_FILENAME); 21590877a1f1SSchplurtz le Déboulonné $pattern=mediaFN($baseid).'.*.*.vtt'; 21600877a1f1SSchplurtz le Déboulonné $list=glob($pattern); 21610877a1f1SSchplurtz le Déboulonné foreach($list as $track) { 21620877a1f1SSchplurtz le Déboulonné if(preg_match($re, $track, $matches)){ 2163*24870174SAndreas Gohr $files[$baseid.'.'.$matches[1].'.'.$matches[2].'.vtt']=[$kinds[$matches[1]], $matches[2]]; 21640877a1f1SSchplurtz le Déboulonné } 21650877a1f1SSchplurtz le Déboulonné } 21660877a1f1SSchplurtz le Déboulonné return $files; 21670877a1f1SSchplurtz le Déboulonné} 21680877a1f1SSchplurtz le Déboulonné 2169365be586SAndreas Gohr/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 2170