13df72098SAndreas Gohr<?php 2d4f83172SAndreas Gohr 33df72098SAndreas Gohr/** 43df72098SAndreas Gohr * All output and handler function needed for the media management popup 53df72098SAndreas Gohr * 63df72098SAndreas Gohr * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 73df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 83df72098SAndreas Gohr */ 93df72098SAndreas Gohr 1024870174SAndreas Gohruse dokuwiki\Ui\MediaRevisions; 1124870174SAndreas Gohruse dokuwiki\Cache\CacheImageMod; 1224870174SAndreas Gohruse splitbrain\slika\Exception; 1324870174SAndreas Gohruse dokuwiki\PassHash; 140c3a5702SAndreas Gohruse dokuwiki\ChangeLog\MediaChangeLog; 15e1d9dcc8SAndreas Gohruse dokuwiki\Extension\Event; 16b960c74fSSatoshi Saharause dokuwiki\Form\Form; 173df72098SAndreas Gohruse dokuwiki\HTTP\DokuHTTPClient; 1879a2d784SGerrit Uitslaguse dokuwiki\Logger; 190c3a5702SAndreas Gohruse dokuwiki\Subscriptions\MediaSubscriptionSender; 2079a2d784SGerrit Uitslaguse dokuwiki\Ui\Media\DisplayRow; 2179a2d784SGerrit Uitslaguse dokuwiki\Ui\Media\DisplayTile; 22*6734bb8cSAndreas Gohruse dokuwiki\Search\MetadataSearch; 2379a2d784SGerrit Uitslaguse dokuwiki\Ui\MediaDiff; 2479a2d784SGerrit Uitslaguse dokuwiki\Utf8\PhpString; 252d85e841SAndreas Gohruse dokuwiki\Utf8\Sort; 2679a2d784SGerrit Uitslaguse splitbrain\slika\Slika; 270c3a5702SAndreas Gohr 283df72098SAndreas Gohr/** 293df72098SAndreas Gohr * Lists pages which currently use a media file selected for deletion 303df72098SAndreas Gohr * 313df72098SAndreas Gohr * References uses the same visual as search results and share 323df72098SAndreas Gohr * their CSS tags except pagenames won't be links. 333df72098SAndreas Gohr * 343df72098SAndreas Gohr * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 3542ea7f44SGerrit Uitslag * 3642ea7f44SGerrit Uitslag * @param array $data 3742ea7f44SGerrit Uitslag * @param string $id 383df72098SAndreas Gohr */ 39d868eb89SAndreas Gohrfunction media_filesinuse($data, $id) 40d868eb89SAndreas Gohr{ 413df72098SAndreas Gohr global $lang; 423df72098SAndreas Gohr echo '<h1>' . $lang['reference'] . ' <code>' . hsc(noNS($id)) . '</code></h1>'; 433df72098SAndreas Gohr echo '<p>' . hsc($lang['ref_inuse']) . '</p>'; 443df72098SAndreas Gohr 453df72098SAndreas Gohr $hidden = 0; //count of hits without read permission 463df72098SAndreas Gohr foreach ($data as $row) { 47a05e297aSAndreas Gohr if (auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)) { 483df72098SAndreas Gohr echo '<div class="search_result">'; 49a05e297aSAndreas Gohr echo '<span class="mediaref_ref">' . hsc($row) . '</span>'; 503df72098SAndreas Gohr echo '</div>'; 51177d6836SAndreas Gohr } else $hidden++; 523df72098SAndreas Gohr } 533df72098SAndreas Gohr if ($hidden) { 5426dfc232SAndreas Gohr echo '<div class="mediaref_hidden">' . $lang['ref_hidden'] . '</div>'; 553df72098SAndreas Gohr } 563df72098SAndreas Gohr} 573df72098SAndreas Gohr 583df72098SAndreas Gohr/** 593df72098SAndreas Gohr * Handles the saving of image meta data 603df72098SAndreas Gohr * 613df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 62cf832786SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 63e0c26282SGerrit Uitslag * 64e0c26282SGerrit Uitslag * @param string $id media id 65e0c26282SGerrit Uitslag * @param int $auth permission level 66e0c26282SGerrit Uitslag * @param array $data 6742ea7f44SGerrit Uitslag * @return false|string 683df72098SAndreas Gohr */ 69d868eb89SAndreas Gohrfunction media_metasave($id, $auth, $data) 70d868eb89SAndreas Gohr{ 713df72098SAndreas Gohr if ($auth < AUTH_UPLOAD) return false; 72f2ea8432SAndreas Gohr if (!checkSecurityToken()) return false; 733df72098SAndreas Gohr global $lang; 740b308644SOtto Vainio global $conf; 753df72098SAndreas Gohr $src = mediaFN($id); 763df72098SAndreas Gohr 773df72098SAndreas Gohr $meta = new JpegMeta($src); 783df72098SAndreas Gohr $meta->_parseAll(); 793df72098SAndreas Gohr 803df72098SAndreas Gohr foreach ($data as $key => $val) { 813df72098SAndreas Gohr $val = trim($val); 823df72098SAndreas Gohr if (empty($val)) { 833df72098SAndreas Gohr $meta->deleteField($key); 843df72098SAndreas Gohr } else { 853df72098SAndreas Gohr $meta->setField($key, $val); 863df72098SAndreas Gohr } 873df72098SAndreas Gohr } 883df72098SAndreas Gohr 89cf832786SKate Arzamastseva $old = @filemtime($src); 9079e79377SAndreas Gohr if (!file_exists(mediaFN($id, $old)) && file_exists($src)) { 91cf832786SKate Arzamastseva // add old revision to the attic 92cf832786SKate Arzamastseva media_saveOldRevision($id); 93cf832786SKate Arzamastseva } 94ac3ed4afSGerrit Uitslag $filesize_old = filesize($src); 953df72098SAndreas Gohr if ($meta->save()) { 960b308644SOtto Vainio if ($conf['fperm']) chmod($src, $conf['fperm']); 97ac3ed4afSGerrit Uitslag @clearstatcache(true, $src); 98cf832786SKate Arzamastseva $new = @filemtime($src); 99ac3ed4afSGerrit Uitslag $filesize_new = filesize($src); 100ac3ed4afSGerrit Uitslag $sizechange = $filesize_new - $filesize_old; 101ac3ed4afSGerrit Uitslag 102cf832786SKate Arzamastseva // add a log entry to the media changelog 103ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited'], '', null, $sizechange); 104cf832786SKate Arzamastseva 1053df72098SAndreas Gohr msg($lang['metasaveok'], 1); 1063df72098SAndreas Gohr return $id; 1073df72098SAndreas Gohr } else { 1083df72098SAndreas Gohr msg($lang['metasaveerr'], -1); 1093df72098SAndreas Gohr return false; 1103df72098SAndreas Gohr } 1113df72098SAndreas Gohr} 1123df72098SAndreas Gohr 1133df72098SAndreas Gohr/** 114d54f7963SKlap-in * check if a media is external source 115d54f7963SKlap-in * 116d54f7963SKlap-in * @author Gerrit Uitslag <klapinklapin@gmail.com> 11742ea7f44SGerrit Uitslag * 118d54f7963SKlap-in * @param string $id the media ID or URL 119d54f7963SKlap-in * @return bool 120d54f7963SKlap-in */ 121d868eb89SAndreas Gohrfunction media_isexternal($id) 122d868eb89SAndreas Gohr{ 123fe578fe9SElan Ruusamäe if (preg_match('#^(?:https?|ftp)://#i', $id)) return true; 124d54f7963SKlap-in return false; 125d54f7963SKlap-in} 126d54f7963SKlap-in 127d54f7963SKlap-in/** 128add8678fSAndreas Gohr * Check if a media item is public (eg, external URL or readable by @ALL) 129add8678fSAndreas Gohr * 130add8678fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 13142ea7f44SGerrit Uitslag * 132add8678fSAndreas Gohr * @param string $id the media ID or URL 133add8678fSAndreas Gohr * @return bool 134add8678fSAndreas Gohr */ 135d868eb89SAndreas Gohrfunction media_ispublic($id) 136d868eb89SAndreas Gohr{ 137d54f7963SKlap-in if (media_isexternal($id)) return true; 138add8678fSAndreas Gohr $id = cleanID($id); 13924870174SAndreas Gohr if (auth_aclcheck(getNS($id) . ':*', '', []) >= AUTH_READ) return true; 140add8678fSAndreas Gohr return false; 141add8678fSAndreas Gohr} 142add8678fSAndreas Gohr 143add8678fSAndreas Gohr/** 1443df72098SAndreas Gohr * Display the form to edit image meta data 1453df72098SAndreas Gohr * 1463df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 147d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 148e0c26282SGerrit Uitslag * 149e0c26282SGerrit Uitslag * @param string $id media id 150e0c26282SGerrit Uitslag * @param int $auth permission level 151e0c26282SGerrit Uitslag * @return bool 1523df72098SAndreas Gohr */ 153d868eb89SAndreas Gohrfunction media_metaform($id, $auth) 154d868eb89SAndreas Gohr{ 155ebc28e69SAndreas Gohr global $lang; 1563df72098SAndreas Gohr 15788a71175SKate Arzamastseva if ($auth < AUTH_UPLOAD) { 158b960c74fSSatoshi Sahara echo '<div class="nothing">' . $lang['media_perm_upload'] . '</div>' . DOKU_LF; 15988a71175SKate Arzamastseva return false; 16088a71175SKate Arzamastseva } 16188a71175SKate Arzamastseva 1623df72098SAndreas Gohr // load the field descriptions 1633df72098SAndreas Gohr static $fields = null; 164b960c74fSSatoshi Sahara if ($fields === null) { 1653e98e685SKate Arzamastseva $config_files = getConfigFiles('mediameta'); 1663e98e685SKate Arzamastseva foreach ($config_files as $config_file) { 16779e79377SAndreas Gohr if (file_exists($config_file)) include($config_file); 1683df72098SAndreas Gohr } 1693df72098SAndreas Gohr } 1703df72098SAndreas Gohr 1713df72098SAndreas Gohr $src = mediaFN($id); 1723df72098SAndreas Gohr 1733df72098SAndreas Gohr // output 174b960c74fSSatoshi Sahara $form = new Form([ 175b960c74fSSatoshi Sahara 'action' => media_managerURL(['tab_details' => 'view'], '&'), 176b960c74fSSatoshi Sahara 'class' => 'meta' 177b960c74fSSatoshi Sahara ]); 178b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 179b960c74fSSatoshi Sahara $form->setHiddenField('img', $id); 180b960c74fSSatoshi Sahara $form->setHiddenField('mediado', 'save'); 1813df72098SAndreas Gohr foreach ($fields as $key => $field) { 1823df72098SAndreas Gohr // get current value 1833e98e685SKate Arzamastseva if (empty($field[0])) continue; 18424870174SAndreas Gohr $tags = [$field[0]]; 1855cefb623SEduardo Mozart de Oliveira if (isset($field[3]) && is_array($field[3])) $tags = array_merge($tags, $field[3]); 1863df72098SAndreas Gohr $value = tpl_img_getTag($tags, '', $src); 187ca6a0701SAndreas Gohr $value = cleanText($value); 1883df72098SAndreas Gohr 1893df72098SAndreas Gohr // prepare attributes 19024870174SAndreas Gohr $p = [ 191b960c74fSSatoshi Sahara 'class' => 'edit', 192b960c74fSSatoshi Sahara 'id' => 'meta__' . $key, 19324870174SAndreas Gohr 'name' => 'meta[' . $field[0] . ']' 19424870174SAndreas Gohr ]; 1953df72098SAndreas Gohr 196b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('row'); 1973df72098SAndreas Gohr if ($field[2] == 'text') { 198bde2a644SSatoshi Sahara $form->addTextInput( 19964159a61SAndreas Gohr $p['name'], 20079a2d784SGerrit Uitslag ($lang[$field[1]] ?: $field[1] . ':') 201b960c74fSSatoshi Sahara )->id($p['id'])->addClass($p['class'])->val($value); 2023df72098SAndreas Gohr } else { 203b960c74fSSatoshi Sahara $form->addTextarea($p['name'], $lang[$field[1]])->id($p['id']) 204b960c74fSSatoshi Sahara ->val(formText($value)) 205b960c74fSSatoshi Sahara ->addClass($p['class']) 206b960c74fSSatoshi Sahara ->attr('rows', '6')->attr('cols', '50'); 2073df72098SAndreas Gohr } 208b960c74fSSatoshi Sahara $form->addTagClose('div'); 2093df72098SAndreas Gohr } 210b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('buttons'); 211b960c74fSSatoshi Sahara $form->addButton('mediado[save]', $lang['btn_save'])->attr('type', 'submit') 212b960c74fSSatoshi Sahara ->attrs(['accesskey' => 's']); 213b960c74fSSatoshi Sahara $form->addTagClose('div'); 214ebc28e69SAndreas Gohr 215b960c74fSSatoshi Sahara $form->addTagClose('div'); 216b960c74fSSatoshi Sahara echo $form->toHTML(); 217ebc28e69SAndreas Gohr return true; 2183df72098SAndreas Gohr} 2193df72098SAndreas Gohr 220666cdec5SMichael Klier/** 22187229c84SAdrian Lang * Convenience function to check if a media file is still in use 222666cdec5SMichael Klier * 223666cdec5SMichael Klier * @author Michael Klier <chi@chimeric.de> 224e0c26282SGerrit Uitslag * 225e0c26282SGerrit Uitslag * @param string $id media id 226e0c26282SGerrit Uitslag * @return array|bool 227666cdec5SMichael Klier */ 228d868eb89SAndreas Gohrfunction media_inuse($id) 229d868eb89SAndreas Gohr{ 230666cdec5SMichael Klier global $conf; 231ebc28e69SAndreas Gohr 232666cdec5SMichael Klier if ($conf['refcheck']) { 233*6734bb8cSAndreas Gohr $mediareferences = (new MetadataSearch())->mediause($id, true); 23424870174SAndreas Gohr if ($mediareferences === []) { 2356dae2464SAndreas Gohr return false; 236666cdec5SMichael Klier } else { 237666cdec5SMichael Klier return $mediareferences; 238666cdec5SMichael Klier } 239666cdec5SMichael Klier } else { 240666cdec5SMichael Klier return false; 241666cdec5SMichael Klier } 242666cdec5SMichael Klier} 243a05e297aSAndreas Gohr 2443df72098SAndreas Gohr/** 2453df72098SAndreas Gohr * Handles media file deletions 2463df72098SAndreas Gohr * 2473df72098SAndreas Gohr * If configured, checks for media references before deletion 2483df72098SAndreas Gohr * 2493df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 25042ea7f44SGerrit Uitslag * 251ebc28e69SAndreas Gohr * @param string $id media id 25222db8df7SAndreas Gohr * @param int $auth no longer used 25387229c84SAdrian Lang * @return int One of: 0, 25463703ba5SAndreas Gohr * DOKU_MEDIA_DELETED, 25563703ba5SAndreas Gohr * DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS, 25663703ba5SAndreas Gohr * DOKU_MEDIA_NOT_AUTH, 25763703ba5SAndreas Gohr * DOKU_MEDIA_INUSE 2583df72098SAndreas Gohr */ 259d868eb89SAndreas Gohrfunction media_delete($id, $auth) 260d868eb89SAndreas Gohr{ 2616183fb05SKate Arzamastseva global $lang; 262ff04e8b7SAndreas Gohr $auth = auth_quickaclcheck(ltrim(getNS($id) . ':*', ':')); 26387229c84SAdrian Lang if ($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; 26487229c84SAdrian Lang if (media_inuse($id)) return DOKU_MEDIA_INUSE; 2653df72098SAndreas Gohr 2663df72098SAndreas Gohr $file = mediaFN($id); 2674a961e72SMichal Kolodziejski 2684a961e72SMichal Kolodziejski // trigger an event - MEDIA_DELETE_FILE 26924870174SAndreas Gohr $data = []; 270666cdec5SMichael Klier $data['id'] = $id; 27179a2d784SGerrit Uitslag $data['name'] = PhpString::basename($file); 2724a961e72SMichal Kolodziejski $data['path'] = $file; 27379e79377SAndreas Gohr $data['size'] = (file_exists($file)) ? filesize($file) : 0; 274666cdec5SMichael Klier 275666cdec5SMichael Klier $data['unl'] = false; 276666cdec5SMichael Klier $data['del'] = false; 277e1d9dcc8SAndreas Gohr $evt = new Event('MEDIA_DELETE_FILE', $data); 2784a961e72SMichal Kolodziejski if ($evt->advise_before()) { 2796183fb05SKate Arzamastseva $old = @filemtime($file); 28079e79377SAndreas Gohr if (!file_exists(mediaFN($id, $old)) && file_exists($file)) { 2816183fb05SKate Arzamastseva // add old revision to the attic 2826183fb05SKate Arzamastseva media_saveOldRevision($id); 2836183fb05SKate Arzamastseva } 2846183fb05SKate Arzamastseva 285666cdec5SMichael Klier $data['unl'] = @unlink($file); 286666cdec5SMichael Klier if ($data['unl']) { 287ac3ed4afSGerrit Uitslag $sizechange = 0 - $data['size']; 288ac3ed4afSGerrit Uitslag addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted'], '', null, $sizechange); 289ac3ed4afSGerrit Uitslag 290666cdec5SMichael Klier $data['del'] = io_sweepNS($id, 'mediadir'); 2913df72098SAndreas Gohr } 2924a961e72SMichal Kolodziejski } 2934a961e72SMichal Kolodziejski $evt->advise_after(); 2944a961e72SMichal Kolodziejski unset($evt); 2954a961e72SMichal Kolodziejski 296666cdec5SMichael Klier if ($data['unl'] && $data['del']) { 29787229c84SAdrian Lang return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS; 2983df72098SAndreas Gohr } 2993df72098SAndreas Gohr 30087229c84SAdrian Lang return $data['unl'] ? DOKU_MEDIA_DELETED : 0; 3013df72098SAndreas Gohr} 3023df72098SAndreas Gohr 3033df72098SAndreas Gohr/** 3042d6cc64fSKate Arzamastseva * Handle file uploads via XMLHttpRequest 3052d6cc64fSKate Arzamastseva * 306ebc28e69SAndreas Gohr * @param string $ns target namespace 307ebc28e69SAndreas Gohr * @param int $auth current auth check result 30842ea7f44SGerrit Uitslag * @return false|string false on error, id of the new file on success 3092d6cc64fSKate Arzamastseva */ 310d868eb89SAndreas Gohrfunction media_upload_xhr($ns, $auth) 311d868eb89SAndreas Gohr{ 312da45d883SKate Arzamastseva if (!checkSecurityToken()) return false; 3138108113cSTom N Harris global $INPUT; 314da45d883SKate Arzamastseva 3158108113cSTom N Harris $id = $INPUT->get->str('qqfile'); 31624870174SAndreas Gohr [$ext, $mime] = mimetype($id); 3172d6cc64fSKate Arzamastseva $input = fopen("php://input", "r"); 3182d6cc64fSKate Arzamastseva if (!($tmp = io_mktmpdir())) return false; 31962231793SKate Arzamastseva $path = $tmp . '/' . md5($id); 3202d6cc64fSKate Arzamastseva $target = fopen($path, "w"); 321063fb5b5SAndreas Gohr $realSize = stream_copy_to_stream($input, $target); 3222d6cc64fSKate Arzamastseva fclose($target); 323063fb5b5SAndreas Gohr fclose($input); 3242b9be456SAndreas Gohr if ($INPUT->server->has('CONTENT_LENGTH') && ($realSize != $INPUT->server->int('CONTENT_LENGTH'))) { 325063fb5b5SAndreas Gohr unlink($path); 326063fb5b5SAndreas Gohr return false; 327063fb5b5SAndreas Gohr } 328063fb5b5SAndreas Gohr 3292d6cc64fSKate Arzamastseva $res = media_save( 33024870174SAndreas Gohr ['name' => $path, 'mime' => $mime, 'ext' => $ext], 3312d6cc64fSKate Arzamastseva $ns . ':' . $id, 33279a2d784SGerrit Uitslag ($INPUT->get->str('ow') == 'true'), 3332d6cc64fSKate Arzamastseva $auth, 3342d6cc64fSKate Arzamastseva 'copy' 3352d6cc64fSKate Arzamastseva ); 3362d6cc64fSKate Arzamastseva unlink($path); 337900a9e9eSGerrit Uitslag if ($tmp) io_rmdir($tmp, true); 3382d6cc64fSKate Arzamastseva if (is_array($res)) { 3392d6cc64fSKate Arzamastseva msg($res[0], $res[1]); 3402d6cc64fSKate Arzamastseva return false; 3412d6cc64fSKate Arzamastseva } 3422d6cc64fSKate Arzamastseva return $res; 3432d6cc64fSKate Arzamastseva} 3442d6cc64fSKate Arzamastseva 3452d6cc64fSKate Arzamastseva/** 3463df72098SAndreas Gohr * Handles media file uploads 3473df72098SAndreas Gohr * 3483df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 34911d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 35042ea7f44SGerrit Uitslag * 351ebc28e69SAndreas Gohr * @param string $ns target namespace 352ebc28e69SAndreas Gohr * @param int $auth current auth check result 353ebc28e69SAndreas Gohr * @param bool|array $file $_FILES member, $_FILES['upload'] if false 35442ea7f44SGerrit Uitslag * @return false|string false on error, id of the new file on success 3553df72098SAndreas Gohr */ 356d868eb89SAndreas Gohrfunction media_upload($ns, $auth, $file = false) 357d868eb89SAndreas Gohr{ 358f2ea8432SAndreas Gohr if (!checkSecurityToken()) return false; 3593df72098SAndreas Gohr global $lang; 3608108113cSTom N Harris global $INPUT; 3613df72098SAndreas Gohr 36244409c3dSAndreas Gohr // get file and id 3638108113cSTom N Harris $id = $INPUT->post->str('mediaid'); 3642d6cc64fSKate Arzamastseva if (!$file) $file = $_FILES['upload']; 3653df72098SAndreas Gohr if (empty($id)) $id = $file['name']; 36644409c3dSAndreas Gohr 36799766eefSAndreas Gohr // check for errors (messages are done in lib/exe/mediamanager.php) 36899766eefSAndreas Gohr if ($file['error']) return false; 3699676dc23SAndreas Gohr 37044409c3dSAndreas Gohr // check extensions 37124870174SAndreas Gohr [$fext, $fmime] = mimetype($file['name']); 37224870174SAndreas Gohr [$iext, $imime] = mimetype($id); 37344409c3dSAndreas Gohr if ($fext && !$iext) { 3748cb1eb01SAndreas Gohr // no extension specified in id - read original one 37544409c3dSAndreas Gohr $id .= '.' . $fext; 3768cb1eb01SAndreas Gohr $imime = $fmime; 37744409c3dSAndreas Gohr } elseif ($fext && $fext != $iext) { 37844409c3dSAndreas Gohr // extension was changed, print warning 37944409c3dSAndreas Gohr msg(sprintf($lang['mediaextchange'], $fext, $iext)); 38044409c3dSAndreas Gohr } 38144409c3dSAndreas Gohr 38224870174SAndreas Gohr $res = media_save( 38324870174SAndreas Gohr [ 38424870174SAndreas Gohr 'name' => $file['tmp_name'], 385ffb291f2SAdrian Lang 'mime' => $imime, 38624870174SAndreas Gohr 'ext' => $iext 38724870174SAndreas Gohr ], 38824870174SAndreas Gohr $ns . ':' . $id, 38924870174SAndreas Gohr $INPUT->post->bool('ow'), 39024870174SAndreas Gohr $auth, 39124870174SAndreas Gohr 'copy_uploaded_file' 39224870174SAndreas Gohr ); 393ffb291f2SAdrian Lang if (is_array($res)) { 394ffb291f2SAdrian Lang msg($res[0], $res[1]); 395ffb291f2SAdrian Lang return false; 396ffb291f2SAdrian Lang } 397ffb291f2SAdrian Lang return $res; 398ffb291f2SAdrian Lang} 399ffb291f2SAdrian Lang 400ffb291f2SAdrian Lang/** 40171f17ac4SAndreas Gohr * An alternative to move_uploaded_file that copies 40271f17ac4SAndreas Gohr * 40371f17ac4SAndreas Gohr * Using copy, makes sure any setgid bits on the media directory are honored 40471f17ac4SAndreas Gohr * 40571f17ac4SAndreas Gohr * @see move_uploaded_file() 40642ea7f44SGerrit Uitslag * 40771f17ac4SAndreas Gohr * @param string $from 40871f17ac4SAndreas Gohr * @param string $to 40971f17ac4SAndreas Gohr * @return bool 41071f17ac4SAndreas Gohr */ 411d868eb89SAndreas Gohrfunction copy_uploaded_file($from, $to) 412d868eb89SAndreas Gohr{ 41371f17ac4SAndreas Gohr if (!is_uploaded_file($from)) return false; 41471f17ac4SAndreas Gohr $ok = copy($from, $to); 41571f17ac4SAndreas Gohr @unlink($from); 41671f17ac4SAndreas Gohr return $ok; 41771f17ac4SAndreas Gohr} 41871f17ac4SAndreas Gohr 41971f17ac4SAndreas Gohr/** 420ffb291f2SAdrian Lang * This generates an action event and delegates to _media_upload_action(). 421ffb291f2SAdrian Lang * Action plugins are allowed to pre/postprocess the uploaded file. 422ffb291f2SAdrian Lang * (The triggered event is preventable.) 423ffb291f2SAdrian Lang * 424ffb291f2SAdrian Lang * Event data: 425ffb291f2SAdrian Lang * $data[0] fn_tmp: the temporary file name (read from $_FILES) 426ffb291f2SAdrian Lang * $data[1] fn: the file name of the uploaded file 427ffb291f2SAdrian Lang * $data[2] id: the future directory id of the uploaded file 428ffb291f2SAdrian Lang * $data[3] imime: the mimetype of the uploaded file 429ffb291f2SAdrian Lang * $data[4] overwrite: if an existing file is going to be overwritten 43052a281e8SGerrit Uitslag * $data[5] move: name of function that performs move/copy/.. 431ffb291f2SAdrian Lang * 432ffb291f2SAdrian Lang * @triggers MEDIA_UPLOAD_FINISH 43342ea7f44SGerrit Uitslag * 434e0c26282SGerrit Uitslag * @param array $file 43552a281e8SGerrit Uitslag * @param string $id media id 43642ea7f44SGerrit Uitslag * @param bool $ow overwrite? 437e0c26282SGerrit Uitslag * @param int $auth permission level 43852a281e8SGerrit Uitslag * @param string $move name of functions that performs move/copy/.. 43942ea7f44SGerrit Uitslag * @return false|array|string 440e0c26282SGerrit Uitslag */ 441d868eb89SAndreas Gohrfunction media_save($file, $id, $ow, $auth, $move) 442d868eb89SAndreas Gohr{ 443ffb291f2SAdrian Lang if ($auth < AUTH_UPLOAD) { 44424870174SAndreas Gohr return ["You don't have permissions to upload files.", -1]; 445ffb291f2SAdrian Lang } 446ffb291f2SAdrian Lang 447ffb291f2SAdrian Lang if (!isset($file['mime']) || !isset($file['ext'])) { 44824870174SAndreas Gohr [$ext, $mime] = mimetype($id); 449ffb291f2SAdrian Lang if (!isset($file['mime'])) { 450ffb291f2SAdrian Lang $file['mime'] = $mime; 451ffb291f2SAdrian Lang } 452ffb291f2SAdrian Lang if (!isset($file['ext'])) { 453ffb291f2SAdrian Lang $file['ext'] = $ext; 454ffb291f2SAdrian Lang } 455ffb291f2SAdrian Lang } 456ffb291f2SAdrian Lang 45792cac9a9SKate Arzamastseva global $lang, $conf; 458ffb291f2SAdrian Lang 4593df72098SAndreas Gohr // get filename 4603543c6deSAndreas Gohr $id = cleanID($id); 4613df72098SAndreas Gohr $fn = mediaFN($id); 4623df72098SAndreas Gohr 4633df72098SAndreas Gohr // get filetype regexp 4643df72098SAndreas Gohr $types = array_keys(getMimeTypes()); 465bad6fc0dSAndreas Gohr $types = array_map( 46624870174SAndreas Gohr static fn($q) => preg_quote($q, "/"), 467bad6fc0dSAndreas Gohr $types 468bad6fc0dSAndreas Gohr ); 46924870174SAndreas Gohr $regex = implode('|', $types); 4703df72098SAndreas Gohr 4713df72098SAndreas Gohr // because a temp file was created already 472ffb291f2SAdrian Lang if (!preg_match('/\.(' . $regex . ')$/i', $fn)) { 47324870174SAndreas Gohr return [$lang['uploadwrong'], -1]; 474ffb291f2SAdrian Lang } 475ffb291f2SAdrian Lang 4763df72098SAndreas Gohr //check for overwrite 47779e79377SAndreas Gohr $overwrite = file_exists($fn); 478e5d185e1SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 479e5d185e1SKate Arzamastseva if ($overwrite && (!$ow || $auth < $auth_ow)) { 48024870174SAndreas Gohr return [$lang['uploadexist'], 0]; 4813df72098SAndreas Gohr } 4828cb1eb01SAndreas Gohr // check for valid content 483ffb291f2SAdrian Lang $ok = media_contentcheck($file['name'], $file['mime']); 4848cb1eb01SAndreas Gohr if ($ok == -1) { 48524870174SAndreas Gohr return [sprintf($lang['uploadbadcontent'], '.' . $file['ext']), -1]; 4868cb1eb01SAndreas Gohr } elseif ($ok == -2) { 48724870174SAndreas Gohr return [$lang['uploadspam'], -1]; 48826ceae18SAndreas Gohr } elseif ($ok == -3) { 48924870174SAndreas Gohr return [$lang['uploadxss'], -1]; 4908cb1eb01SAndreas Gohr } 4918cb1eb01SAndreas Gohr 49211d9dfa5SMichael Klier // prepare event data 49324870174SAndreas Gohr $data = []; 494ffb291f2SAdrian Lang $data[0] = $file['name']; 49511d9dfa5SMichael Klier $data[1] = $fn; 49611d9dfa5SMichael Klier $data[2] = $id; 497ffb291f2SAdrian Lang $data[3] = $file['mime']; 49899c8d7f2Smichael $data[4] = $overwrite; 499ffb291f2SAdrian Lang $data[5] = $move; 50011d9dfa5SMichael Klier 50111d9dfa5SMichael Klier // trigger event 502cbb44eabSAndreas Gohr return Event::createAndTrigger('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); 50311d9dfa5SMichael Klier} 50411d9dfa5SMichael Klier 50511d9dfa5SMichael Klier/** 50642ea7f44SGerrit Uitslag * Callback adapter for media_upload_finish() triggered by MEDIA_UPLOAD_FINISH 50742ea7f44SGerrit Uitslag * 50811d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 50942ea7f44SGerrit Uitslag * 51042ea7f44SGerrit Uitslag * @param array $data event data 51142ea7f44SGerrit Uitslag * @return false|array|string 51211d9dfa5SMichael Klier */ 513d868eb89SAndreas Gohrfunction _media_upload_action($data) 514d868eb89SAndreas Gohr{ 51511d9dfa5SMichael Klier // fixme do further sanity tests of given data? 516ffb291f2SAdrian Lang if (is_array($data) && count($data) === 6) { 517ffb291f2SAdrian Lang return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 51811d9dfa5SMichael Klier } else { 51911d9dfa5SMichael Klier return false; //callback error 52011d9dfa5SMichael Klier } 52111d9dfa5SMichael Klier} 52211d9dfa5SMichael Klier 52311d9dfa5SMichael Klier/** 52411d9dfa5SMichael Klier * Saves an uploaded media file 52511d9dfa5SMichael Klier * 52611d9dfa5SMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 52711d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 528cbe26ad6SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 52942ea7f44SGerrit Uitslag * 53042ea7f44SGerrit Uitslag * @param string $fn_tmp 53142ea7f44SGerrit Uitslag * @param string $fn 53242ea7f44SGerrit Uitslag * @param string $id media id 53342ea7f44SGerrit Uitslag * @param string $imime mime type 53442ea7f44SGerrit Uitslag * @param bool $overwrite overwrite existing? 53542ea7f44SGerrit Uitslag * @param string $move function name 53642ea7f44SGerrit Uitslag * @return array|string 53711d9dfa5SMichael Klier */ 538d868eb89SAndreas Gohrfunction media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') 539d868eb89SAndreas Gohr{ 54011d9dfa5SMichael Klier global $conf; 54111d9dfa5SMichael Klier global $lang; 5429c1bd4bcSKate Arzamastseva global $REV; 54311d9dfa5SMichael Klier 544e4f389efSKate Arzamastseva $old = @filemtime($fn); 54579e79377SAndreas Gohr if (!file_exists(mediaFN($id, $old)) && file_exists($fn)) { 546e4f389efSKate Arzamastseva // add old revision to the attic if missing 547cbe26ad6SKate Arzamastseva media_saveOldRevision($id); 548e4f389efSKate Arzamastseva } 549e4f389efSKate Arzamastseva 5503df72098SAndreas Gohr // prepare directory 551cc7d0c94SBen Coburn io_createNamespace($id, 'media'); 55211d9dfa5SMichael Klier 553ac3ed4afSGerrit Uitslag $filesize_old = file_exists($fn) ? filesize($fn) : 0; 554ac3ed4afSGerrit Uitslag 555ffb291f2SAdrian Lang if ($move($fn_tmp, $fn)) { 55623846a98SKate Arzamastseva @clearstatcache(true, $fn); 557dad6764eSKate Arzamastseva $new = @filemtime($fn); 55874400ea5SBen Coburn // Set the correct permission here. 55974400ea5SBen Coburn // Always chmod media because they may be saved with different permissions than expected from the php umask. 56074400ea5SBen Coburn // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 56174400ea5SBen Coburn chmod($fn, $conf['fmode']); 5623df72098SAndreas Gohr msg($lang['uploadsucc'], 1); 56383734cddSPhy media_notify($id, $fn, $imime, $old, $new); 56499c8d7f2Smichael // add a log entry to the media changelog 565ac3ed4afSGerrit Uitslag $filesize_new = filesize($fn); 566ac3ed4afSGerrit Uitslag $sizechange = $filesize_new - $filesize_old; 5679c1bd4bcSKate Arzamastseva if ($REV) { 56864159a61SAndreas Gohr addMediaLogEntry( 56964159a61SAndreas Gohr $new, 57064159a61SAndreas Gohr $id, 57164159a61SAndreas Gohr DOKU_CHANGE_TYPE_REVERT, 57264159a61SAndreas Gohr sprintf($lang['restored'], dformat($REV)), 57364159a61SAndreas Gohr $REV, 57464159a61SAndreas Gohr null, 57564159a61SAndreas Gohr $sizechange 57664159a61SAndreas Gohr ); 5779c1bd4bcSKate Arzamastseva } elseif ($overwrite) { 578ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); 57999c8d7f2Smichael } else { 580ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); 58199c8d7f2Smichael } 5823df72098SAndreas Gohr return $id; 5833df72098SAndreas Gohr } else { 58424870174SAndreas Gohr return [$lang['uploadfail'], -1]; 5853df72098SAndreas Gohr } 5863df72098SAndreas Gohr} 5873df72098SAndreas Gohr 5888cb1eb01SAndreas Gohr/** 589cbe26ad6SKate Arzamastseva * Moves the current version of media file to the media_attic 590cbe26ad6SKate Arzamastseva * directory 591cbe26ad6SKate Arzamastseva * 592cbe26ad6SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 59342ea7f44SGerrit Uitslag * 594cbe26ad6SKate Arzamastseva * @param string $id 595cbe26ad6SKate Arzamastseva * @return int - revision date 596e4f389efSKate Arzamastseva */ 597d868eb89SAndreas Gohrfunction media_saveOldRevision($id) 598d868eb89SAndreas Gohr{ 599dbf57c96SKate Arzamastseva global $conf, $lang; 600dbf57c96SKate Arzamastseva 601e4f389efSKate Arzamastseva $oldf = mediaFN($id); 60279e79377SAndreas Gohr if (!file_exists($oldf)) return ''; 603e4f389efSKate Arzamastseva $date = filemtime($oldf); 604e5d185e1SKate Arzamastseva if (!$conf['mediarevisions']) return $date; 605e5d185e1SKate Arzamastseva 606047bad06SGerrit Uitslag $medialog = new MediaChangeLog($id); 607047bad06SGerrit Uitslag if (!$medialog->getRevisionInfo($date)) { 608dbf57c96SKate Arzamastseva // there was an external edit, 609dbf57c96SKate Arzamastseva // there is no log entry for current version of file 610ac3ed4afSGerrit Uitslag $sizechange = filesize($oldf); 61179e79377SAndreas Gohr if (!file_exists(mediaMetaFN($id, '.changes'))) { 612ac3ed4afSGerrit Uitslag addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); 613dbf57c96SKate Arzamastseva } else { 614ac3ed4afSGerrit Uitslag $oldRev = $medialog->getRevisions(-1, 1); // from changelog 615ac3ed4afSGerrit Uitslag $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]); 616ac3ed4afSGerrit Uitslag $filesize_old = filesize(mediaFN($id, $oldRev)); 61724870174SAndreas Gohr $sizechange -= $filesize_old; 618ac3ed4afSGerrit Uitslag 619ac3ed4afSGerrit Uitslag addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); 620dbf57c96SKate Arzamastseva } 621dbf57c96SKate Arzamastseva } 622dbf57c96SKate Arzamastseva 623e4f389efSKate Arzamastseva $newf = mediaFN($id, $date); 624e4f389efSKate Arzamastseva io_makeFileDir($newf); 625cbe26ad6SKate Arzamastseva if (copy($oldf, $newf)) { 626e4f389efSKate Arzamastseva // Set the correct permission here. 627e4f389efSKate Arzamastseva // Always chmod media because they may be saved with different permissions than expected from the php umask. 628e4f389efSKate Arzamastseva // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 629e4f389efSKate Arzamastseva chmod($newf, $conf['fmode']); 630e4f389efSKate Arzamastseva } 631e4f389efSKate Arzamastseva return $date; 632e4f389efSKate Arzamastseva} 633e4f389efSKate Arzamastseva 634e4f389efSKate Arzamastseva/** 6358cb1eb01SAndreas Gohr * This function checks if the uploaded content is really what the 63626ceae18SAndreas Gohr * mimetype says it is. We also do spam checking for text types here. 6378cb1eb01SAndreas Gohr * 6388cb1eb01SAndreas Gohr * We need to do this stuff because we can not rely on the browser 6398cb1eb01SAndreas Gohr * to do this check correctly. Yes, IE is broken as usual. 6408cb1eb01SAndreas Gohr * 6418cb1eb01SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 64226ceae18SAndreas Gohr * @link http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting 6438cb1eb01SAndreas Gohr * @fixme check all 26 magic IE filetypes here? 64442ea7f44SGerrit Uitslag * 64542ea7f44SGerrit Uitslag * @param string $file path to file 64642ea7f44SGerrit Uitslag * @param string $mime mimetype 64742ea7f44SGerrit Uitslag * @return int 6488cb1eb01SAndreas Gohr */ 649d868eb89SAndreas Gohrfunction media_contentcheck($file, $mime) 650d868eb89SAndreas Gohr{ 65126ceae18SAndreas Gohr global $conf; 65226ceae18SAndreas Gohr if ($conf['iexssprotect']) { 65326ceae18SAndreas Gohr $fh = @fopen($file, 'rb'); 65426ceae18SAndreas Gohr if ($fh) { 65526ceae18SAndreas Gohr $bytes = fread($fh, 256); 65626ceae18SAndreas Gohr fclose($fh); 65726ceae18SAndreas Gohr if (preg_match('/<(script|a|img|html|body|iframe)[\s>]/i', $bytes)) { 65842ea7f44SGerrit Uitslag return -3; //XSS: possibly malicious content 65926ceae18SAndreas Gohr } 66026ceae18SAndreas Gohr } 66126ceae18SAndreas Gohr } 6626c16a3a9Sfiwswe if (str_starts_with($mime, 'image/')) { 6638cb1eb01SAndreas Gohr $info = @getimagesize($file); 6648cb1eb01SAndreas Gohr if ($mime == 'image/gif' && $info[2] != 1) { 66542ea7f44SGerrit Uitslag return -1; // uploaded content did not match the file extension 6668cb1eb01SAndreas Gohr } elseif ($mime == 'image/jpeg' && $info[2] != 2) { 6678cb1eb01SAndreas Gohr return -1; 6688cb1eb01SAndreas Gohr } elseif ($mime == 'image/png' && $info[2] != 3) { 6698cb1eb01SAndreas Gohr return -1; 6708cb1eb01SAndreas Gohr } 6718cb1eb01SAndreas Gohr # fixme maybe check other images types as well 6726c16a3a9Sfiwswe } elseif (str_starts_with($mime, 'text/')) { 6738cb1eb01SAndreas Gohr global $TEXT; 6748cb1eb01SAndreas Gohr $TEXT = io_readFile($file); 6758cb1eb01SAndreas Gohr if (checkwordblock()) { 67642ea7f44SGerrit Uitslag return -2; //blocked by the spam blacklist 6778cb1eb01SAndreas Gohr } 6788cb1eb01SAndreas Gohr } 6798cb1eb01SAndreas Gohr return 0; 6808cb1eb01SAndreas Gohr} 6813df72098SAndreas Gohr 6823df72098SAndreas Gohr/** 68375030359SAndreas Gohr * Send a notify mail on uploads 68475030359SAndreas Gohr * 68575030359SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 68642ea7f44SGerrit Uitslag * 68742ea7f44SGerrit Uitslag * @param string $id media id 68842ea7f44SGerrit Uitslag * @param string $file path to file 68942ea7f44SGerrit Uitslag * @param string $mime mime type 69042ea7f44SGerrit Uitslag * @param bool|int $old_rev revision timestamp or false 69175030359SAndreas Gohr */ 692d868eb89SAndreas Gohrfunction media_notify($id, $file, $mime, $old_rev = false, $current_rev = false) 693d868eb89SAndreas Gohr{ 69475030359SAndreas Gohr global $conf; 69579a2d784SGerrit Uitslag if (empty($conf['notify'])) return; //notify enabled? 69675030359SAndreas Gohr 697704a815fSMichael Große $subscription = new MediaSubscriptionSender(); 69879a2d784SGerrit Uitslag $subscription->sendMediaDiff($conf['notify'], 'uploadmail', $id, $old_rev, $current_rev); 69975030359SAndreas Gohr} 70075030359SAndreas Gohr 70175030359SAndreas Gohr/** 7023df72098SAndreas Gohr * List all files in a given Media namespace 70342ea7f44SGerrit Uitslag * 70421d806cdSGerrit Uitslag * @param string $ns namespace 70542ea7f44SGerrit Uitslag * @param null|int $auth permission level 70642ea7f44SGerrit Uitslag * @param string $jump id 70742ea7f44SGerrit Uitslag * @param bool $fullscreenview 7088702de7fSGerrit Uitslag * @param bool|string $sort sorting order, false skips sorting 7093df72098SAndreas Gohr */ 710d868eb89SAndreas Gohrfunction media_filelist($ns, $auth = null, $jump = '', $fullscreenview = false, $sort = false) 711d868eb89SAndreas Gohr{ 7123df72098SAndreas Gohr global $conf; 7133df72098SAndreas Gohr global $lang; 7143df72098SAndreas Gohr $ns = cleanID($ns); 7153df72098SAndreas Gohr 7163df72098SAndreas Gohr // check auth our self if not given (needed for ajax calls) 7173df72098SAndreas Gohr if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 7183df72098SAndreas Gohr 719d9162c6cSKate Arzamastseva if (!$fullscreenview) echo '<h1 id="media__ns">:' . hsc($ns) . '</h1>' . NL; 7203df72098SAndreas Gohr 7213df72098SAndreas Gohr if ($auth < AUTH_READ) { 7223df72098SAndreas Gohr // FIXME: print permission warning here instead? 7233df72098SAndreas Gohr echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; 72456fe6664SAndreas Gohr } else { 72589274c0dSChristopher Smith if (!$fullscreenview) { 72689274c0dSChristopher Smith media_uploadform($ns, $auth); 72789274c0dSChristopher Smith media_searchform($ns); 72889274c0dSChristopher Smith } 7293df72098SAndreas Gohr 7303df72098SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $ns)); 73124870174SAndreas Gohr $data = []; 732dccd6b2bSAndreas Gohr search( 733dccd6b2bSAndreas Gohr $data, 734dccd6b2bSAndreas Gohr $conf['mediadir'], 735dccd6b2bSAndreas Gohr 'search_mediafiles', 736dccd6b2bSAndreas Gohr ['showmsg' => true, 'depth' => 1], 737dccd6b2bSAndreas Gohr $dir, 738dccd6b2bSAndreas Gohr 1, 739dccd6b2bSAndreas Gohr $sort 740dccd6b2bSAndreas Gohr ); 7413df72098SAndreas Gohr 742093fe67eSAndreas Gohr if ($data === []) { 7433df72098SAndreas Gohr echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; 7445b9353faSKate Arzamastseva } else { 7455b9353faSKate Arzamastseva if ($fullscreenview) { 746554a8c9fSAdrian Lang echo '<ul class="' . _media_get_list_type() . '">'; 7475b9353faSKate Arzamastseva } 7485b9353faSKate Arzamastseva foreach ($data as $item) { 7495b9353faSKate Arzamastseva if (!$fullscreenview) { 7504f33babfSAndreas Gohr //FIXME old call: media_printfile($item,$auth,$jump); 75179a2d784SGerrit Uitslag $display = new DisplayRow($item); 7529453716dSAndreas Gohr $display->scrollIntoView($jump == $item->getID()); 7534f33babfSAndreas Gohr $display->show(); 7545b9353faSKate Arzamastseva } else { 7554f33babfSAndreas Gohr //FIXME old call: media_printfile_thumbs($item,$auth,$jump); 7564f33babfSAndreas Gohr echo '<li>'; 75779a2d784SGerrit Uitslag $display = new DisplayTile($item); 7589453716dSAndreas Gohr $display->scrollIntoView($jump == $item->getID()); 7594f33babfSAndreas Gohr $display->show(); 7604f33babfSAndreas Gohr echo '</li>'; 7615b9353faSKate Arzamastseva } 7625b9353faSKate Arzamastseva } 76394add303SAnika Henke if ($fullscreenview) echo '</ul>' . NL; 7643df72098SAndreas Gohr } 76556fe6664SAndreas Gohr } 766d9162c6cSKate Arzamastseva} 767d9162c6cSKate Arzamastseva 768d9162c6cSKate Arzamastseva/** 769d9162c6cSKate Arzamastseva * Prints tabs for files list actions 770d9162c6cSKate Arzamastseva * 771d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 77295b451bcSAdrian Lang * @author Adrian Lang <mail@adrianlang.de> 77395b451bcSAdrian Lang * 774035e07f1SKate Arzamastseva * @param string $selected_tab - opened tab 775d9162c6cSKate Arzamastseva */ 77695b451bcSAdrian Lang 777d868eb89SAndreas Gohrfunction media_tabs_files($selected_tab = '') 778d868eb89SAndreas Gohr{ 779d9162c6cSKate Arzamastseva global $lang; 78024870174SAndreas Gohr $tabs = []; 7817d34963bSAndreas Gohr foreach ( 7827d34963bSAndreas Gohr [ 78324870174SAndreas Gohr 'files' => 'mediaselect', 78495b451bcSAdrian Lang 'upload' => 'media_uploadtab', 78524870174SAndreas Gohr 'search' => 'media_searchtab' 7867d34963bSAndreas Gohr ] as $tab => $caption 7877d34963bSAndreas Gohr ) { 78824870174SAndreas Gohr $tabs[$tab] = [ 78924870174SAndreas Gohr 'href' => media_managerURL(['tab_files' => $tab], '&'), 79024870174SAndreas Gohr 'caption' => $lang[$caption] 79124870174SAndreas Gohr ]; 79295b451bcSAdrian Lang } 793d9162c6cSKate Arzamastseva 79495b451bcSAdrian Lang html_tabs($tabs, $selected_tab); 795d9162c6cSKate Arzamastseva} 796d9162c6cSKate Arzamastseva 797d9162c6cSKate Arzamastseva/** 798d9162c6cSKate Arzamastseva * Prints tabs for files details actions 799d9162c6cSKate Arzamastseva * 800d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 801ebc28e69SAndreas Gohr * @param string $image filename of the current image 802ebc28e69SAndreas Gohr * @param string $selected_tab opened tab 803d9162c6cSKate Arzamastseva */ 804d868eb89SAndreas Gohrfunction media_tabs_details($image, $selected_tab = '') 805d868eb89SAndreas Gohr{ 806e5d185e1SKate Arzamastseva global $lang, $conf; 807d9162c6cSKate Arzamastseva 80824870174SAndreas Gohr $tabs = []; 80924870174SAndreas Gohr $tabs['view'] = [ 81024870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'view'], '&'), 81124870174SAndreas Gohr 'caption' => $lang['media_viewtab'] 81224870174SAndreas Gohr ]; 813d9162c6cSKate Arzamastseva 81424870174SAndreas Gohr [, $mime] = mimetype($image); 81579e79377SAndreas Gohr if ($mime == 'image/jpeg' && file_exists(mediaFN($image))) { 81624870174SAndreas Gohr $tabs['edit'] = [ 81724870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'edit'], '&'), 81824870174SAndreas Gohr 'caption' => $lang['media_edittab'] 81924870174SAndreas Gohr ]; 820dd9ba38eSKate Arzamastseva } 821e5d185e1SKate Arzamastseva if ($conf['mediarevisions']) { 82224870174SAndreas Gohr $tabs['history'] = [ 82324870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'history'], '&'), 82424870174SAndreas Gohr 'caption' => $lang['media_historytab'] 82524870174SAndreas Gohr ]; 826e5d185e1SKate Arzamastseva } 827d9162c6cSKate Arzamastseva 82895b451bcSAdrian Lang html_tabs($tabs, $selected_tab); 829d9162c6cSKate Arzamastseva} 830d9162c6cSKate Arzamastseva 831d9162c6cSKate Arzamastseva/** 832d9162c6cSKate Arzamastseva * Prints options for the tab that displays a list of all files 833d9162c6cSKate Arzamastseva * 834d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 835d9162c6cSKate Arzamastseva */ 836d868eb89SAndreas Gohrfunction media_tab_files_options() 837d868eb89SAndreas Gohr{ 8388108113cSTom N Harris global $lang; 8398108113cSTom N Harris global $INPUT; 840b7e5821dSAndreas Gohr global $ID; 841b960c74fSSatoshi Sahara 842b960c74fSSatoshi Sahara $form = new Form([ 843b960c74fSSatoshi Sahara 'method' => 'get', 844b960c74fSSatoshi Sahara 'action' => wl($ID), 845b960c74fSSatoshi Sahara 'class' => 'options' 846b960c74fSSatoshi Sahara ]); 847b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 848b960c74fSSatoshi Sahara $form->setHiddenField('sectok', null); 849b960c74fSSatoshi Sahara $media_manager_params = media_managerURL([], '', false, true); 85038b2bf35SAnika Henke foreach ($media_manager_params as $pKey => $pVal) { 851b960c74fSSatoshi Sahara $form->setHiddenField($pKey, $pVal); 85238b2bf35SAnika Henke } 8538108113cSTom N Harris if ($INPUT->has('q')) { 854b960c74fSSatoshi Sahara $form->setHiddenField('q', $INPUT->str('q')); 855554a8c9fSAdrian Lang } 856b960c74fSSatoshi Sahara $form->addHTML('<ul>' . NL); 8577d34963bSAndreas Gohr foreach ( 8587d34963bSAndreas Gohr [ 85924870174SAndreas Gohr 'list' => ['listType', ['thumbs', 'rows']], 86024870174SAndreas Gohr 'sort' => ['sortBy', ['name', 'date']] 8617d34963bSAndreas Gohr ] as $group => $content 8627d34963bSAndreas Gohr ) { 863ec88e837SAndreas Gohr $checked = "_media_get_{$group}_type"; 864554a8c9fSAdrian Lang $checked = $checked(); 865d9162c6cSKate Arzamastseva 866b960c74fSSatoshi Sahara $form->addHTML('<li class="' . $content[0] . '">'); 86795b451bcSAdrian Lang foreach ($content[1] as $option) { 86824870174SAndreas Gohr $attrs = []; 869554a8c9fSAdrian Lang if ($checked == $option) { 87095b451bcSAdrian Lang $attrs['checked'] = 'checked'; 87195b451bcSAdrian Lang } 872b960c74fSSatoshi Sahara $radio = $form->addRadioButton( 873b960c74fSSatoshi Sahara $group . '_dwmedia', 874b960c74fSSatoshi Sahara $lang['media_' . $group . '_' . $option] 875b960c74fSSatoshi Sahara )->val($option)->id($content[0] . '__' . $option)->addClass($option); 876b960c74fSSatoshi Sahara $radio->attrs($attrs); 87795b451bcSAdrian Lang } 878b960c74fSSatoshi Sahara $form->addHTML('</li>' . NL); 87995b451bcSAdrian Lang } 880b960c74fSSatoshi Sahara $form->addHTML('<li>'); 881b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_apply'])->attr('type', 'submit'); 882b960c74fSSatoshi Sahara $form->addHTML('</li>' . NL); 883b960c74fSSatoshi Sahara $form->addHTML('</ul>' . NL); 884b960c74fSSatoshi Sahara $form->addTagClose('div'); 88526dfc232SAndreas Gohr echo $form->toHTML(); 886d9162c6cSKate Arzamastseva} 887d9162c6cSKate Arzamastseva 888d9162c6cSKate Arzamastseva/** 88987deddfaSKate Arzamastseva * Returns type of sorting for the list of files in media manager 89087deddfaSKate Arzamastseva * 89187deddfaSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 89242ea7f44SGerrit Uitslag * 89387deddfaSKate Arzamastseva * @return string - sort type 89487deddfaSKate Arzamastseva */ 895d868eb89SAndreas Gohrfunction _media_get_sort_type() 896d868eb89SAndreas Gohr{ 89724870174SAndreas Gohr return _media_get_display_param('sort', ['default' => 'name', 'date']); 89887deddfaSKate Arzamastseva} 899554a8c9fSAdrian Lang 9006ffaeda9SGerrit Uitslag/** 9016ffaeda9SGerrit Uitslag * Returns type of listing for the list of files in media manager 9026ffaeda9SGerrit Uitslag * 9036ffaeda9SGerrit Uitslag * @author Kate Arzamastseva <pshns@ukr.net> 90442ea7f44SGerrit Uitslag * 9056ffaeda9SGerrit Uitslag * @return string - list type 9066ffaeda9SGerrit Uitslag */ 907d868eb89SAndreas Gohrfunction _media_get_list_type() 908d868eb89SAndreas Gohr{ 90924870174SAndreas Gohr return _media_get_display_param('list', ['default' => 'thumbs', 'rows']); 91087deddfaSKate Arzamastseva} 911554a8c9fSAdrian Lang 9126ffaeda9SGerrit Uitslag/** 9136ffaeda9SGerrit Uitslag * Get display parameters 9146ffaeda9SGerrit Uitslag * 9156ffaeda9SGerrit Uitslag * @param string $param name of parameter 9166ffaeda9SGerrit Uitslag * @param array $values allowed values, where default value has index key 'default' 9176ffaeda9SGerrit Uitslag * @return string the parameter value 9186ffaeda9SGerrit Uitslag */ 919d868eb89SAndreas Gohrfunction _media_get_display_param($param, $values) 920d868eb89SAndreas Gohr{ 9218108113cSTom N Harris global $INPUT; 9228108113cSTom N Harris if (in_array($INPUT->str($param), $values)) { 923554a8c9fSAdrian Lang // FIXME: Set cookie 9248108113cSTom N Harris return $INPUT->str($param); 925554a8c9fSAdrian Lang } else { 9263629bc8cSAdrian Lang $val = get_doku_pref($param, $values['default']); 9273629bc8cSAdrian Lang if (!in_array($val, $values)) { 9283629bc8cSAdrian Lang $val = $values['default']; 9293629bc8cSAdrian Lang } 9303629bc8cSAdrian Lang return $val; 931554a8c9fSAdrian Lang } 93287deddfaSKate Arzamastseva} 93387deddfaSKate Arzamastseva 93487deddfaSKate Arzamastseva/** 935d9162c6cSKate Arzamastseva * Prints tab that displays a list of all files 936d9162c6cSKate Arzamastseva * 937d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 93842ea7f44SGerrit Uitslag * 93942ea7f44SGerrit Uitslag * @param string $ns 94042ea7f44SGerrit Uitslag * @param null|int $auth permission level 94142ea7f44SGerrit Uitslag * @param string $jump item id 942d9162c6cSKate Arzamastseva */ 943d868eb89SAndreas Gohrfunction media_tab_files($ns, $auth = null, $jump = '') 944d868eb89SAndreas Gohr{ 945d9162c6cSKate Arzamastseva global $lang; 946d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 947d9162c6cSKate Arzamastseva 948d9162c6cSKate Arzamastseva if ($auth < AUTH_READ) { 94988a71175SKate Arzamastseva echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; 950d9162c6cSKate Arzamastseva } else { 95195b451bcSAdrian Lang media_filelist($ns, $auth, $jump, true, _media_get_sort_type()); 952d9162c6cSKate Arzamastseva } 953d9162c6cSKate Arzamastseva} 954d9162c6cSKate Arzamastseva 955d9162c6cSKate Arzamastseva/** 956d9162c6cSKate Arzamastseva * Prints tab that displays uploading form 957d9162c6cSKate Arzamastseva * 958d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 95942ea7f44SGerrit Uitslag * 96042ea7f44SGerrit Uitslag * @param string $ns 96142ea7f44SGerrit Uitslag * @param null|int $auth permission level 96242ea7f44SGerrit Uitslag * @param string $jump item id 963d9162c6cSKate Arzamastseva */ 964d868eb89SAndreas Gohrfunction media_tab_upload($ns, $auth = null, $jump = '') 965d868eb89SAndreas Gohr{ 966d9162c6cSKate Arzamastseva global $lang; 967d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 968d9162c6cSKate Arzamastseva 96994add303SAnika Henke echo '<div class="upload">' . NL; 97095b451bcSAdrian Lang if ($auth >= AUTH_UPLOAD) { 97195b451bcSAdrian Lang echo '<p>' . $lang['mediaupload'] . '</p>'; 97295b451bcSAdrian Lang } 973d9162c6cSKate Arzamastseva media_uploadform($ns, $auth, true); 97494add303SAnika Henke echo '</div>' . NL; 975d9162c6cSKate Arzamastseva} 976d9162c6cSKate Arzamastseva 977d9162c6cSKate Arzamastseva/** 978d9162c6cSKate Arzamastseva * Prints tab that displays search form 979d9162c6cSKate Arzamastseva * 980d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 98142ea7f44SGerrit Uitslag * 98242ea7f44SGerrit Uitslag * @param string $ns 98342ea7f44SGerrit Uitslag * @param null|int $auth permission level 984d9162c6cSKate Arzamastseva */ 985d868eb89SAndreas Gohrfunction media_tab_search($ns, $auth = null) 986d868eb89SAndreas Gohr{ 9878108113cSTom N Harris global $INPUT; 988d9162c6cSKate Arzamastseva 9898108113cSTom N Harris $do = $INPUT->str('mediado'); 9908108113cSTom N Harris $query = $INPUT->str('q'); 99194add303SAnika Henke echo '<div class="search">' . NL; 992d9162c6cSKate Arzamastseva 993d9162c6cSKate Arzamastseva media_searchform($ns, $query, true); 9942dba8df4SAdrian Lang if ($do == 'searchlist' || $query) { 99595b451bcSAdrian Lang media_searchlist($query, $ns, $auth, true, _media_get_sort_type()); 99695b451bcSAdrian Lang } 99794add303SAnika Henke echo '</div>' . NL; 998d9162c6cSKate Arzamastseva} 999d9162c6cSKate Arzamastseva 1000d9162c6cSKate Arzamastseva/** 1001d9162c6cSKate Arzamastseva * Prints tab that displays mediafile details 1002d9162c6cSKate Arzamastseva * 1003d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1004e0c26282SGerrit Uitslag * 1005e0c26282SGerrit Uitslag * @param string $image media id 1006e0c26282SGerrit Uitslag * @param string $ns 1007e0c26282SGerrit Uitslag * @param null|int $auth permission level 100842ea7f44SGerrit Uitslag * @param string|int $rev revision timestamp or empty string 1009d9162c6cSKate Arzamastseva */ 1010d868eb89SAndreas Gohrfunction media_tab_view($image, $ns, $auth = null, $rev = '') 1011d868eb89SAndreas Gohr{ 1012ebc28e69SAndreas Gohr global $lang; 1013d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 1014d9162c6cSKate Arzamastseva 1015e136d6ccSKate Arzamastseva if ($image && $auth >= AUTH_READ) { 1016dd9ba38eSKate Arzamastseva $meta = new JpegMeta(mediaFN($image, $rev)); 1017dd9ba38eSKate Arzamastseva media_preview($image, $auth, $rev, $meta); 1018e136d6ccSKate Arzamastseva media_preview_buttons($image, $auth, $rev); 1019dd9ba38eSKate Arzamastseva media_details($image, $auth, $rev, $meta); 1020e136d6ccSKate Arzamastseva } else { 102194add303SAnika Henke echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; 1022e136d6ccSKate Arzamastseva } 1023d9162c6cSKate Arzamastseva} 1024d9162c6cSKate Arzamastseva 1025d9162c6cSKate Arzamastseva/** 1026d9162c6cSKate Arzamastseva * Prints tab that displays form for editing mediafile metadata 1027d9162c6cSKate Arzamastseva * 1028d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1029e0c26282SGerrit Uitslag * 1030e0c26282SGerrit Uitslag * @param string $image media id 1031e0c26282SGerrit Uitslag * @param string $ns 1032e0c26282SGerrit Uitslag * @param null|int $auth permission level 1033d9162c6cSKate Arzamastseva */ 1034d868eb89SAndreas Gohrfunction media_tab_edit($image, $ns, $auth = null) 1035d868eb89SAndreas Gohr{ 1036d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 1037d9162c6cSKate Arzamastseva 10381eeeced2SKate Arzamastseva if ($image) { 103924870174SAndreas Gohr [, $mime] = mimetype($image); 104030fd72fbSKate Arzamastseva if ($mime == 'image/jpeg') media_metaform($image, $auth); 10411eeeced2SKate Arzamastseva } 1042d9162c6cSKate Arzamastseva} 1043d9162c6cSKate Arzamastseva 1044d9162c6cSKate Arzamastseva/** 1045d9162c6cSKate Arzamastseva * Prints tab that displays mediafile revisions 1046d9162c6cSKate Arzamastseva * 1047d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1048e0c26282SGerrit Uitslag * 1049e0c26282SGerrit Uitslag * @param string $image media id 1050e0c26282SGerrit Uitslag * @param string $ns 1051e0c26282SGerrit Uitslag * @param null|int $auth permission level 1052d9162c6cSKate Arzamastseva */ 1053d868eb89SAndreas Gohrfunction media_tab_history($image, $ns, $auth = null) 1054d868eb89SAndreas Gohr{ 1055d9162c6cSKate Arzamastseva global $lang; 10568108113cSTom N Harris global $INPUT; 10578108113cSTom N Harris 1058d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 10598108113cSTom N Harris $do = $INPUT->str('mediado'); 1060d9162c6cSKate Arzamastseva 10612e55802cSKate Arzamastseva if ($auth >= AUTH_READ && $image) { 10622e55802cSKate Arzamastseva if ($do == 'diff') { 106324870174SAndreas Gohr (new MediaDiff($image))->show(); //media_diff($image, $ns, $auth); 10642e55802cSKate Arzamastseva } else { 1065a46cc3dcSAndreas Gohr $first = $INPUT->int('first', -1); 106624870174SAndreas Gohr (new MediaRevisions($image))->show($first); 10672e55802cSKate Arzamastseva } 106888a71175SKate Arzamastseva } else { 106988a71175SKate Arzamastseva echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; 10702e55802cSKate Arzamastseva } 10713df72098SAndreas Gohr} 10723df72098SAndreas Gohr 10733df72098SAndreas Gohr/** 10741eeeced2SKate Arzamastseva * Prints mediafile details 10751eeeced2SKate Arzamastseva * 10766ffaeda9SGerrit Uitslag * @param string $image media id 1077e0c26282SGerrit Uitslag * @param int $auth permission level 107859bc3b48SGerrit Uitslag * @param int|string $rev revision timestamp or empty string 10796ffaeda9SGerrit Uitslag * @param JpegMeta|bool $meta 108042ea7f44SGerrit Uitslag * 10811eeeced2SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 10821eeeced2SKate Arzamastseva */ 1083d868eb89SAndreas Gohrfunction media_preview($image, $auth, $rev = '', $meta = false) 1084d868eb89SAndreas Gohr{ 1085e136d6ccSKate Arzamastseva 1086e136d6ccSKate Arzamastseva $size = media_image_preview_size($image, $rev, $meta); 1087e136d6ccSKate Arzamastseva 1088e136d6ccSKate Arzamastseva if ($size) { 108959f3611bSAnika Henke global $lang; 109094add303SAnika Henke echo '<div class="image">'; 109194add303SAnika Henke 109224870174SAndreas Gohr $more = []; 1093e136d6ccSKate Arzamastseva if ($rev) { 10945b9353faSKate Arzamastseva $more['rev'] = $rev; 1095e136d6ccSKate Arzamastseva } else { 1096e136d6ccSKate Arzamastseva $t = @filemtime(mediaFN($image)); 10975b9353faSKate Arzamastseva $more['t'] = $t; 109888a71175SKate Arzamastseva } 109923786fd7SKate Arzamastseva 11005b9353faSKate Arzamastseva $more['w'] = $size[0]; 11015b9353faSKate Arzamastseva $more['h'] = $size[1]; 1102e136d6ccSKate Arzamastseva $src = ml($image, $more); 110359f3611bSAnika Henke 110459f3611bSAnika Henke echo '<a href="' . $src . '" target="_blank" title="' . $lang['mediaview'] . '">'; 110595b451bcSAdrian Lang echo '<img src="' . $src . '" alt="" style="max-width: ' . $size[0] . 'px;" />'; 110659f3611bSAnika Henke echo '</a>'; 1107e136d6ccSKate Arzamastseva 1108871895a7SSatoshi Sahara echo '</div>'; 110994add303SAnika Henke } 1110e136d6ccSKate Arzamastseva} 1111e136d6ccSKate Arzamastseva 1112e136d6ccSKate Arzamastseva/** 1113e136d6ccSKate Arzamastseva * Prints mediafile action buttons 1114e136d6ccSKate Arzamastseva * 1115e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1116e0c26282SGerrit Uitslag * 1117e0c26282SGerrit Uitslag * @param string $image media id 1118e0c26282SGerrit Uitslag * @param int $auth permission level 1119871895a7SSatoshi Sahara * @param int|string $rev revision timestamp, or empty string 1120e136d6ccSKate Arzamastseva */ 1121d868eb89SAndreas Gohrfunction media_preview_buttons($image, $auth, $rev = '') 1122d868eb89SAndreas Gohr{ 1123e5d185e1SKate Arzamastseva global $lang, $conf; 1124e136d6ccSKate Arzamastseva 1125871895a7SSatoshi Sahara echo '<ul class="actions">'; 11261eeeced2SKate Arzamastseva 112779e79377SAndreas Gohr if ($auth >= AUTH_DELETE && !$rev && file_exists(mediaFN($image))) { 1128e136d6ccSKate Arzamastseva // delete button 1129b960c74fSSatoshi Sahara $form = new Form([ 1130b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_delete', 1131b960c74fSSatoshi Sahara 'action' => media_managerURL(['delete' => $image], '&'), 1132b960c74fSSatoshi Sahara ]); 1133b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1134b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_delete'])->attr('type', 'submit'); 1135b960c74fSSatoshi Sahara $form->addTagClose('div'); 113695b451bcSAdrian Lang echo '<li>'; 1137b960c74fSSatoshi Sahara echo $form->toHTML(); 1138871895a7SSatoshi Sahara echo '</li>'; 1139e5d185e1SKate Arzamastseva } 1140e5d185e1SKate Arzamastseva 1141e5d185e1SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 1142e5d185e1SKate Arzamastseva if ($auth >= $auth_ow && !$rev) { 1143e136d6ccSKate Arzamastseva // upload new version button 1144b960c74fSSatoshi Sahara $form = new Form([ 1145b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_update', 1146b960c74fSSatoshi Sahara 'action' => media_managerURL(['image' => $image, 'mediado' => 'update'], '&'), 1147b960c74fSSatoshi Sahara ]); 1148b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1149b960c74fSSatoshi Sahara $form->addButton('', $lang['media_update'])->attr('type', 'submit'); 1150b960c74fSSatoshi Sahara $form->addTagClose('div'); 115195b451bcSAdrian Lang echo '<li>'; 1152b960c74fSSatoshi Sahara echo $form->toHTML(); 1153871895a7SSatoshi Sahara echo '</li>'; 115470c3cc9aSKate Arzamastseva } 1155e136d6ccSKate Arzamastseva 115679e79377SAndreas Gohr if ($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && file_exists(mediaFN($image, $rev))) { 1157e136d6ccSKate Arzamastseva // restore button 1158b960c74fSSatoshi Sahara $form = new Form([ 1159b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_restore', 1160b960c74fSSatoshi Sahara 'action' => media_managerURL(['image' => $image], '&'), 1161b960c74fSSatoshi Sahara ]); 1162b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1163b960c74fSSatoshi Sahara $form->setHiddenField('mediado', 'restore'); 1164b960c74fSSatoshi Sahara $form->setHiddenField('rev', $rev); 1165b960c74fSSatoshi Sahara $form->addButton('', $lang['media_restore'])->attr('type', 'submit'); 1166b960c74fSSatoshi Sahara $form->addTagClose('div'); 116795b451bcSAdrian Lang echo '<li>'; 1168b960c74fSSatoshi Sahara echo $form->toHTML(); 1169871895a7SSatoshi Sahara echo '</li>'; 11709c1bd4bcSKate Arzamastseva } 1171e136d6ccSKate Arzamastseva 1172871895a7SSatoshi Sahara echo '</ul>'; 11732e55802cSKate Arzamastseva} 11742e55802cSKate Arzamastseva 11752e55802cSKate Arzamastseva/** 1176fa8e5c77SKate Arzamastseva * Returns image width and height for mediamanager preview panel 1177fa8e5c77SKate Arzamastseva * 1178fa8e5c77SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1179fa8e5c77SKate Arzamastseva * @param string $image 1180e0c26282SGerrit Uitslag * @param int|string $rev 118159bc3b48SGerrit Uitslag * @param JpegMeta|bool $meta 1182ebc28e69SAndreas Gohr * @param int $size 1183871895a7SSatoshi Sahara * @return array 1184fa8e5c77SKate Arzamastseva */ 1185d868eb89SAndreas Gohrfunction media_image_preview_size($image, $rev, $meta = false, $size = 500) 1186d868eb89SAndreas Gohr{ 11877d34963bSAndreas Gohr if ( 11880296c9b0SMatt Perry !preg_match("/\.(jpe?g|gif|png|webp)$/", $image) 1189871895a7SSatoshi Sahara || !file_exists($filename = mediaFN($image, $rev)) 119024870174SAndreas Gohr ) return []; 1191fa8e5c77SKate Arzamastseva 1192871895a7SSatoshi Sahara $info = getimagesize($filename); 119324870174SAndreas Gohr $w = $info[0]; 119424870174SAndreas Gohr $h = $info[1]; 1195fa8e5c77SKate Arzamastseva 1196fa8e5c77SKate Arzamastseva if ($meta && ($w > $size || $h > $size)) { 1197fa8e5c77SKate Arzamastseva $ratio = $meta->getResizeRatio($size, $size); 1198fa8e5c77SKate Arzamastseva $w = floor($w * $ratio); 1199fa8e5c77SKate Arzamastseva $h = floor($h * $ratio); 1200fa8e5c77SKate Arzamastseva } 120124870174SAndreas Gohr return [$w, $h]; 1202fa8e5c77SKate Arzamastseva} 1203fa8e5c77SKate Arzamastseva 1204fa8e5c77SKate Arzamastseva/** 1205fa8e5c77SKate Arzamastseva * Returns the requested EXIF/IPTC tag from the image meta 1206fa8e5c77SKate Arzamastseva * 1207fa8e5c77SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1208e0c26282SGerrit Uitslag * 120942ea7f44SGerrit Uitslag * @param array $tags array with tags, first existing is returned 1210fa8e5c77SKate Arzamastseva * @param JpegMeta $meta 121142ea7f44SGerrit Uitslag * @param string $alt alternative value 1212fa8e5c77SKate Arzamastseva * @return string 1213fa8e5c77SKate Arzamastseva */ 1214d868eb89SAndreas Gohrfunction media_getTag($tags, $meta = false, $alt = '') 1215d868eb89SAndreas Gohr{ 1216871895a7SSatoshi Sahara if (!$meta) return $alt; 1217fa8e5c77SKate Arzamastseva $info = $meta->getField($tags); 1218871895a7SSatoshi Sahara if (!$info) return $alt; 1219fa8e5c77SKate Arzamastseva return $info; 1220fa8e5c77SKate Arzamastseva} 1221fa8e5c77SKate Arzamastseva 1222fa8e5c77SKate Arzamastseva/** 1223e136d6ccSKate Arzamastseva * Returns mediafile tags 12242e55802cSKate Arzamastseva * 12252e55802cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1226e0c26282SGerrit Uitslag * 1227e136d6ccSKate Arzamastseva * @param JpegMeta $meta 122842ea7f44SGerrit Uitslag * @return array list of tags of the mediafile 12292e55802cSKate Arzamastseva */ 1230d868eb89SAndreas Gohrfunction media_file_tags($meta) 1231d868eb89SAndreas Gohr{ 1232532850edSKate Arzamastseva // load the field descriptions 12333e98e685SKate Arzamastseva static $fields = null; 12343e98e685SKate Arzamastseva if (is_null($fields)) { 12353e98e685SKate Arzamastseva $config_files = getConfigFiles('mediameta'); 12363e98e685SKate Arzamastseva foreach ($config_files as $config_file) { 123779e79377SAndreas Gohr if (file_exists($config_file)) include($config_file); 1238532850edSKate Arzamastseva } 1239532850edSKate Arzamastseva } 12401eeeced2SKate Arzamastseva 124124870174SAndreas Gohr $tags = []; 1242dd9ba38eSKate Arzamastseva 124324870174SAndreas Gohr foreach ($fields as $tag) { 124424870174SAndreas Gohr $t = []; 124524870174SAndreas Gohr if (!empty($tag[0])) $t = [$tag[0]]; 12460e80bb5eSChristopher Smith if (isset($tag[3]) && is_array($tag[3])) $t = array_merge($t, $tag[3]); 1247e136d6ccSKate Arzamastseva $value = media_getTag($t, $meta); 124824870174SAndreas Gohr $tags[] = ['tag' => $tag, 'value' => $value]; 1249e136d6ccSKate Arzamastseva } 1250e136d6ccSKate Arzamastseva 1251e136d6ccSKate Arzamastseva return $tags; 1252e136d6ccSKate Arzamastseva} 1253e136d6ccSKate Arzamastseva 1254e136d6ccSKate Arzamastseva/** 1255e136d6ccSKate Arzamastseva * Prints mediafile tags 1256e136d6ccSKate Arzamastseva * 1257e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 125842ea7f44SGerrit Uitslag * 1259e0c26282SGerrit Uitslag * @param string $image image id 1260e0c26282SGerrit Uitslag * @param int $auth permission level 1261e0c26282SGerrit Uitslag * @param string|int $rev revision timestamp, or empty string 1262e0c26282SGerrit Uitslag * @param bool|JpegMeta $meta image object, or create one if false 1263e0c26282SGerrit Uitslag */ 1264d868eb89SAndreas Gohrfunction media_details($image, $auth, $rev = '', $meta = false) 1265d868eb89SAndreas Gohr{ 1266e136d6ccSKate Arzamastseva global $lang; 1267e136d6ccSKate Arzamastseva 1268e136d6ccSKate Arzamastseva if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev)); 1269e136d6ccSKate Arzamastseva $tags = media_file_tags($meta); 1270e136d6ccSKate Arzamastseva 127194add303SAnika Henke echo '<dl>' . NL; 1272e136d6ccSKate Arzamastseva foreach ($tags as $tag) { 1273e136d6ccSKate Arzamastseva if ($tag['value']) { 1274e136d6ccSKate Arzamastseva $value = cleanText($tag['value']); 1275fde860beSGerrit Uitslag echo '<dt>' . $lang[$tag['tag'][1]] . '</dt><dd>'; 12764a90f94bSSatoshi Sahara if ($tag['tag'][2] == 'date') { 12774a90f94bSSatoshi Sahara echo dformat($value); 12784a90f94bSSatoshi Sahara } else { 12794a90f94bSSatoshi Sahara echo hsc($value); 12804a90f94bSSatoshi Sahara } 128194add303SAnika Henke echo '</dd>' . NL; 12821eeeced2SKate Arzamastseva } 1283e136d6ccSKate Arzamastseva } 128494add303SAnika Henke echo '</dl>' . NL; 128522e68399Sflammy echo '<dl>' . NL; 128622e68399Sflammy echo '<dt>' . $lang['reference'] . ':</dt>'; 1287*6734bb8cSAndreas Gohr $media_usage = (new MetadataSearch())->mediause($image, true); 128824870174SAndreas Gohr if ($media_usage !== []) { 128922e68399Sflammy foreach ($media_usage as $path) { 129022e68399Sflammy echo '<dd>' . html_wikilink($path) . '</dd>'; 129122e68399Sflammy } 129222e68399Sflammy } else { 129322e68399Sflammy echo '<dd>' . $lang['nothingfound'] . '</dd>'; 129422e68399Sflammy } 129522e68399Sflammy echo '</dl>' . NL; 12961eeeced2SKate Arzamastseva} 12972e55802cSKate Arzamastseva 12982e55802cSKate Arzamastseva/** 12992e55802cSKate Arzamastseva * Shows difference between two revisions of file 13002e55802cSKate Arzamastseva * 13012e55802cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 130242ea7f44SGerrit Uitslag * 1303e0c26282SGerrit Uitslag * @param string $image image id 1304e0c26282SGerrit Uitslag * @param string $ns 1305e0c26282SGerrit Uitslag * @param int $auth permission level 1306e0c26282SGerrit Uitslag * @param bool $fromajax 130779a2d784SGerrit Uitslag * 1308297071beSSatoshi Sahara * @deprecated 2020-12-31 1309e0c26282SGerrit Uitslag */ 1310d868eb89SAndreas Gohrfunction media_diff($image, $ns, $auth, $fromajax = false) 1311d868eb89SAndreas Gohr{ 131279a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::show()'); 131359e81a43SKate Arzamastseva} 131459e81a43SKate Arzamastseva 13156ffaeda9SGerrit Uitslag/** 13166ffaeda9SGerrit Uitslag * Callback for media file diff 13176ffaeda9SGerrit Uitslag * 131842ea7f44SGerrit Uitslag * @param array $data event data 131979a2d784SGerrit Uitslag * 1320297071beSSatoshi Sahara * @deprecated 2020-12-31 13216ffaeda9SGerrit Uitslag */ 1322d868eb89SAndreas Gohrfunction _media_file_diff($data) 1323d868eb89SAndreas Gohr{ 132479a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::show()'); 132559e81a43SKate Arzamastseva} 132659e81a43SKate Arzamastseva 132759e81a43SKate Arzamastseva/** 132859e81a43SKate Arzamastseva * Shows difference between two revisions of image 132959e81a43SKate Arzamastseva * 133059e81a43SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1331e0c26282SGerrit Uitslag * 1332e0c26282SGerrit Uitslag * @param string $image 1333e0c26282SGerrit Uitslag * @param string|int $l_rev revision timestamp, or empty string 1334e0c26282SGerrit Uitslag * @param string|int $r_rev revision timestamp, or empty string 1335e0c26282SGerrit Uitslag * @param string $ns 1336e0c26282SGerrit Uitslag * @param int $auth permission level 1337e0c26282SGerrit Uitslag * @param bool $fromajax 1338297071beSSatoshi Sahara * @deprecated 2020-12-31 133959e81a43SKate Arzamastseva */ 1340d868eb89SAndreas Gohrfunction media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) 1341d868eb89SAndreas Gohr{ 134279a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::showFileDiff()'); 1343e136d6ccSKate Arzamastseva} 1344e136d6ccSKate Arzamastseva 1345e136d6ccSKate Arzamastseva/** 1346e136d6ccSKate Arzamastseva * Prints two images side by side 1347fa8e5c77SKate Arzamastseva * and slider 1348e136d6ccSKate Arzamastseva * 1349e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 135042ea7f44SGerrit Uitslag * 135142ea7f44SGerrit Uitslag * @param string $image image id 1352e0c26282SGerrit Uitslag * @param int $l_rev revision timestamp, or empty string 1353e0c26282SGerrit Uitslag * @param int $r_rev revision timestamp, or empty string 135442ea7f44SGerrit Uitslag * @param array $l_size array with width and height 135542ea7f44SGerrit Uitslag * @param array $r_size array with width and height 135650fc55feSKate Arzamastseva * @param string $type 1357297071beSSatoshi Sahara * @deprecated 2020-12-31 1358e136d6ccSKate Arzamastseva */ 1359d868eb89SAndreas Gohrfunction media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) 1360d868eb89SAndreas Gohr{ 136179a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::showImageDiff()'); 13621eeeced2SKate Arzamastseva} 13631eeeced2SKate Arzamastseva 13641eeeced2SKate Arzamastseva/** 13659c1bd4bcSKate Arzamastseva * Restores an old revision of a media file 13669c1bd4bcSKate Arzamastseva * 136742ea7f44SGerrit Uitslag * @param string $image media id 136842ea7f44SGerrit Uitslag * @param int $rev revision timestamp or empty string 13699c1bd4bcSKate Arzamastseva * @param int $auth 13709c1bd4bcSKate Arzamastseva * @return string - file's id 137142ea7f44SGerrit Uitslag * 13729c1bd4bcSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 13739c1bd4bcSKate Arzamastseva */ 1374d868eb89SAndreas Gohrfunction media_restore($image, $rev, $auth) 1375d868eb89SAndreas Gohr{ 1376e5d185e1SKate Arzamastseva global $conf; 137780525638SKate Arzamastseva if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false; 137892cac9a9SKate Arzamastseva $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes'))); 137992cac9a9SKate Arzamastseva if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false; 13809c1bd4bcSKate Arzamastseva if (!$rev || !file_exists(mediaFN($image, $rev))) return false; 138124870174SAndreas Gohr [, $imime, ] = mimetype($image); 1382dccd6b2bSAndreas Gohr $res = media_upload_finish( 1383dccd6b2bSAndreas Gohr mediaFN($image, $rev), 13849c1bd4bcSKate Arzamastseva mediaFN($image), 13859c1bd4bcSKate Arzamastseva $image, 13869c1bd4bcSKate Arzamastseva $imime, 13879c1bd4bcSKate Arzamastseva true, 1388dccd6b2bSAndreas Gohr 'copy' 1389dccd6b2bSAndreas Gohr ); 13909c1bd4bcSKate Arzamastseva if (is_array($res)) { 13919c1bd4bcSKate Arzamastseva msg($res[0], $res[1]); 13929c1bd4bcSKate Arzamastseva return false; 13939c1bd4bcSKate Arzamastseva } 13949c1bd4bcSKate Arzamastseva return $res; 13959c1bd4bcSKate Arzamastseva} 13969c1bd4bcSKate Arzamastseva 13979c1bd4bcSKate Arzamastseva/** 1398bf1f3ac4Ssarnowski * List all files found by the search request 1399c9f56829SAndreas Gohr * 1400c9f56829SAndreas Gohr * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1401c9f56829SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 1402d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1403c9f56829SAndreas Gohr * @triggers MEDIA_SEARCH 1404e0c26282SGerrit Uitslag * 1405e0c26282SGerrit Uitslag * @param string $query 1406e0c26282SGerrit Uitslag * @param string $ns 1407e0c26282SGerrit Uitslag * @param null|int $auth 1408e0c26282SGerrit Uitslag * @param bool $fullscreen 1409e0c26282SGerrit Uitslag * @param string $sort 1410bf1f3ac4Ssarnowski */ 1411d868eb89SAndreas Gohrfunction media_searchlist($query, $ns, $auth = null, $fullscreen = false, $sort = 'natural') 1412d868eb89SAndreas Gohr{ 1413bf1f3ac4Ssarnowski global $conf; 1414bf1f3ac4Ssarnowski global $lang; 14158e69fd30SKate Arzamastseva 1416bf1f3ac4Ssarnowski $ns = cleanID($ns); 141724870174SAndreas Gohr $evdata = [ 141856fe6664SAndreas Gohr 'ns' => $ns, 141924870174SAndreas Gohr 'data' => [], 142056fe6664SAndreas Gohr 'query' => $query 142124870174SAndreas Gohr ]; 14227ed31746SSzymon Olewniczak if (!blank($query)) { 1423e1d9dcc8SAndreas Gohr $evt = new Event('MEDIA_SEARCH', $evdata); 1424bf1f3ac4Ssarnowski if ($evt->advise_before()) { 142556fe6664SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $evdata['ns'])); 142676472096SSzymon Olewniczak $quoted = preg_quote($evdata['query'], '/'); 142776472096SSzymon Olewniczak //apply globbing 142824870174SAndreas Gohr $quoted = str_replace(['\*', '\?'], ['.*', '.'], $quoted, $count); 142923e31e76SSzymon Olewniczak 143023e31e76SSzymon Olewniczak //if we use globbing file name must match entirely but may be preceded by arbitrary namespace 143123e31e76SSzymon Olewniczak if ($count > 0) $quoted = '^([^:]*:)*' . $quoted . '$'; 143223e31e76SSzymon Olewniczak 143376472096SSzymon Olewniczak $pattern = '/' . $quoted . '/i'; 1434dccd6b2bSAndreas Gohr search( 1435dccd6b2bSAndreas Gohr $evdata['data'], 143656fe6664SAndreas Gohr $conf['mediadir'], 14374f33babfSAndreas Gohr 'search_mediafiles', 143824870174SAndreas Gohr ['showmsg' => false, 'pattern' => $pattern], 143900e3e394SChristopher Smith $dir, 144000e3e394SChristopher Smith 1, 1441dccd6b2bSAndreas Gohr $sort 1442dccd6b2bSAndreas Gohr ); 1443bf1f3ac4Ssarnowski } 1444bf1f3ac4Ssarnowski $evt->advise_after(); 1445bf1f3ac4Ssarnowski unset($evt); 144656fe6664SAndreas Gohr } 1447bf1f3ac4Ssarnowski 1448d9162c6cSKate Arzamastseva if (!$fullscreen) { 144956fe6664SAndreas Gohr echo '<h1 id="media__ns">' . sprintf($lang['searchmedia_in'], hsc($ns) . ':*') . '</h1>' . NL; 145056fe6664SAndreas Gohr media_searchform($ns, $query); 1451d9162c6cSKate Arzamastseva } 145256fe6664SAndreas Gohr 145356fe6664SAndreas Gohr if (!count($evdata['data'])) { 1454bf1f3ac4Ssarnowski echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; 14555b9353faSKate Arzamastseva } else { 14565b9353faSKate Arzamastseva if ($fullscreen) { 1457554a8c9fSAdrian Lang echo '<ul class="' . _media_get_list_type() . '">'; 14585b9353faSKate Arzamastseva } 14595b9353faSKate Arzamastseva foreach ($evdata['data'] as $item) { 14604f33babfSAndreas Gohr if (!$fullscreen) { 14614f33babfSAndreas Gohr // FIXME old call: media_printfile($item,$item['perm'],'',true); 146279a2d784SGerrit Uitslag $display = new DisplayRow($item); 146379b00823SAndreas Gohr $display->relativeDisplay($ns); 14644f33babfSAndreas Gohr $display->show(); 14654f33babfSAndreas Gohr } else { 14664f33babfSAndreas Gohr // FIXME old call: media_printfile_thumbs($item,$item['perm'],false,true); 146779a2d784SGerrit Uitslag $display = new DisplayTile($item); 146879b00823SAndreas Gohr $display->relativeDisplay($ns); 14694f33babfSAndreas Gohr echo '<li>'; 14704f33babfSAndreas Gohr $display->show(); 14714f33babfSAndreas Gohr echo '</li>'; 14724f33babfSAndreas Gohr } 1473bf1f3ac4Ssarnowski } 147494add303SAnika Henke if ($fullscreen) echo '</ul>' . NL; 14755b9353faSKate Arzamastseva } 1476bf1f3ac4Ssarnowski} 1477bf1f3ac4Ssarnowski 1478bf1f3ac4Ssarnowski/** 1479c6571d58SAndreas Gohr * Display a media icon 1480c6571d58SAndreas Gohr * 148142ea7f44SGerrit Uitslag * @param string $filename media id 1482c6571d58SAndreas Gohr * @param string $size the size subfolder, if not specified 16x16 is used 148342ea7f44SGerrit Uitslag * @return string html 1484c6571d58SAndreas Gohr */ 1485d868eb89SAndreas Gohrfunction media_printicon($filename, $size = '') 1486d868eb89SAndreas Gohr{ 148724870174SAndreas Gohr [$ext] = mimetype(mediaFN($filename), false); 148823786fd7SKate Arzamastseva 148979e79377SAndreas Gohr if (file_exists(DOKU_INC . 'lib/images/fileicons/' . $size . '/' . $ext . '.png')) { 1490c6571d58SAndreas Gohr $icon = DOKU_BASE . 'lib/images/fileicons/' . $size . '/' . $ext . '.png'; 149123786fd7SKate Arzamastseva } else { 1492c6571d58SAndreas Gohr $icon = DOKU_BASE . 'lib/images/fileicons/' . $size . '/file.png'; 149323786fd7SKate Arzamastseva } 149423786fd7SKate Arzamastseva 1495421ec38eSKate Arzamastseva return '<img src="' . $icon . '" alt="' . $filename . '" class="icon" />'; 149623786fd7SKate Arzamastseva} 149723786fd7SKate Arzamastseva 14983df72098SAndreas Gohr/** 149942ea7f44SGerrit Uitslag * Build link based on the current, adding/rewriting parameters 1500d9162c6cSKate Arzamastseva * 1501d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 150242ea7f44SGerrit Uitslag * 1503ebc28e69SAndreas Gohr * @param array|bool $params 150442ea7f44SGerrit Uitslag * @param string $amp separator 150542ea7f44SGerrit Uitslag * @param bool $abs absolute url? 150642ea7f44SGerrit Uitslag * @param bool $params_array return the parmeters array? 150742ea7f44SGerrit Uitslag * @return string|array - link or link parameters 1508d9162c6cSKate Arzamastseva */ 1509d868eb89SAndreas Gohrfunction media_managerURL($params = false, $amp = '&', $abs = false, $params_array = false) 1510d868eb89SAndreas Gohr{ 1511d9162c6cSKate Arzamastseva global $ID; 15128108113cSTom N Harris global $INPUT; 1513d9162c6cSKate Arzamastseva 151424870174SAndreas Gohr $gets = ['do' => 'media']; 151524870174SAndreas Gohr $media_manager_params = ['tab_files', 'tab_details', 'image', 'ns', 'list', 'sort']; 151623846a98SKate Arzamastseva foreach ($media_manager_params as $x) { 15178108113cSTom N Harris if ($INPUT->has($x)) $gets[$x] = $INPUT->str($x); 151823846a98SKate Arzamastseva } 1519d9162c6cSKate Arzamastseva 1520d9162c6cSKate Arzamastseva if ($params) { 1521554a8c9fSAdrian Lang $gets = $params + $gets; 1522d9162c6cSKate Arzamastseva } 1523d9162c6cSKate Arzamastseva unset($gets['id']); 1524554a8c9fSAdrian Lang if (isset($gets['delete'])) { 15251eeeced2SKate Arzamastseva unset($gets['image']); 15261eeeced2SKate Arzamastseva unset($gets['tab_details']); 15271eeeced2SKate Arzamastseva } 1528d9162c6cSKate Arzamastseva 1529035e07f1SKate Arzamastseva if ($params_array) return $gets; 1530035e07f1SKate Arzamastseva 15316dd095f5SKate Arzamastseva return wl($ID, $gets, $abs, $amp); 1532d9162c6cSKate Arzamastseva} 1533d9162c6cSKate Arzamastseva 1534d9162c6cSKate Arzamastseva/** 15353df72098SAndreas Gohr * Print the media upload form if permissions are correct 15363df72098SAndreas Gohr * 15373df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1538d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1539e0c26282SGerrit Uitslag * 1540e0c26282SGerrit Uitslag * @param string $ns 1541e0c26282SGerrit Uitslag * @param int $auth permission level 1542e0c26282SGerrit Uitslag * @param bool $fullscreen 15433df72098SAndreas Gohr */ 1544d868eb89SAndreas Gohrfunction media_uploadform($ns, $auth, $fullscreen = false) 1545d868eb89SAndreas Gohr{ 15468108113cSTom N Harris global $lang; 15478108113cSTom N Harris global $conf; 15488108113cSTom N Harris global $INPUT; 15493df72098SAndreas Gohr 155088a71175SKate Arzamastseva if ($auth < AUTH_UPLOAD) { 155188a71175SKate Arzamastseva echo '<div class="nothing">' . $lang['media_perm_upload'] . '</div>' . NL; 155288a71175SKate Arzamastseva return; 155388a71175SKate Arzamastseva } 155492cac9a9SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 15553df72098SAndreas Gohr 155670c3cc9aSKate Arzamastseva $update = false; 155770c3cc9aSKate Arzamastseva $id = ''; 15588108113cSTom N Harris if ($auth >= $auth_ow && $fullscreen && $INPUT->str('mediado') == 'update') { 155970c3cc9aSKate Arzamastseva $update = true; 15608108113cSTom N Harris $id = cleanID($INPUT->str('image')); 156170c3cc9aSKate Arzamastseva } 156270c3cc9aSKate Arzamastseva 1563d00ec455SAndreas Gohr // The default HTML upload form 1564b960c74fSSatoshi Sahara $form = new Form([ 1565b960c74fSSatoshi Sahara 'id' => 'dw__upload', 1566b960c74fSSatoshi Sahara 'enctype' => 'multipart/form-data', 1567b960c74fSSatoshi Sahara 'action' => ($fullscreen) 1568b960c74fSSatoshi Sahara ? media_managerURL(['tab_files' => 'files', 'tab_details' => 'view'], '&') 1569b960c74fSSatoshi Sahara : DOKU_BASE . 'lib/exe/mediamanager.php', 1570b960c74fSSatoshi Sahara ]); 1571b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1572b960c74fSSatoshi Sahara $form->setHiddenField('ns', hsc($ns)); // FIXME hsc required? 1573b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1574b960c74fSSatoshi Sahara $form->addTextInput('upload', $lang['txt_upload'])->id('upload__file') 1575b960c74fSSatoshi Sahara ->attrs(['type' => 'file']); 1576b960c74fSSatoshi Sahara $form->addTagClose('p'); 1577b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1578b960c74fSSatoshi Sahara $form->addTextInput('mediaid', $lang['txt_filename'])->id('upload__name') 1579b960c74fSSatoshi Sahara ->val(noNS($id)); 1580b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_upload'])->attr('type', 'submit'); 1581b960c74fSSatoshi Sahara $form->addTagClose('p'); 158292cac9a9SKate Arzamastseva if ($auth >= $auth_ow) { 1583b960c74fSSatoshi Sahara $form->addTagOpen('p'); 158424870174SAndreas Gohr $attrs = []; 158570c3cc9aSKate Arzamastseva if ($update) $attrs['checked'] = 'checked'; 1586b960c74fSSatoshi Sahara $form->addCheckbox('ow', $lang['txt_overwrt'])->id('dw__ow')->val('1') 1587b960c74fSSatoshi Sahara ->addClass('check')->attrs($attrs); 1588b960c74fSSatoshi Sahara $form->addTagClose('p'); 1589b960c74fSSatoshi Sahara } 1590b960c74fSSatoshi Sahara $form->addTagClose('div'); 1591b960c74fSSatoshi Sahara 1592b960c74fSSatoshi Sahara if (!$fullscreen) { 1593b960c74fSSatoshi Sahara echo '<div class="upload">' . $lang['mediaupload'] . '</div>' . DOKU_LF; 1594b960c74fSSatoshi Sahara } else { 1595b960c74fSSatoshi Sahara echo DOKU_LF; 15963df72098SAndreas Gohr } 1597c472bad9SKate Arzamastseva 1598b960c74fSSatoshi Sahara echo '<div id="mediamanager__uploader">' . DOKU_LF; 1599c6977b3aSSatoshi Sahara echo $form->toHTML('Upload'); 1600b960c74fSSatoshi Sahara echo '</div>' . DOKU_LF; 1601f940e4a0SAndreas Gohr 1602f940e4a0SAndreas Gohr echo '<p class="maxsize">'; 1603f940e4a0SAndreas Gohr printf($lang['maxuploadsize'], filesize_h(media_getuploadsize())); 160456fc6b15SAnna Dabrowska echo ' <a class="allowedmime" href="#">' . $lang['allowedmime'] . '</a>'; 1605499d9bcdSAndreas Gohr echo ' <span>' . implode(', ', array_keys(getMimeTypes())) . '</span>'; 1606b960c74fSSatoshi Sahara echo '</p>' . DOKU_LF; 1607f940e4a0SAndreas Gohr} 1608f940e4a0SAndreas Gohr 1609f940e4a0SAndreas Gohr/** 1610f940e4a0SAndreas Gohr * Returns the size uploaded files may have 1611f940e4a0SAndreas Gohr * 1612f940e4a0SAndreas Gohr * This uses a conservative approach using the lowest number found 1613f940e4a0SAndreas Gohr * in any of the limiting ini settings 1614f940e4a0SAndreas Gohr * 1615f940e4a0SAndreas Gohr * @returns int size in bytes 1616f940e4a0SAndreas Gohr */ 1617d868eb89SAndreas Gohrfunction media_getuploadsize() 1618d868eb89SAndreas Gohr{ 1619f940e4a0SAndreas Gohr $okay = 0; 1620f940e4a0SAndreas Gohr 162124870174SAndreas Gohr $post = php_to_byte(@ini_get('post_max_size')); 162224870174SAndreas Gohr $suho = php_to_byte(@ini_get('suhosin.post.max_value_length')); 162324870174SAndreas Gohr $upld = php_to_byte(@ini_get('upload_max_filesize')); 1624f940e4a0SAndreas Gohr 162524870174SAndreas Gohr if ($post && ($post < $okay || $okay === 0)) $okay = $post; 1626f940e4a0SAndreas Gohr if ($suho && ($suho < $okay || $okay == 0)) $okay = $suho; 1627f940e4a0SAndreas Gohr if ($upld && ($upld < $okay || $okay == 0)) $okay = $upld; 1628f940e4a0SAndreas Gohr 1629f940e4a0SAndreas Gohr return $okay; 16309f5dde7fSMichael Klier} 16313df72098SAndreas Gohr 16323df72098SAndreas Gohr/** 1633bf1f3ac4Ssarnowski * Print the search field form 1634bf1f3ac4Ssarnowski * 1635bf1f3ac4Ssarnowski * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1636d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1637e0c26282SGerrit Uitslag * 1638e0c26282SGerrit Uitslag * @param string $ns 1639e0c26282SGerrit Uitslag * @param string $query 1640e0c26282SGerrit Uitslag * @param bool $fullscreen 1641bf1f3ac4Ssarnowski */ 1642d868eb89SAndreas Gohrfunction media_searchform($ns, $query = '', $fullscreen = false) 1643d868eb89SAndreas Gohr{ 1644bf1f3ac4Ssarnowski global $lang; 1645bf1f3ac4Ssarnowski 1646bf1f3ac4Ssarnowski // The default HTML search form 1647b960c74fSSatoshi Sahara $form = new Form([ 1648b960c74fSSatoshi Sahara 'id' => 'dw__mediasearch', 1649b960c74fSSatoshi Sahara 'action' => ($fullscreen) 1650b960c74fSSatoshi Sahara ? media_managerURL([], '&') 1651b960c74fSSatoshi Sahara : DOKU_BASE . 'lib/exe/mediamanager.php', 1652b960c74fSSatoshi Sahara ]); 1653b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1654b960c74fSSatoshi Sahara $form->setHiddenField('ns', $ns); 1655b960c74fSSatoshi Sahara $form->setHiddenField($fullscreen ? 'mediado' : 'do', 'searchlist'); 1656554a8c9fSAdrian Lang 1657b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1658bde2a644SSatoshi Sahara $form->addTextInput('q', $lang['searchmedia']) 1659b960c74fSSatoshi Sahara ->attr('title', sprintf($lang['searchmedia_in'], hsc($ns) . ':*')) 1660b960c74fSSatoshi Sahara ->val($query); 1661bde2a644SSatoshi Sahara $form->addHTML(' '); 1662b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_search'])->attr('type', 'submit'); 1663b960c74fSSatoshi Sahara $form->addTagClose('p'); 1664b960c74fSSatoshi Sahara $form->addTagClose('div'); 166526dfc232SAndreas Gohr echo $form->toHTML('SearchMedia'); 1666bf1f3ac4Ssarnowski} 1667bf1f3ac4Ssarnowski 1668bf1f3ac4Ssarnowski/** 16693df72098SAndreas Gohr * Build a tree outline of available media namespaces 16703df72098SAndreas Gohr * 16713df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1672e0c26282SGerrit Uitslag * 1673e0c26282SGerrit Uitslag * @param string $ns 16743df72098SAndreas Gohr */ 1675d868eb89SAndreas Gohrfunction media_nstree($ns) 1676d868eb89SAndreas Gohr{ 16773df72098SAndreas Gohr global $conf; 1678256ca81eSAndreas Gohr global $lang; 16793df72098SAndreas Gohr 16803df72098SAndreas Gohr // currently selected namespace 16813df72098SAndreas Gohr $ns = cleanID($ns); 16823df72098SAndreas Gohr if (empty($ns)) { 1683de3eb1d7SAdrian Lang global $ID; 1684dd90013aSMichael Hamann $ns = (string)getNS($ID); 16853df72098SAndreas Gohr } 1686dd90013aSMichael Hamann 1687dd90013aSMichael Hamann $ns_dir = utf8_encodeFN(str_replace(':', '/', $ns)); 16883df72098SAndreas Gohr 168924870174SAndreas Gohr $data = []; 169024870174SAndreas Gohr search($data, $conf['mediadir'], 'search_index', ['ns' => $ns_dir, 'nofiles' => true]); 16913df72098SAndreas Gohr 16923df72098SAndreas Gohr // wrap a list with the root level around the other namespaces 169324870174SAndreas Gohr array_unshift($data, ['level' => 0, 'id' => '', 'open' => 'true', 'label' => '[' . $lang['mediaroot'] . ']']); 16943df72098SAndreas Gohr 1695dd90013aSMichael Hamann // insert the current ns into the hierarchy if it isn't already part of it 1696dd90013aSMichael Hamann $ns_parts = explode(':', $ns); 1697dd90013aSMichael Hamann $tmp_ns = ''; 1698dd90013aSMichael Hamann $pos = 0; 1699de301a35SDamien Regad $insert = false; 1700dd90013aSMichael Hamann foreach ($ns_parts as $level => $part) { 1701186263b2SDamien Regad if ($tmp_ns) { 1702186263b2SDamien Regad $tmp_ns .= ':' . $part; 1703186263b2SDamien Regad } else { 1704186263b2SDamien Regad $tmp_ns = $part; 1705186263b2SDamien Regad } 1706dd90013aSMichael Hamann 1707de301a35SDamien Regad // find the namespace parts 17089988e853SDamien Regad while (array_key_exists($pos, $data) && $data[$pos]['id'] != $tmp_ns) { 170964159a61SAndreas Gohr if ( 171064159a61SAndreas Gohr $pos >= count($data) || 17112d85e841SAndreas Gohr ($data[$pos]['level'] <= $level + 1 && Sort::strcmp($data[$pos]['id'], $tmp_ns) > 0) 171264159a61SAndreas Gohr ) { 1713de301a35SDamien Regad $insert = true; 1714dd90013aSMichael Hamann break; 1715dd90013aSMichael Hamann } 1716dd90013aSMichael Hamann ++$pos; 1717dd90013aSMichael Hamann } 1718de301a35SDamien Regad // insert namespace in hierarchy; if not found in above loop, append it to the end 1719b3894732Ssplitbrain if ($insert || $pos === count($data)) { 1720de301a35SDamien Regad array_splice($data, $pos, 0, [['level' => $level + 1, 'id' => $tmp_ns, 'open' => 'true']]); 1721de301a35SDamien Regad } 1722dd90013aSMichael Hamann } 1723dd90013aSMichael Hamann 17243df72098SAndreas Gohr echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); 17253df72098SAndreas Gohr} 17263df72098SAndreas Gohr 17273df72098SAndreas Gohr/** 17283df72098SAndreas Gohr * Userfunction for html_buildlist 17293df72098SAndreas Gohr * 17303df72098SAndreas Gohr * Prints a media namespace tree item 17313df72098SAndreas Gohr * 17323df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 173342ea7f44SGerrit Uitslag * 173442ea7f44SGerrit Uitslag * @param array $item 173542ea7f44SGerrit Uitslag * @return string html 17363df72098SAndreas Gohr */ 1737d868eb89SAndreas Gohrfunction media_nstree_item($item) 1738d868eb89SAndreas Gohr{ 17398108113cSTom N Harris global $INPUT; 17403df72098SAndreas Gohr $pos = strrpos($item['id'], ':'); 17413df72098SAndreas Gohr $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); 17420e80bb5eSChristopher Smith if (empty($item['label'])) $item['label'] = $label; 17433df72098SAndreas Gohr 17443df72098SAndreas Gohr $ret = ''; 174524870174SAndreas Gohr if ($INPUT->str('do') != 'media') 17463df72098SAndreas Gohr $ret .= '<a href="' . DOKU_BASE . 'lib/exe/mediamanager.php?ns=' . idfilter($item['id']) . '" class="idx_dir">'; 1747b960c74fSSatoshi Sahara else $ret .= '<a href="' . media_managerURL(['ns' => idfilter($item['id'], false), 'tab_files' => 'files']) 174823846a98SKate Arzamastseva . '" class="idx_dir">'; 17493df72098SAndreas Gohr $ret .= $item['label']; 17503df72098SAndreas Gohr $ret .= '</a>'; 17513df72098SAndreas Gohr return $ret; 17523df72098SAndreas Gohr} 17533df72098SAndreas Gohr 17543df72098SAndreas Gohr/** 17553df72098SAndreas Gohr * Userfunction for html_buildlist 17563df72098SAndreas Gohr * 17573df72098SAndreas Gohr * Prints a media namespace tree item opener 17583df72098SAndreas Gohr * 17593df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 176042ea7f44SGerrit Uitslag * 176142ea7f44SGerrit Uitslag * @param array $item 176242ea7f44SGerrit Uitslag * @return string html 17633df72098SAndreas Gohr */ 1764d868eb89SAndreas Gohrfunction media_nstree_li($item) 1765d868eb89SAndreas Gohr{ 17663df72098SAndreas Gohr $class = 'media level' . $item['level']; 17673df72098SAndreas Gohr if ($item['open']) { 17683df72098SAndreas Gohr $class .= ' open'; 17693df72098SAndreas Gohr $img = DOKU_BASE . 'lib/images/minus.gif'; 1770e260f93bSAnika Henke $alt = '−'; 17713df72098SAndreas Gohr } else { 17723df72098SAndreas Gohr $class .= ' closed'; 17733df72098SAndreas Gohr $img = DOKU_BASE . 'lib/images/plus.gif'; 17747af1b404SAnika Henke $alt = '+'; 17753df72098SAndreas Gohr } 1776231b8c34SPierre Spring // TODO: only deliver an image if it actually has a subtree... 17773df72098SAndreas Gohr return '<li class="' . $class . '">' . 17787af1b404SAnika Henke '<img src="' . $img . '" alt="' . $alt . '" />'; 17793df72098SAndreas Gohr} 178013c08e2fSMichael Klier 178113c08e2fSMichael Klier/** 1782b021f0b4SAndreas Gohr * Resizes or crop the given image to the given size 1783b021f0b4SAndreas Gohr * 1784b021f0b4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1785b021f0b4SAndreas Gohr * 1786b021f0b4SAndreas Gohr * @param string $file filename, path to file 1787b021f0b4SAndreas Gohr * @param string $ext extension 1788b021f0b4SAndreas Gohr * @param int $w desired width 1789b021f0b4SAndreas Gohr * @param int $h desired height 1790b021f0b4SAndreas Gohr * @param bool $crop should a center crop be used? 1791b021f0b4SAndreas Gohr * @return string path to resized or original size if failed 1792b021f0b4SAndreas Gohr */ 1793b021f0b4SAndreas Gohrfunction media_mod_image($file, $ext, $w, $h = 0, $crop = false) 1794b021f0b4SAndreas Gohr{ 1795b021f0b4SAndreas Gohr global $conf; 1796d967ecd8SAndreas Gohr if (!$h) $h = 0; 1797b021f0b4SAndreas Gohr // we wont scale up to infinity 1798b021f0b4SAndreas Gohr if ($w > 2000 || $h > 2000) return $file; 1799b021f0b4SAndreas Gohr 1800b021f0b4SAndreas Gohr $operation = $crop ? 'crop' : 'resize'; 1801b021f0b4SAndreas Gohr 1802b021f0b4SAndreas Gohr $options = [ 1803b021f0b4SAndreas Gohr 'quality' => $conf['jpg_quality'], 1804b021f0b4SAndreas Gohr 'imconvert' => $conf['im_convert'], 1805b021f0b4SAndreas Gohr ]; 1806b021f0b4SAndreas Gohr 180724870174SAndreas Gohr $cache = new CacheImageMod($file, $w, $h, $ext, $crop); 1808b021f0b4SAndreas Gohr if (!$cache->useCache()) { 1809b021f0b4SAndreas Gohr try { 1810b021f0b4SAndreas Gohr Slika::run($file, $options) 1811b021f0b4SAndreas Gohr ->autorotate() 1812b021f0b4SAndreas Gohr ->$operation($w, $h) 1813b021f0b4SAndreas Gohr ->save($cache->cache, $ext); 1814b021f0b4SAndreas Gohr if ($conf['fperm']) @chmod($cache->cache, $conf['fperm']); 181524870174SAndreas Gohr } catch (Exception $e) { 1816b021f0b4SAndreas Gohr Logger::debug($e->getMessage()); 1817b021f0b4SAndreas Gohr return $file; 1818b021f0b4SAndreas Gohr } 1819b021f0b4SAndreas Gohr } 1820b021f0b4SAndreas Gohr 1821b021f0b4SAndreas Gohr return $cache->cache; 1822b021f0b4SAndreas Gohr} 1823b021f0b4SAndreas Gohr 1824b021f0b4SAndreas Gohr/** 182513c08e2fSMichael Klier * Resizes the given image to the given size 182613c08e2fSMichael Klier * 182713c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 182842ea7f44SGerrit Uitslag * 182942ea7f44SGerrit Uitslag * @param string $file filename, path to file 183042ea7f44SGerrit Uitslag * @param string $ext extension 183142ea7f44SGerrit Uitslag * @param int $w desired width 183242ea7f44SGerrit Uitslag * @param int $h desired height 183342ea7f44SGerrit Uitslag * @return string path to resized or original size if failed 183413c08e2fSMichael Klier */ 1835b021f0b4SAndreas Gohrfunction media_resize_image($file, $ext, $w, $h = 0) 1836b021f0b4SAndreas Gohr{ 1837b021f0b4SAndreas Gohr return media_mod_image($file, $ext, $w, $h, false); 1838d2bd34a5SAndreas Gohr} 183913c08e2fSMichael Klier 184013c08e2fSMichael Klier/** 1841d2bd34a5SAndreas Gohr * Center crops the given image to the wanted size 184213c08e2fSMichael Klier * 184313c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 184442ea7f44SGerrit Uitslag * 184542ea7f44SGerrit Uitslag * @param string $file filename, path to file 184642ea7f44SGerrit Uitslag * @param string $ext extension 184742ea7f44SGerrit Uitslag * @param int $w desired width 184842ea7f44SGerrit Uitslag * @param int $h desired height 184942ea7f44SGerrit Uitslag * @return string path to resized or original size if failed 185013c08e2fSMichael Klier */ 1851b021f0b4SAndreas Gohrfunction media_crop_image($file, $ext, $w, $h = 0) 1852b021f0b4SAndreas Gohr{ 1853b021f0b4SAndreas Gohr return media_mod_image($file, $ext, $w, $h, true); 185413c08e2fSMichael Klier} 185513c08e2fSMichael Klier 185613c08e2fSMichael Klier/** 18570f4e0092SChristopher Smith * Calculate a token to be used to verify fetch requests for resized or 18580f4e0092SChristopher Smith * cropped images have been internally generated - and prevent external 18590f4e0092SChristopher Smith * DDOS attacks via fetch 18600f4e0092SChristopher Smith * 18613c124064SAndreas Gohr * @author Christopher Smith <chris@jalakai.co.uk> 18623c124064SAndreas Gohr * 18630f4e0092SChristopher Smith * @param string $id id of the image 18640f4e0092SChristopher Smith * @param int $w resize/crop width 18650f4e0092SChristopher Smith * @param int $h resize/crop height 186642ea7f44SGerrit Uitslag * @return string token or empty string if no token required 18670f4e0092SChristopher Smith */ 1868d868eb89SAndreas Gohrfunction media_get_token($id, $w, $h) 1869d868eb89SAndreas Gohr{ 18700f4e0092SChristopher Smith // token is only required for modified images 1871cc036f74SKlap-in if ($w || $h || media_isexternal($id)) { 18723c124064SAndreas Gohr $token = $id; 18730f4e0092SChristopher Smith if ($w) $token .= '.' . $w; 18740f4e0092SChristopher Smith if ($h) $token .= '.' . $h; 18750f4e0092SChristopher Smith 187624870174SAndreas Gohr return substr(PassHash::hmac('md5', $token, auth_cookiesalt()), 0, 6); 18770f4e0092SChristopher Smith } 18780f4e0092SChristopher Smith 18790f4e0092SChristopher Smith return ''; 18800f4e0092SChristopher Smith} 18810f4e0092SChristopher Smith 18820f4e0092SChristopher Smith/** 188313c08e2fSMichael Klier * Download a remote file and return local filename 188413c08e2fSMichael Klier * 188513c08e2fSMichael Klier * returns false if download fails. Uses cached file if available and 188613c08e2fSMichael Klier * wanted 188713c08e2fSMichael Klier * 188813c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 188913c08e2fSMichael Klier * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 189042ea7f44SGerrit Uitslag * 189142ea7f44SGerrit Uitslag * @param string $url 189242ea7f44SGerrit Uitslag * @param string $ext extension 189342ea7f44SGerrit Uitslag * @param int $cache cachetime in seconds 189442ea7f44SGerrit Uitslag * @return false|string path to cached file 189513c08e2fSMichael Klier */ 1896d868eb89SAndreas Gohrfunction media_get_from_URL($url, $ext, $cache) 1897d868eb89SAndreas Gohr{ 189813c08e2fSMichael Klier global $conf; 189913c08e2fSMichael Klier 190013c08e2fSMichael Klier // if no cache or fetchsize just redirect 190113c08e2fSMichael Klier if ($cache == 0) return false; 190213c08e2fSMichael Klier if (!$conf['fetchsize']) return false; 190313c08e2fSMichael Klier 190413c08e2fSMichael Klier $local = getCacheName(strtolower($url), ".media.$ext"); 190513c08e2fSMichael Klier $mtime = @filemtime($local); // 0 if not exists 190613c08e2fSMichael Klier 190713c08e2fSMichael Klier //decide if download needed: 19087d34963bSAndreas Gohr if ( 19097d34963bSAndreas Gohr ($mtime == 0) || // cache does not exist 191013c08e2fSMichael Klier ($cache != -1 && $mtime < time() - $cache) // 'recache' and cache has expired 191113c08e2fSMichael Klier ) { 191213c08e2fSMichael Klier if (media_image_download($url, $local)) { 191313c08e2fSMichael Klier return $local; 191413c08e2fSMichael Klier } else { 191513c08e2fSMichael Klier return false; 191613c08e2fSMichael Klier } 191713c08e2fSMichael Klier } 191813c08e2fSMichael Klier 191913c08e2fSMichael Klier //if cache exists use it else 192013c08e2fSMichael Klier if ($mtime) return $local; 192113c08e2fSMichael Klier 192213c08e2fSMichael Klier //else return false 192313c08e2fSMichael Klier return false; 192413c08e2fSMichael Klier} 192513c08e2fSMichael Klier 192613c08e2fSMichael Klier/** 192713c08e2fSMichael Klier * Download image files 192813c08e2fSMichael Klier * 192913c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 193042ea7f44SGerrit Uitslag * 193142ea7f44SGerrit Uitslag * @param string $url 193242ea7f44SGerrit Uitslag * @param string $file path to file in which to put the downloaded content 193342ea7f44SGerrit Uitslag * @return bool 193413c08e2fSMichael Klier */ 1935d868eb89SAndreas Gohrfunction media_image_download($url, $file) 1936d868eb89SAndreas Gohr{ 193713c08e2fSMichael Klier global $conf; 193813c08e2fSMichael Klier $http = new DokuHTTPClient(); 1939a5951419SAndreas Gohr $http->keep_alive = false; // we do single ops here, no need for keep-alive 1940a5951419SAndreas Gohr 194113c08e2fSMichael Klier $http->max_bodysize = $conf['fetchsize']; 194213c08e2fSMichael Klier $http->timeout = 25; //max. 25 sec 194313c08e2fSMichael Klier $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; 194413c08e2fSMichael Klier 194513c08e2fSMichael Klier $data = $http->get($url); 194613c08e2fSMichael Klier if (!$data) return false; 194713c08e2fSMichael Klier 194879e79377SAndreas Gohr $fileexists = file_exists($file); 194913c08e2fSMichael Klier $fp = @fopen($file, "w"); 195013c08e2fSMichael Klier if (!$fp) return false; 195113c08e2fSMichael Klier fwrite($fp, $data); 195213c08e2fSMichael Klier fclose($fp); 195324870174SAndreas Gohr if (!$fileexists && $conf['fperm']) chmod($file, $conf['fperm']); 195413c08e2fSMichael Klier 195513c08e2fSMichael Klier // check if it is really an image 195613c08e2fSMichael Klier $info = @getimagesize($file); 195713c08e2fSMichael Klier if (!$info) { 195813c08e2fSMichael Klier @unlink($file); 195913c08e2fSMichael Klier return false; 196013c08e2fSMichael Klier } 196113c08e2fSMichael Klier 196213c08e2fSMichael Klier return true; 196313c08e2fSMichael Klier} 196413c08e2fSMichael Klier 196513c08e2fSMichael Klier/** 196613c08e2fSMichael Klier * resize images using external ImageMagick convert program 196713c08e2fSMichael Klier * 196813c08e2fSMichael Klier * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 196913c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 197042ea7f44SGerrit Uitslag * 197142ea7f44SGerrit Uitslag * @param string $ext extension 197242ea7f44SGerrit Uitslag * @param string $from filename path to file 197342ea7f44SGerrit Uitslag * @param int $from_w original width 197442ea7f44SGerrit Uitslag * @param int $from_h original height 197542ea7f44SGerrit Uitslag * @param string $to path to resized file 197642ea7f44SGerrit Uitslag * @param int $to_w desired width 197742ea7f44SGerrit Uitslag * @param int $to_h desired height 197842ea7f44SGerrit Uitslag * @return bool 197913c08e2fSMichael Klier */ 1980d868eb89SAndreas Gohrfunction media_resize_imageIM($ext, $from, $from_w, $from_h, $to, $to_w, $to_h) 1981d868eb89SAndreas Gohr{ 198213c08e2fSMichael Klier global $conf; 198313c08e2fSMichael Klier 198413c08e2fSMichael Klier // check if convert is configured 198513c08e2fSMichael Klier if (!$conf['im_convert']) return false; 198613c08e2fSMichael Klier 198713c08e2fSMichael Klier // prepare command 198813c08e2fSMichael Klier $cmd = $conf['im_convert']; 198913c08e2fSMichael Klier $cmd .= ' -resize ' . $to_w . 'x' . $to_h . '!'; 199013c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 199113c08e2fSMichael Klier $cmd .= ' -quality ' . $conf['jpg_quality']; 199213c08e2fSMichael Klier } 199313c08e2fSMichael Klier $cmd .= " $from $to"; 199413c08e2fSMichael Klier 199513c08e2fSMichael Klier @exec($cmd, $out, $retval); 199613c08e2fSMichael Klier if ($retval == 0) return true; 199713c08e2fSMichael Klier return false; 199813c08e2fSMichael Klier} 199913c08e2fSMichael Klier 200013c08e2fSMichael Klier/** 200113c08e2fSMichael Klier * crop images using external ImageMagick convert program 200213c08e2fSMichael Klier * 200313c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 200442ea7f44SGerrit Uitslag * 200542ea7f44SGerrit Uitslag * @param string $ext extension 200642ea7f44SGerrit Uitslag * @param string $from filename path to file 200742ea7f44SGerrit Uitslag * @param int $from_w original width 200842ea7f44SGerrit Uitslag * @param int $from_h original height 200942ea7f44SGerrit Uitslag * @param string $to path to resized file 201042ea7f44SGerrit Uitslag * @param int $to_w desired width 201142ea7f44SGerrit Uitslag * @param int $to_h desired height 201242ea7f44SGerrit Uitslag * @param int $ofs_x offset of crop centre 201342ea7f44SGerrit Uitslag * @param int $ofs_y offset of crop centre 201442ea7f44SGerrit Uitslag * @return bool 2015d2bd34a5SAndreas Gohr * @deprecated 2020-09-01 201613c08e2fSMichael Klier */ 2017d868eb89SAndreas Gohrfunction media_crop_imageIM($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x, $ofs_y) 2018d868eb89SAndreas Gohr{ 201913c08e2fSMichael Klier global $conf; 2020d2bd34a5SAndreas Gohr dbg_deprecated('splitbrain\\Slika'); 202113c08e2fSMichael Klier 202213c08e2fSMichael Klier // check if convert is configured 202313c08e2fSMichael Klier if (!$conf['im_convert']) return false; 202413c08e2fSMichael Klier 202513c08e2fSMichael Klier // prepare command 202613c08e2fSMichael Klier $cmd = $conf['im_convert']; 202713c08e2fSMichael Klier $cmd .= ' -crop ' . $to_w . 'x' . $to_h . '+' . $ofs_x . '+' . $ofs_y; 202813c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 202913c08e2fSMichael Klier $cmd .= ' -quality ' . $conf['jpg_quality']; 203013c08e2fSMichael Klier } 203113c08e2fSMichael Klier $cmd .= " $from $to"; 203213c08e2fSMichael Klier 203313c08e2fSMichael Klier @exec($cmd, $out, $retval); 203413c08e2fSMichael Klier if ($retval == 0) return true; 203513c08e2fSMichael Klier return false; 203613c08e2fSMichael Klier} 203713c08e2fSMichael Klier 203813c08e2fSMichael Klier/** 203913c08e2fSMichael Klier * resize or crop images using PHP's libGD support 204013c08e2fSMichael Klier * 204113c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 204213c08e2fSMichael Klier * @author Sebastian Wienecke <s_wienecke@web.de> 204342ea7f44SGerrit Uitslag * 204442ea7f44SGerrit Uitslag * @param string $ext extension 204542ea7f44SGerrit Uitslag * @param string $from filename path to file 204642ea7f44SGerrit Uitslag * @param int $from_w original width 204742ea7f44SGerrit Uitslag * @param int $from_h original height 204842ea7f44SGerrit Uitslag * @param string $to path to resized file 204942ea7f44SGerrit Uitslag * @param int $to_w desired width 205042ea7f44SGerrit Uitslag * @param int $to_h desired height 205142ea7f44SGerrit Uitslag * @param int $ofs_x offset of crop centre 205242ea7f44SGerrit Uitslag * @param int $ofs_y offset of crop centre 205342ea7f44SGerrit Uitslag * @return bool 2054d2bd34a5SAndreas Gohr * @deprecated 2020-09-01 205513c08e2fSMichael Klier */ 2056d868eb89SAndreas Gohrfunction media_resize_imageGD($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x = 0, $ofs_y = 0) 2057d868eb89SAndreas Gohr{ 205813c08e2fSMichael Klier global $conf; 2059d2bd34a5SAndreas Gohr dbg_deprecated('splitbrain\\Slika'); 206013c08e2fSMichael Klier 206113c08e2fSMichael Klier if ($conf['gdlib'] < 1) return false; //no GDlib available or wanted 206213c08e2fSMichael Klier 206313c08e2fSMichael Klier // check available memory 206413c08e2fSMichael Klier if (!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))) { 206513c08e2fSMichael Klier return false; 206613c08e2fSMichael Klier } 206713c08e2fSMichael Klier 206813c08e2fSMichael Klier // create an image of the given filetype 206959bc3b48SGerrit Uitslag $image = false; 207013c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 207113c08e2fSMichael Klier if (!function_exists("imagecreatefromjpeg")) return false; 207213c08e2fSMichael Klier $image = @imagecreatefromjpeg($from); 207313c08e2fSMichael Klier } elseif ($ext == 'png') { 207413c08e2fSMichael Klier if (!function_exists("imagecreatefrompng")) return false; 207513c08e2fSMichael Klier $image = @imagecreatefrompng($from); 207613c08e2fSMichael Klier } elseif ($ext == 'gif') { 207713c08e2fSMichael Klier if (!function_exists("imagecreatefromgif")) return false; 207813c08e2fSMichael Klier $image = @imagecreatefromgif($from); 207913c08e2fSMichael Klier } 208013c08e2fSMichael Klier if (!$image) return false; 208113c08e2fSMichael Klier 208259bc3b48SGerrit Uitslag $newimg = false; 208313c08e2fSMichael Klier if (($conf['gdlib'] > 1) && function_exists("imagecreatetruecolor") && $ext != 'gif') { 208413c08e2fSMichael Klier $newimg = @imagecreatetruecolor($to_w, $to_h); 208513c08e2fSMichael Klier } 208613c08e2fSMichael Klier if (!$newimg) $newimg = @imagecreate($to_w, $to_h); 208713c08e2fSMichael Klier if (!$newimg) { 208813c08e2fSMichael Klier imagedestroy($image); 208913c08e2fSMichael Klier return false; 209013c08e2fSMichael Klier } 209113c08e2fSMichael Klier 209213c08e2fSMichael Klier //keep png alpha channel if possible 209313c08e2fSMichael Klier if ($ext == 'png' && $conf['gdlib'] > 1 && function_exists('imagesavealpha')) { 209413c08e2fSMichael Klier imagealphablending($newimg, false); 209513c08e2fSMichael Klier imagesavealpha($newimg, true); 209613c08e2fSMichael Klier } 209713c08e2fSMichael Klier 209813c08e2fSMichael Klier //keep gif transparent color if possible 209913c08e2fSMichael Klier if ($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { 210013c08e2fSMichael Klier if (function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { 210113c08e2fSMichael Klier $transcolorindex = @imagecolortransparent($image); 210213c08e2fSMichael Klier if ($transcolorindex >= 0) { //transparent color exists 210313c08e2fSMichael Klier $transcolor = @imagecolorsforindex($image, $transcolorindex); 210464159a61SAndreas Gohr $transcolorindex = @imagecolorallocate( 210564159a61SAndreas Gohr $newimg, 210664159a61SAndreas Gohr $transcolor['red'], 210764159a61SAndreas Gohr $transcolor['green'], 210864159a61SAndreas Gohr $transcolor['blue'] 210964159a61SAndreas Gohr ); 211013c08e2fSMichael Klier @imagefill($newimg, 0, 0, $transcolorindex); 211113c08e2fSMichael Klier @imagecolortransparent($newimg, $transcolorindex); 211213c08e2fSMichael Klier } else { //filling with white 211313c08e2fSMichael Klier $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 211413c08e2fSMichael Klier @imagefill($newimg, 0, 0, $whitecolorindex); 211513c08e2fSMichael Klier } 211613c08e2fSMichael Klier } else { //filling with white 211713c08e2fSMichael Klier $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 211813c08e2fSMichael Klier @imagefill($newimg, 0, 0, $whitecolorindex); 211913c08e2fSMichael Klier } 212013c08e2fSMichael Klier } 212113c08e2fSMichael Klier 212213c08e2fSMichael Klier //try resampling first 212313c08e2fSMichael Klier if (function_exists("imagecopyresampled")) { 212413c08e2fSMichael Klier if (!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { 212513c08e2fSMichael Klier imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 212613c08e2fSMichael Klier } 212713c08e2fSMichael Klier } else { 212813c08e2fSMichael Klier imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 212913c08e2fSMichael Klier } 213013c08e2fSMichael Klier 213113c08e2fSMichael Klier $okay = false; 213213c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 213313c08e2fSMichael Klier if (!function_exists('imagejpeg')) { 213413c08e2fSMichael Klier $okay = false; 213513c08e2fSMichael Klier } else { 213613c08e2fSMichael Klier $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); 213713c08e2fSMichael Klier } 213813c08e2fSMichael Klier } elseif ($ext == 'png') { 213913c08e2fSMichael Klier if (!function_exists('imagepng')) { 214013c08e2fSMichael Klier $okay = false; 214113c08e2fSMichael Klier } else { 214213c08e2fSMichael Klier $okay = imagepng($newimg, $to); 214313c08e2fSMichael Klier } 214413c08e2fSMichael Klier } elseif ($ext == 'gif') { 214513c08e2fSMichael Klier if (!function_exists('imagegif')) { 214613c08e2fSMichael Klier $okay = false; 214713c08e2fSMichael Klier } else { 214813c08e2fSMichael Klier $okay = imagegif($newimg, $to); 214913c08e2fSMichael Klier } 215013c08e2fSMichael Klier } 215113c08e2fSMichael Klier 215279a2d784SGerrit Uitslag // destroy GD image resources 215379a2d784SGerrit Uitslag imagedestroy($image); 215479a2d784SGerrit Uitslag imagedestroy($newimg); 215513c08e2fSMichael Klier 215613c08e2fSMichael Klier return $okay; 215713c08e2fSMichael Klier} 215813c08e2fSMichael Klier 21593d7a9e0aSAnika Henke/** 21603d7a9e0aSAnika Henke * Return other media files with the same base name 216179e53fe5SAnika Henke * but different extensions. 21623d7a9e0aSAnika Henke * 21633d7a9e0aSAnika Henke * @param string $src - ID of media file 216442ea7f44SGerrit Uitslag * @param string[] $exts - alternative extensions to find other files for 216542ea7f44SGerrit Uitslag * @return array - array(mime type => file ID) 21663d7a9e0aSAnika Henke * 21673d7a9e0aSAnika Henke * @author Anika Henke <anika@selfthinker.org> 21683d7a9e0aSAnika Henke */ 2169d868eb89SAndreas Gohrfunction media_alternativefiles($src, $exts) 2170d868eb89SAndreas Gohr{ 21713d7a9e0aSAnika Henke 217224870174SAndreas Gohr $files = []; 2173a19c9aa0SGerrit Uitslag [$srcExt, /* srcMime */] = mimetype($src); 21743d7a9e0aSAnika Henke $filebase = substr($src, 0, -1 * (strlen($srcExt) + 1)); 21753d7a9e0aSAnika Henke 21763d7a9e0aSAnika Henke foreach ($exts as $ext) { 21773d7a9e0aSAnika Henke $fileid = $filebase . '.' . $ext; 21783d7a9e0aSAnika Henke $file = mediaFN($fileid); 21793d7a9e0aSAnika Henke if (file_exists($file)) { 2180a19c9aa0SGerrit Uitslag [/* fileExt */, $fileMime] = mimetype($file); 218179e53fe5SAnika Henke $files[$fileMime] = $fileid; 218299f943f6SAnika Henke } 21833d7a9e0aSAnika Henke } 21843d7a9e0aSAnika Henke return $files; 21853d7a9e0aSAnika Henke} 21863d7a9e0aSAnika Henke 2187f50634f0SAnika Henke/** 2188f50634f0SAnika Henke * Check if video/audio is supported to be embedded. 2189f50634f0SAnika Henke * 2190b83a74f1SAnika Henke * @param string $mime - mimetype of media file 219142ea7f44SGerrit Uitslag * @param string $type - type of media files to check ('video', 'audio', or null for all) 2192f50634f0SAnika Henke * @return boolean 2193f50634f0SAnika Henke * 2194f50634f0SAnika Henke * @author Anika Henke <anika@selfthinker.org> 2195f50634f0SAnika Henke */ 2196ed823bcdSAndreas Gohrfunction media_supportedav($mime, $type = null) 2197d868eb89SAndreas Gohr{ 219824870174SAndreas Gohr $supportedAudio = [ 2199f50634f0SAnika Henke 'ogg' => 'audio/ogg', 2200f50634f0SAnika Henke 'mp3' => 'audio/mpeg', 220124870174SAndreas Gohr 'wav' => 'audio/wav' 220224870174SAndreas Gohr ]; 220324870174SAndreas Gohr $supportedVideo = [ 2204f50634f0SAnika Henke 'webm' => 'video/webm', 2205f50634f0SAnika Henke 'ogv' => 'video/ogg', 220624870174SAndreas Gohr 'mp4' => 'video/mp4' 220724870174SAndreas Gohr ]; 2208f50634f0SAnika Henke if ($type == 'audio') { 2209f50634f0SAnika Henke $supportedAv = $supportedAudio; 2210f50634f0SAnika Henke } elseif ($type == 'video') { 2211f50634f0SAnika Henke $supportedAv = $supportedVideo; 2212f50634f0SAnika Henke } else { 2213f50634f0SAnika Henke $supportedAv = array_merge($supportedAudio, $supportedVideo); 2214f50634f0SAnika Henke } 2215f50634f0SAnika Henke return in_array($mime, $supportedAv); 2216f50634f0SAnika Henke} 2217f50634f0SAnika Henke 22180877a1f1SSchplurtz le Déboulonné/** 22190877a1f1SSchplurtz le Déboulonné * Return track media files with the same base name 22200877a1f1SSchplurtz le Déboulonné * but extensions that indicate kind and lang. 22210877a1f1SSchplurtz le Déboulonné * ie for foo.webm search foo.sub.lang.vtt, foo.cap.lang.vtt... 22220877a1f1SSchplurtz le Déboulonné * 22230877a1f1SSchplurtz le Déboulonné * @param string $src - ID of media file 222401299338SSchplurtz le Déboulonné * @return array - array(mediaID => array( kind, srclang )) 22250877a1f1SSchplurtz le Déboulonné * 22260877a1f1SSchplurtz le Déboulonné * @author Schplurtz le Déboulonné <Schplurtz@laposte.net> 22270877a1f1SSchplurtz le Déboulonné */ 2228d868eb89SAndreas Gohrfunction media_trackfiles($src) 2229d868eb89SAndreas Gohr{ 223024870174SAndreas Gohr $kinds = [ 22310877a1f1SSchplurtz le Déboulonné 'sub' => 'subtitles', 22320877a1f1SSchplurtz le Déboulonné 'cap' => 'captions', 22330877a1f1SSchplurtz le Déboulonné 'des' => 'descriptions', 22340877a1f1SSchplurtz le Déboulonné 'cha' => 'chapters', 22350877a1f1SSchplurtz le Déboulonné 'met' => 'metadata' 223624870174SAndreas Gohr ]; 22370877a1f1SSchplurtz le Déboulonné 223824870174SAndreas Gohr $files = []; 22390877a1f1SSchplurtz le Déboulonné $re = '/\\.(sub|cap|des|cha|met)\\.([^.]+)\\.vtt$/'; 22400877a1f1SSchplurtz le Déboulonné $baseid = pathinfo($src, PATHINFO_FILENAME); 22410877a1f1SSchplurtz le Déboulonné $pattern = mediaFN($baseid) . '.*.*.vtt'; 22420877a1f1SSchplurtz le Déboulonné $list = glob($pattern); 22430877a1f1SSchplurtz le Déboulonné foreach ($list as $track) { 22440877a1f1SSchplurtz le Déboulonné if (preg_match($re, $track, $matches)) { 224524870174SAndreas Gohr $files[$baseid . '.' . $matches[1] . '.' . $matches[2] . '.vtt'] = [$kinds[$matches[1]], $matches[2]]; 22460877a1f1SSchplurtz le Déboulonné } 22470877a1f1SSchplurtz le Déboulonné } 22480877a1f1SSchplurtz le Déboulonné return $files; 22490877a1f1SSchplurtz le Déboulonné} 22500877a1f1SSchplurtz le Déboulonné 2251365be586SAndreas Gohr/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 2252