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; 15b021f0b4SAndreas Gohruse dokuwiki\Extension\Event; 16*dd9e8e5eSAndreas Gohruse dokuwiki\File\MediaFile; 17b021f0b4SAndreas Gohruse dokuwiki\Form\Form; 185a8d6e48SMichael Großeuse dokuwiki\HTTP\DokuHTTPClient; 1979a2d784SGerrit Uitslaguse dokuwiki\Logger; 20704a815fSMichael Großeuse dokuwiki\Subscriptions\MediaSubscriptionSender; 21*dd9e8e5eSAndreas Gohruse dokuwiki\Ui\Media\Display; 2279a2d784SGerrit Uitslaguse dokuwiki\Ui\Media\DisplayRow; 2379a2d784SGerrit Uitslaguse dokuwiki\Ui\Media\DisplayTile; 2479a2d784SGerrit Uitslaguse dokuwiki\Ui\MediaDiff; 2579a2d784SGerrit Uitslaguse dokuwiki\Utf8\PhpString; 262d85e841SAndreas Gohruse dokuwiki\Utf8\Sort; 2779a2d784SGerrit Uitslaguse splitbrain\slika\Slika; 280c3a5702SAndreas Gohr 293df72098SAndreas Gohr/** 303df72098SAndreas Gohr * Lists pages which currently use a media file selected for deletion 313df72098SAndreas Gohr * 323df72098SAndreas Gohr * References uses the same visual as search results and share 333df72098SAndreas Gohr * their CSS tags except pagenames won't be links. 343df72098SAndreas Gohr * 353df72098SAndreas Gohr * @author Matthias Grimm <matthiasgrimm@users.sourceforge.net> 3642ea7f44SGerrit Uitslag * 3742ea7f44SGerrit Uitslag * @param array $data 3842ea7f44SGerrit Uitslag * @param string $id 393df72098SAndreas Gohr */ 40d868eb89SAndreas Gohrfunction media_filesinuse($data, $id) 41d868eb89SAndreas Gohr{ 423df72098SAndreas Gohr global $lang; 433df72098SAndreas Gohr echo '<h1>' . $lang['reference'] . ' <code>' . hsc(noNS($id)) . '</code></h1>'; 443df72098SAndreas Gohr echo '<p>' . hsc($lang['ref_inuse']) . '</p>'; 453df72098SAndreas Gohr 463df72098SAndreas Gohr $hidden = 0; //count of hits without read permission 473df72098SAndreas Gohr foreach ($data as $row) { 48a05e297aSAndreas Gohr if (auth_quickaclcheck($row) >= AUTH_READ && isVisiblePage($row)) { 493df72098SAndreas Gohr echo '<div class="search_result">'; 50a05e297aSAndreas Gohr echo '<span class="mediaref_ref">' . hsc($row) . '</span>'; 513df72098SAndreas Gohr echo '</div>'; 52177d6836SAndreas Gohr } else $hidden++; 533df72098SAndreas Gohr } 543df72098SAndreas Gohr if ($hidden) { 5526dfc232SAndreas Gohr echo '<div class="mediaref_hidden">' . $lang['ref_hidden'] . '</div>'; 563df72098SAndreas Gohr } 573df72098SAndreas Gohr} 583df72098SAndreas Gohr 593df72098SAndreas Gohr/** 603df72098SAndreas Gohr * Handles the saving of image meta data 613df72098SAndreas Gohr * 623df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 63cf832786SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 64e0c26282SGerrit Uitslag * 65e0c26282SGerrit Uitslag * @param string $id media id 66e0c26282SGerrit Uitslag * @param int $auth permission level 67e0c26282SGerrit Uitslag * @param array $data 6842ea7f44SGerrit Uitslag * @return false|string 693df72098SAndreas Gohr */ 70d868eb89SAndreas Gohrfunction media_metasave($id, $auth, $data) 71d868eb89SAndreas Gohr{ 723df72098SAndreas Gohr if ($auth < AUTH_UPLOAD) return false; 73f2ea8432SAndreas Gohr if (!checkSecurityToken()) return false; 743df72098SAndreas Gohr global $lang; 750b308644SOtto Vainio global $conf; 763df72098SAndreas Gohr $src = mediaFN($id); 773df72098SAndreas Gohr 783df72098SAndreas Gohr $meta = new JpegMeta($src); 793df72098SAndreas Gohr $meta->_parseAll(); 803df72098SAndreas Gohr 813df72098SAndreas Gohr foreach ($data as $key => $val) { 823df72098SAndreas Gohr $val = trim($val); 833df72098SAndreas Gohr if (empty($val)) { 843df72098SAndreas Gohr $meta->deleteField($key); 853df72098SAndreas Gohr } else { 863df72098SAndreas Gohr $meta->setField($key, $val); 873df72098SAndreas Gohr } 883df72098SAndreas Gohr } 893df72098SAndreas Gohr 90cf832786SKate Arzamastseva $old = @filemtime($src); 9179e79377SAndreas Gohr if (!file_exists(mediaFN($id, $old)) && file_exists($src)) { 92cf832786SKate Arzamastseva // add old revision to the attic 93cf832786SKate Arzamastseva media_saveOldRevision($id); 94cf832786SKate Arzamastseva } 95ac3ed4afSGerrit Uitslag $filesize_old = filesize($src); 963df72098SAndreas Gohr if ($meta->save()) { 970b308644SOtto Vainio if ($conf['fperm']) chmod($src, $conf['fperm']); 98ac3ed4afSGerrit Uitslag @clearstatcache(true, $src); 99cf832786SKate Arzamastseva $new = @filemtime($src); 100ac3ed4afSGerrit Uitslag $filesize_new = filesize($src); 101ac3ed4afSGerrit Uitslag $sizechange = $filesize_new - $filesize_old; 102ac3ed4afSGerrit Uitslag 103cf832786SKate Arzamastseva // add a log entry to the media changelog 104ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, $lang['media_meta_edited'], '', null, $sizechange); 105cf832786SKate Arzamastseva 1063df72098SAndreas Gohr msg($lang['metasaveok'], 1); 1073df72098SAndreas Gohr return $id; 1083df72098SAndreas Gohr } else { 1093df72098SAndreas Gohr msg($lang['metasaveerr'], -1); 1103df72098SAndreas Gohr return false; 1113df72098SAndreas Gohr } 1123df72098SAndreas Gohr} 1133df72098SAndreas Gohr 1143df72098SAndreas Gohr/** 115d54f7963SKlap-in * check if a media is external source 116d54f7963SKlap-in * 117d54f7963SKlap-in * @author Gerrit Uitslag <klapinklapin@gmail.com> 11842ea7f44SGerrit Uitslag * 119d54f7963SKlap-in * @param string $id the media ID or URL 120d54f7963SKlap-in * @return bool 121d54f7963SKlap-in */ 122d868eb89SAndreas Gohrfunction media_isexternal($id) 123d868eb89SAndreas Gohr{ 124fe578fe9SElan Ruusamäe if (preg_match('#^(?:https?|ftp)://#i', $id)) return true; 125d54f7963SKlap-in return false; 126d54f7963SKlap-in} 127d54f7963SKlap-in 128d54f7963SKlap-in/** 129add8678fSAndreas Gohr * Check if a media item is public (eg, external URL or readable by @ALL) 130add8678fSAndreas Gohr * 131add8678fSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 13242ea7f44SGerrit Uitslag * 133add8678fSAndreas Gohr * @param string $id the media ID or URL 134add8678fSAndreas Gohr * @return bool 135add8678fSAndreas Gohr */ 136d868eb89SAndreas Gohrfunction media_ispublic($id) 137d868eb89SAndreas Gohr{ 138d54f7963SKlap-in if (media_isexternal($id)) return true; 139add8678fSAndreas Gohr $id = cleanID($id); 14024870174SAndreas Gohr if (auth_aclcheck(getNS($id) . ':*', '', []) >= AUTH_READ) return true; 141add8678fSAndreas Gohr return false; 142add8678fSAndreas Gohr} 143add8678fSAndreas Gohr 144add8678fSAndreas Gohr/** 1453df72098SAndreas Gohr * Display the form to edit image meta data 1463df72098SAndreas Gohr * 1473df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 148d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 149e0c26282SGerrit Uitslag * 150e0c26282SGerrit Uitslag * @param string $id media id 151e0c26282SGerrit Uitslag * @param int $auth permission level 152e0c26282SGerrit Uitslag * @return bool 1533df72098SAndreas Gohr */ 154d868eb89SAndreas Gohrfunction media_metaform($id, $auth) 155d868eb89SAndreas Gohr{ 156ebc28e69SAndreas Gohr global $lang; 1573df72098SAndreas Gohr 15888a71175SKate Arzamastseva if ($auth < AUTH_UPLOAD) { 159b960c74fSSatoshi Sahara echo '<div class="nothing">' . $lang['media_perm_upload'] . '</div>' . DOKU_LF; 16088a71175SKate Arzamastseva return false; 16188a71175SKate Arzamastseva } 16288a71175SKate Arzamastseva 1633df72098SAndreas Gohr // load the field descriptions 1643df72098SAndreas Gohr static $fields = null; 165b960c74fSSatoshi Sahara if ($fields === null) { 1663e98e685SKate Arzamastseva $config_files = getConfigFiles('mediameta'); 1673e98e685SKate Arzamastseva foreach ($config_files as $config_file) { 16879e79377SAndreas Gohr if (file_exists($config_file)) include($config_file); 1693df72098SAndreas Gohr } 1703df72098SAndreas Gohr } 1713df72098SAndreas Gohr 1723df72098SAndreas Gohr $src = mediaFN($id); 1733df72098SAndreas Gohr 1743df72098SAndreas Gohr // output 175b960c74fSSatoshi Sahara $form = new Form([ 176b960c74fSSatoshi Sahara 'action' => media_managerURL(['tab_details' => 'view'], '&'), 177b960c74fSSatoshi Sahara 'class' => 'meta' 178b960c74fSSatoshi Sahara ]); 179b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 180b960c74fSSatoshi Sahara $form->setHiddenField('img', $id); 181b960c74fSSatoshi Sahara $form->setHiddenField('mediado', 'save'); 1823df72098SAndreas Gohr foreach ($fields as $key => $field) { 1833df72098SAndreas Gohr // get current value 1843e98e685SKate Arzamastseva if (empty($field[0])) continue; 18524870174SAndreas Gohr $tags = [$field[0]]; 1865cefb623SEduardo Mozart de Oliveira if (isset($field[3]) && is_array($field[3])) $tags = array_merge($tags, $field[3]); 1873df72098SAndreas Gohr $value = tpl_img_getTag($tags, '', $src); 188ca6a0701SAndreas Gohr $value = cleanText($value); 1893df72098SAndreas Gohr 1903df72098SAndreas Gohr // prepare attributes 19124870174SAndreas Gohr $p = [ 192b960c74fSSatoshi Sahara 'class' => 'edit', 193b960c74fSSatoshi Sahara 'id' => 'meta__' . $key, 19424870174SAndreas Gohr 'name' => 'meta[' . $field[0] . ']' 19524870174SAndreas Gohr ]; 1963df72098SAndreas Gohr 197b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('row'); 1983df72098SAndreas Gohr if ($field[2] == 'text') { 199bde2a644SSatoshi Sahara $form->addTextInput( 20064159a61SAndreas Gohr $p['name'], 20179a2d784SGerrit Uitslag ($lang[$field[1]] ?: $field[1] . ':') 202b960c74fSSatoshi Sahara )->id($p['id'])->addClass($p['class'])->val($value); 2033df72098SAndreas Gohr } else { 204b960c74fSSatoshi Sahara $form->addTextarea($p['name'], $lang[$field[1]])->id($p['id']) 205b960c74fSSatoshi Sahara ->val(formText($value)) 206b960c74fSSatoshi Sahara ->addClass($p['class']) 207b960c74fSSatoshi Sahara ->attr('rows', '6')->attr('cols', '50'); 2083df72098SAndreas Gohr } 209b960c74fSSatoshi Sahara $form->addTagClose('div'); 2103df72098SAndreas Gohr } 211b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('buttons'); 212b960c74fSSatoshi Sahara $form->addButton('mediado[save]', $lang['btn_save'])->attr('type', 'submit') 213b960c74fSSatoshi Sahara ->attrs(['accesskey' => 's']); 214b960c74fSSatoshi Sahara $form->addTagClose('div'); 215ebc28e69SAndreas Gohr 216b960c74fSSatoshi Sahara $form->addTagClose('div'); 217b960c74fSSatoshi Sahara echo $form->toHTML(); 218ebc28e69SAndreas Gohr return true; 2193df72098SAndreas Gohr} 2203df72098SAndreas Gohr 221666cdec5SMichael Klier/** 22287229c84SAdrian Lang * Convenience function to check if a media file is still in use 223666cdec5SMichael Klier * 224666cdec5SMichael Klier * @author Michael Klier <chi@chimeric.de> 225e0c26282SGerrit Uitslag * 226e0c26282SGerrit Uitslag * @param string $id media id 227e0c26282SGerrit Uitslag * @return array|bool 228666cdec5SMichael Klier */ 229d868eb89SAndreas Gohrfunction media_inuse($id) 230d868eb89SAndreas Gohr{ 231666cdec5SMichael Klier global $conf; 232ebc28e69SAndreas Gohr 233666cdec5SMichael Klier if ($conf['refcheck']) { 234ffec1009SMichael Hamann $mediareferences = ft_mediause($id, true); 23524870174SAndreas Gohr if ($mediareferences === []) { 2366dae2464SAndreas Gohr return false; 237666cdec5SMichael Klier } else { 238666cdec5SMichael Klier return $mediareferences; 239666cdec5SMichael Klier } 240666cdec5SMichael Klier } else { 241666cdec5SMichael Klier return false; 242666cdec5SMichael Klier } 243666cdec5SMichael Klier} 244a05e297aSAndreas Gohr 2453df72098SAndreas Gohr/** 2463df72098SAndreas Gohr * Handles media file deletions 2473df72098SAndreas Gohr * 2483df72098SAndreas Gohr * If configured, checks for media references before deletion 2493df72098SAndreas Gohr * 2503df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 25142ea7f44SGerrit Uitslag * 252ebc28e69SAndreas Gohr * @param string $id media id 25322db8df7SAndreas Gohr * @param int $auth no longer used 25487229c84SAdrian Lang * @return int One of: 0, 25563703ba5SAndreas Gohr * DOKU_MEDIA_DELETED, 25663703ba5SAndreas Gohr * DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS, 25763703ba5SAndreas Gohr * DOKU_MEDIA_NOT_AUTH, 25863703ba5SAndreas Gohr * DOKU_MEDIA_INUSE 2593df72098SAndreas Gohr */ 260d868eb89SAndreas Gohrfunction media_delete($id, $auth) 261d868eb89SAndreas Gohr{ 2626183fb05SKate Arzamastseva global $lang; 263ff04e8b7SAndreas Gohr $auth = auth_quickaclcheck(ltrim(getNS($id) . ':*', ':')); 26487229c84SAdrian Lang if ($auth < AUTH_DELETE) return DOKU_MEDIA_NOT_AUTH; 26587229c84SAdrian Lang if (media_inuse($id)) return DOKU_MEDIA_INUSE; 2663df72098SAndreas Gohr 2673df72098SAndreas Gohr $file = mediaFN($id); 2684a961e72SMichal Kolodziejski 2694a961e72SMichal Kolodziejski // trigger an event - MEDIA_DELETE_FILE 27024870174SAndreas Gohr $data = []; 271666cdec5SMichael Klier $data['id'] = $id; 27279a2d784SGerrit Uitslag $data['name'] = PhpString::basename($file); 2734a961e72SMichal Kolodziejski $data['path'] = $file; 27479e79377SAndreas Gohr $data['size'] = (file_exists($file)) ? filesize($file) : 0; 275666cdec5SMichael Klier 276666cdec5SMichael Klier $data['unl'] = false; 277666cdec5SMichael Klier $data['del'] = false; 278e1d9dcc8SAndreas Gohr $evt = new Event('MEDIA_DELETE_FILE', $data); 2794a961e72SMichal Kolodziejski if ($evt->advise_before()) { 2806183fb05SKate Arzamastseva $old = @filemtime($file); 28179e79377SAndreas Gohr if (!file_exists(mediaFN($id, $old)) && file_exists($file)) { 2826183fb05SKate Arzamastseva // add old revision to the attic 2836183fb05SKate Arzamastseva media_saveOldRevision($id); 2846183fb05SKate Arzamastseva } 2856183fb05SKate Arzamastseva 286666cdec5SMichael Klier $data['unl'] = @unlink($file); 287666cdec5SMichael Klier if ($data['unl']) { 288ac3ed4afSGerrit Uitslag $sizechange = 0 - $data['size']; 289ac3ed4afSGerrit Uitslag addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE, $lang['deleted'], '', null, $sizechange); 290ac3ed4afSGerrit Uitslag 291666cdec5SMichael Klier $data['del'] = io_sweepNS($id, 'mediadir'); 2923df72098SAndreas Gohr } 2934a961e72SMichal Kolodziejski } 2944a961e72SMichal Kolodziejski $evt->advise_after(); 2954a961e72SMichal Kolodziejski unset($evt); 2964a961e72SMichal Kolodziejski 297666cdec5SMichael Klier if ($data['unl'] && $data['del']) { 29887229c84SAdrian Lang return DOKU_MEDIA_DELETED | DOKU_MEDIA_EMPTY_NS; 2993df72098SAndreas Gohr } 3003df72098SAndreas Gohr 30187229c84SAdrian Lang return $data['unl'] ? DOKU_MEDIA_DELETED : 0; 3023df72098SAndreas Gohr} 3033df72098SAndreas Gohr 3043df72098SAndreas Gohr/** 3052d6cc64fSKate Arzamastseva * Handle file uploads via XMLHttpRequest 3062d6cc64fSKate Arzamastseva * 307ebc28e69SAndreas Gohr * @param string $ns target namespace 308ebc28e69SAndreas Gohr * @param int $auth current auth check result 30942ea7f44SGerrit Uitslag * @return false|string false on error, id of the new file on success 3102d6cc64fSKate Arzamastseva */ 311d868eb89SAndreas Gohrfunction media_upload_xhr($ns, $auth) 312d868eb89SAndreas Gohr{ 313da45d883SKate Arzamastseva if (!checkSecurityToken()) return false; 3148108113cSTom N Harris global $INPUT; 315da45d883SKate Arzamastseva 3168108113cSTom N Harris $id = $INPUT->get->str('qqfile'); 31724870174SAndreas Gohr [$ext, $mime] = mimetype($id); 3182d6cc64fSKate Arzamastseva $input = fopen("php://input", "r"); 3192d6cc64fSKate Arzamastseva if (!($tmp = io_mktmpdir())) return false; 32062231793SKate Arzamastseva $path = $tmp . '/' . md5($id); 3212d6cc64fSKate Arzamastseva $target = fopen($path, "w"); 322063fb5b5SAndreas Gohr $realSize = stream_copy_to_stream($input, $target); 3232d6cc64fSKate Arzamastseva fclose($target); 324063fb5b5SAndreas Gohr fclose($input); 3252b9be456SAndreas Gohr if ($INPUT->server->has('CONTENT_LENGTH') && ($realSize != $INPUT->server->int('CONTENT_LENGTH'))) { 326063fb5b5SAndreas Gohr unlink($path); 327063fb5b5SAndreas Gohr return false; 328063fb5b5SAndreas Gohr } 329063fb5b5SAndreas Gohr 3302d6cc64fSKate Arzamastseva $res = media_save( 33124870174SAndreas Gohr ['name' => $path, 'mime' => $mime, 'ext' => $ext], 3322d6cc64fSKate Arzamastseva $ns . ':' . $id, 33379a2d784SGerrit Uitslag ($INPUT->get->str('ow') == 'true'), 3342d6cc64fSKate Arzamastseva $auth, 3352d6cc64fSKate Arzamastseva 'copy' 3362d6cc64fSKate Arzamastseva ); 3372d6cc64fSKate Arzamastseva unlink($path); 338900a9e9eSGerrit Uitslag if ($tmp) io_rmdir($tmp, true); 3392d6cc64fSKate Arzamastseva if (is_array($res)) { 3402d6cc64fSKate Arzamastseva msg($res[0], $res[1]); 3412d6cc64fSKate Arzamastseva return false; 3422d6cc64fSKate Arzamastseva } 3432d6cc64fSKate Arzamastseva return $res; 3442d6cc64fSKate Arzamastseva} 3452d6cc64fSKate Arzamastseva 3462d6cc64fSKate Arzamastseva/** 3473df72098SAndreas Gohr * Handles media file uploads 3483df72098SAndreas Gohr * 3493df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 35011d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 35142ea7f44SGerrit Uitslag * 352ebc28e69SAndreas Gohr * @param string $ns target namespace 353ebc28e69SAndreas Gohr * @param int $auth current auth check result 354ebc28e69SAndreas Gohr * @param bool|array $file $_FILES member, $_FILES['upload'] if false 35542ea7f44SGerrit Uitslag * @return false|string false on error, id of the new file on success 3563df72098SAndreas Gohr */ 357d868eb89SAndreas Gohrfunction media_upload($ns, $auth, $file = false) 358d868eb89SAndreas Gohr{ 359f2ea8432SAndreas Gohr if (!checkSecurityToken()) return false; 3603df72098SAndreas Gohr global $lang; 3618108113cSTom N Harris global $INPUT; 3623df72098SAndreas Gohr 36344409c3dSAndreas Gohr // get file and id 3648108113cSTom N Harris $id = $INPUT->post->str('mediaid'); 3652d6cc64fSKate Arzamastseva if (!$file) $file = $_FILES['upload']; 3663df72098SAndreas Gohr if (empty($id)) $id = $file['name']; 36744409c3dSAndreas Gohr 36899766eefSAndreas Gohr // check for errors (messages are done in lib/exe/mediamanager.php) 36999766eefSAndreas Gohr if ($file['error']) return false; 3709676dc23SAndreas Gohr 37144409c3dSAndreas Gohr // check extensions 37224870174SAndreas Gohr [$fext, $fmime] = mimetype($file['name']); 37324870174SAndreas Gohr [$iext, $imime] = mimetype($id); 37444409c3dSAndreas Gohr if ($fext && !$iext) { 3758cb1eb01SAndreas Gohr // no extension specified in id - read original one 37644409c3dSAndreas Gohr $id .= '.' . $fext; 3778cb1eb01SAndreas Gohr $imime = $fmime; 37844409c3dSAndreas Gohr } elseif ($fext && $fext != $iext) { 37944409c3dSAndreas Gohr // extension was changed, print warning 38044409c3dSAndreas Gohr msg(sprintf($lang['mediaextchange'], $fext, $iext)); 38144409c3dSAndreas Gohr } 38244409c3dSAndreas Gohr 38324870174SAndreas Gohr $res = media_save( 38424870174SAndreas Gohr [ 38524870174SAndreas Gohr 'name' => $file['tmp_name'], 386ffb291f2SAdrian Lang 'mime' => $imime, 38724870174SAndreas Gohr 'ext' => $iext 38824870174SAndreas Gohr ], 38924870174SAndreas Gohr $ns . ':' . $id, 39024870174SAndreas Gohr $INPUT->post->bool('ow'), 39124870174SAndreas Gohr $auth, 39224870174SAndreas Gohr 'copy_uploaded_file' 39324870174SAndreas Gohr ); 394ffb291f2SAdrian Lang if (is_array($res)) { 395ffb291f2SAdrian Lang msg($res[0], $res[1]); 396ffb291f2SAdrian Lang return false; 397ffb291f2SAdrian Lang } 398ffb291f2SAdrian Lang return $res; 399ffb291f2SAdrian Lang} 400ffb291f2SAdrian Lang 401ffb291f2SAdrian Lang/** 40271f17ac4SAndreas Gohr * An alternative to move_uploaded_file that copies 40371f17ac4SAndreas Gohr * 40471f17ac4SAndreas Gohr * Using copy, makes sure any setgid bits on the media directory are honored 40571f17ac4SAndreas Gohr * 40671f17ac4SAndreas Gohr * @see move_uploaded_file() 40742ea7f44SGerrit Uitslag * 40871f17ac4SAndreas Gohr * @param string $from 40971f17ac4SAndreas Gohr * @param string $to 41071f17ac4SAndreas Gohr * @return bool 41171f17ac4SAndreas Gohr */ 412d868eb89SAndreas Gohrfunction copy_uploaded_file($from, $to) 413d868eb89SAndreas Gohr{ 41471f17ac4SAndreas Gohr if (!is_uploaded_file($from)) return false; 41571f17ac4SAndreas Gohr $ok = copy($from, $to); 41671f17ac4SAndreas Gohr @unlink($from); 41771f17ac4SAndreas Gohr return $ok; 41871f17ac4SAndreas Gohr} 41971f17ac4SAndreas Gohr 42071f17ac4SAndreas Gohr/** 421ffb291f2SAdrian Lang * This generates an action event and delegates to _media_upload_action(). 422ffb291f2SAdrian Lang * Action plugins are allowed to pre/postprocess the uploaded file. 423ffb291f2SAdrian Lang * (The triggered event is preventable.) 424ffb291f2SAdrian Lang * 425ffb291f2SAdrian Lang * Event data: 426ffb291f2SAdrian Lang * $data[0] fn_tmp: the temporary file name (read from $_FILES) 427ffb291f2SAdrian Lang * $data[1] fn: the file name of the uploaded file 428ffb291f2SAdrian Lang * $data[2] id: the future directory id of the uploaded file 429ffb291f2SAdrian Lang * $data[3] imime: the mimetype of the uploaded file 430ffb291f2SAdrian Lang * $data[4] overwrite: if an existing file is going to be overwritten 43152a281e8SGerrit Uitslag * $data[5] move: name of function that performs move/copy/.. 432ffb291f2SAdrian Lang * 433ffb291f2SAdrian Lang * @triggers MEDIA_UPLOAD_FINISH 43442ea7f44SGerrit Uitslag * 435e0c26282SGerrit Uitslag * @param array $file 43652a281e8SGerrit Uitslag * @param string $id media id 43742ea7f44SGerrit Uitslag * @param bool $ow overwrite? 438e0c26282SGerrit Uitslag * @param int $auth permission level 43952a281e8SGerrit Uitslag * @param string $move name of functions that performs move/copy/.. 44042ea7f44SGerrit Uitslag * @return false|array|string 441e0c26282SGerrit Uitslag */ 442d868eb89SAndreas Gohrfunction media_save($file, $id, $ow, $auth, $move) 443d868eb89SAndreas Gohr{ 444ffb291f2SAdrian Lang if ($auth < AUTH_UPLOAD) { 44524870174SAndreas Gohr return ["You don't have permissions to upload files.", -1]; 446ffb291f2SAdrian Lang } 447ffb291f2SAdrian Lang 448ffb291f2SAdrian Lang if (!isset($file['mime']) || !isset($file['ext'])) { 44924870174SAndreas Gohr [$ext, $mime] = mimetype($id); 450ffb291f2SAdrian Lang if (!isset($file['mime'])) { 451ffb291f2SAdrian Lang $file['mime'] = $mime; 452ffb291f2SAdrian Lang } 453ffb291f2SAdrian Lang if (!isset($file['ext'])) { 454ffb291f2SAdrian Lang $file['ext'] = $ext; 455ffb291f2SAdrian Lang } 456ffb291f2SAdrian Lang } 457ffb291f2SAdrian Lang 45892cac9a9SKate Arzamastseva global $lang, $conf; 459ffb291f2SAdrian Lang 4603df72098SAndreas Gohr // get filename 4613543c6deSAndreas Gohr $id = cleanID($id); 4623df72098SAndreas Gohr $fn = mediaFN($id); 4633df72098SAndreas Gohr 4643df72098SAndreas Gohr // get filetype regexp 4653df72098SAndreas Gohr $types = array_keys(getMimeTypes()); 466bad6fc0dSAndreas Gohr $types = array_map( 46724870174SAndreas Gohr static fn($q) => preg_quote($q, "/"), 468bad6fc0dSAndreas Gohr $types 469bad6fc0dSAndreas Gohr ); 47024870174SAndreas Gohr $regex = implode('|', $types); 4713df72098SAndreas Gohr 4723df72098SAndreas Gohr // because a temp file was created already 473ffb291f2SAdrian Lang if (!preg_match('/\.(' . $regex . ')$/i', $fn)) { 47424870174SAndreas Gohr return [$lang['uploadwrong'], -1]; 475ffb291f2SAdrian Lang } 476ffb291f2SAdrian Lang 4773df72098SAndreas Gohr //check for overwrite 47879e79377SAndreas Gohr $overwrite = file_exists($fn); 479e5d185e1SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 480e5d185e1SKate Arzamastseva if ($overwrite && (!$ow || $auth < $auth_ow)) { 48124870174SAndreas Gohr return [$lang['uploadexist'], 0]; 4823df72098SAndreas Gohr } 4838cb1eb01SAndreas Gohr // check for valid content 484ffb291f2SAdrian Lang $ok = media_contentcheck($file['name'], $file['mime']); 4858cb1eb01SAndreas Gohr if ($ok == -1) { 48624870174SAndreas Gohr return [sprintf($lang['uploadbadcontent'], '.' . $file['ext']), -1]; 4878cb1eb01SAndreas Gohr } elseif ($ok == -2) { 48824870174SAndreas Gohr return [$lang['uploadspam'], -1]; 48926ceae18SAndreas Gohr } elseif ($ok == -3) { 49024870174SAndreas Gohr return [$lang['uploadxss'], -1]; 4918cb1eb01SAndreas Gohr } 4928cb1eb01SAndreas Gohr 49311d9dfa5SMichael Klier // prepare event data 49424870174SAndreas Gohr $data = []; 495ffb291f2SAdrian Lang $data[0] = $file['name']; 49611d9dfa5SMichael Klier $data[1] = $fn; 49711d9dfa5SMichael Klier $data[2] = $id; 498ffb291f2SAdrian Lang $data[3] = $file['mime']; 49999c8d7f2Smichael $data[4] = $overwrite; 500ffb291f2SAdrian Lang $data[5] = $move; 50111d9dfa5SMichael Klier 50211d9dfa5SMichael Klier // trigger event 503cbb44eabSAndreas Gohr return Event::createAndTrigger('MEDIA_UPLOAD_FINISH', $data, '_media_upload_action', true); 50411d9dfa5SMichael Klier} 50511d9dfa5SMichael Klier 50611d9dfa5SMichael Klier/** 50742ea7f44SGerrit Uitslag * Callback adapter for media_upload_finish() triggered by MEDIA_UPLOAD_FINISH 50842ea7f44SGerrit Uitslag * 50911d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 51042ea7f44SGerrit Uitslag * 51142ea7f44SGerrit Uitslag * @param array $data event data 51242ea7f44SGerrit Uitslag * @return false|array|string 51311d9dfa5SMichael Klier */ 514d868eb89SAndreas Gohrfunction _media_upload_action($data) 515d868eb89SAndreas Gohr{ 51611d9dfa5SMichael Klier // fixme do further sanity tests of given data? 517ffb291f2SAdrian Lang if (is_array($data) && count($data) === 6) { 518ffb291f2SAdrian Lang return media_upload_finish($data[0], $data[1], $data[2], $data[3], $data[4], $data[5]); 51911d9dfa5SMichael Klier } else { 52011d9dfa5SMichael Klier return false; //callback error 52111d9dfa5SMichael Klier } 52211d9dfa5SMichael Klier} 52311d9dfa5SMichael Klier 52411d9dfa5SMichael Klier/** 52511d9dfa5SMichael Klier * Saves an uploaded media file 52611d9dfa5SMichael Klier * 52711d9dfa5SMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 52811d9dfa5SMichael Klier * @author Michael Klier <chi@chimeric.de> 529cbe26ad6SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 53042ea7f44SGerrit Uitslag * 53142ea7f44SGerrit Uitslag * @param string $fn_tmp 53242ea7f44SGerrit Uitslag * @param string $fn 53342ea7f44SGerrit Uitslag * @param string $id media id 53442ea7f44SGerrit Uitslag * @param string $imime mime type 53542ea7f44SGerrit Uitslag * @param bool $overwrite overwrite existing? 53642ea7f44SGerrit Uitslag * @param string $move function name 53742ea7f44SGerrit Uitslag * @return array|string 53811d9dfa5SMichael Klier */ 539d868eb89SAndreas Gohrfunction media_upload_finish($fn_tmp, $fn, $id, $imime, $overwrite, $move = 'move_uploaded_file') 540d868eb89SAndreas Gohr{ 54111d9dfa5SMichael Klier global $conf; 54211d9dfa5SMichael Klier global $lang; 5439c1bd4bcSKate Arzamastseva global $REV; 54411d9dfa5SMichael Klier 545e4f389efSKate Arzamastseva $old = @filemtime($fn); 54679e79377SAndreas Gohr if (!file_exists(mediaFN($id, $old)) && file_exists($fn)) { 547e4f389efSKate Arzamastseva // add old revision to the attic if missing 548cbe26ad6SKate Arzamastseva media_saveOldRevision($id); 549e4f389efSKate Arzamastseva } 550e4f389efSKate Arzamastseva 5513df72098SAndreas Gohr // prepare directory 552cc7d0c94SBen Coburn io_createNamespace($id, 'media'); 55311d9dfa5SMichael Klier 554ac3ed4afSGerrit Uitslag $filesize_old = file_exists($fn) ? filesize($fn) : 0; 555ac3ed4afSGerrit Uitslag 556ffb291f2SAdrian Lang if ($move($fn_tmp, $fn)) { 55723846a98SKate Arzamastseva @clearstatcache(true, $fn); 558dad6764eSKate Arzamastseva $new = @filemtime($fn); 55974400ea5SBen Coburn // Set the correct permission here. 56074400ea5SBen Coburn // Always chmod media because they may be saved with different permissions than expected from the php umask. 56174400ea5SBen Coburn // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 56274400ea5SBen Coburn chmod($fn, $conf['fmode']); 5633df72098SAndreas Gohr msg($lang['uploadsucc'], 1); 56483734cddSPhy media_notify($id, $fn, $imime, $old, $new); 56599c8d7f2Smichael // add a log entry to the media changelog 566ac3ed4afSGerrit Uitslag $filesize_new = filesize($fn); 567ac3ed4afSGerrit Uitslag $sizechange = $filesize_new - $filesize_old; 5689c1bd4bcSKate Arzamastseva if ($REV) { 56964159a61SAndreas Gohr addMediaLogEntry( 57064159a61SAndreas Gohr $new, 57164159a61SAndreas Gohr $id, 57264159a61SAndreas Gohr DOKU_CHANGE_TYPE_REVERT, 57364159a61SAndreas Gohr sprintf($lang['restored'], dformat($REV)), 57464159a61SAndreas Gohr $REV, 57564159a61SAndreas Gohr null, 57664159a61SAndreas Gohr $sizechange 57764159a61SAndreas Gohr ); 5789c1bd4bcSKate Arzamastseva } elseif ($overwrite) { 579ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); 58099c8d7f2Smichael } else { 581ac3ed4afSGerrit Uitslag addMediaLogEntry($new, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); 58299c8d7f2Smichael } 5833df72098SAndreas Gohr return $id; 5843df72098SAndreas Gohr } else { 58524870174SAndreas Gohr return [$lang['uploadfail'], -1]; 5863df72098SAndreas Gohr } 5873df72098SAndreas Gohr} 5883df72098SAndreas Gohr 5898cb1eb01SAndreas Gohr/** 590cbe26ad6SKate Arzamastseva * Moves the current version of media file to the media_attic 591cbe26ad6SKate Arzamastseva * directory 592cbe26ad6SKate Arzamastseva * 593cbe26ad6SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 59442ea7f44SGerrit Uitslag * 595cbe26ad6SKate Arzamastseva * @param string $id 596cbe26ad6SKate Arzamastseva * @return int - revision date 597e4f389efSKate Arzamastseva */ 598d868eb89SAndreas Gohrfunction media_saveOldRevision($id) 599d868eb89SAndreas Gohr{ 600dbf57c96SKate Arzamastseva global $conf, $lang; 601dbf57c96SKate Arzamastseva 602e4f389efSKate Arzamastseva $oldf = mediaFN($id); 60379e79377SAndreas Gohr if (!file_exists($oldf)) return ''; 604e4f389efSKate Arzamastseva $date = filemtime($oldf); 605e5d185e1SKate Arzamastseva if (!$conf['mediarevisions']) return $date; 606e5d185e1SKate Arzamastseva 607047bad06SGerrit Uitslag $medialog = new MediaChangeLog($id); 608047bad06SGerrit Uitslag if (!$medialog->getRevisionInfo($date)) { 609dbf57c96SKate Arzamastseva // there was an external edit, 610dbf57c96SKate Arzamastseva // there is no log entry for current version of file 611ac3ed4afSGerrit Uitslag $sizechange = filesize($oldf); 61279e79377SAndreas Gohr if (!file_exists(mediaMetaFN($id, '.changes'))) { 613ac3ed4afSGerrit Uitslag addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_CREATE, $lang['created'], '', null, $sizechange); 614dbf57c96SKate Arzamastseva } else { 615ac3ed4afSGerrit Uitslag $oldRev = $medialog->getRevisions(-1, 1); // from changelog 616ac3ed4afSGerrit Uitslag $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]); 617ac3ed4afSGerrit Uitslag $filesize_old = filesize(mediaFN($id, $oldRev)); 61824870174SAndreas Gohr $sizechange -= $filesize_old; 619ac3ed4afSGerrit Uitslag 620ac3ed4afSGerrit Uitslag addMediaLogEntry($date, $id, DOKU_CHANGE_TYPE_EDIT, '', '', null, $sizechange); 621dbf57c96SKate Arzamastseva } 622dbf57c96SKate Arzamastseva } 623dbf57c96SKate Arzamastseva 624e4f389efSKate Arzamastseva $newf = mediaFN($id, $date); 625e4f389efSKate Arzamastseva io_makeFileDir($newf); 626cbe26ad6SKate Arzamastseva if (copy($oldf, $newf)) { 627e4f389efSKate Arzamastseva // Set the correct permission here. 628e4f389efSKate Arzamastseva // Always chmod media because they may be saved with different permissions than expected from the php umask. 629e4f389efSKate Arzamastseva // (Should normally chmod to $conf['fperm'] only if $conf['fperm'] is set.) 630e4f389efSKate Arzamastseva chmod($newf, $conf['fmode']); 631e4f389efSKate Arzamastseva } 632e4f389efSKate Arzamastseva return $date; 633e4f389efSKate Arzamastseva} 634e4f389efSKate Arzamastseva 635e4f389efSKate Arzamastseva/** 6368cb1eb01SAndreas Gohr * This function checks if the uploaded content is really what the 63726ceae18SAndreas Gohr * mimetype says it is. We also do spam checking for text types here. 6388cb1eb01SAndreas Gohr * 6398cb1eb01SAndreas Gohr * We need to do this stuff because we can not rely on the browser 6408cb1eb01SAndreas Gohr * to do this check correctly. Yes, IE is broken as usual. 6418cb1eb01SAndreas Gohr * 6428cb1eb01SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 64326ceae18SAndreas Gohr * @link http://www.splitbrain.org/blog/2007-02/12-internet_explorer_facilitates_cross_site_scripting 6448cb1eb01SAndreas Gohr * @fixme check all 26 magic IE filetypes here? 64542ea7f44SGerrit Uitslag * 64642ea7f44SGerrit Uitslag * @param string $file path to file 64742ea7f44SGerrit Uitslag * @param string $mime mimetype 64842ea7f44SGerrit Uitslag * @return int 6498cb1eb01SAndreas Gohr */ 650d868eb89SAndreas Gohrfunction media_contentcheck($file, $mime) 651d868eb89SAndreas Gohr{ 65226ceae18SAndreas Gohr global $conf; 65326ceae18SAndreas Gohr if ($conf['iexssprotect']) { 65426ceae18SAndreas Gohr $fh = @fopen($file, 'rb'); 65526ceae18SAndreas Gohr if ($fh) { 65626ceae18SAndreas Gohr $bytes = fread($fh, 256); 65726ceae18SAndreas Gohr fclose($fh); 65826ceae18SAndreas Gohr if (preg_match('/<(script|a|img|html|body|iframe)[\s>]/i', $bytes)) { 65942ea7f44SGerrit Uitslag return -3; //XSS: possibly malicious content 66026ceae18SAndreas Gohr } 66126ceae18SAndreas Gohr } 66226ceae18SAndreas Gohr } 6636c16a3a9Sfiwswe if (str_starts_with($mime, 'image/')) { 6648cb1eb01SAndreas Gohr $info = @getimagesize($file); 6658cb1eb01SAndreas Gohr if ($mime == 'image/gif' && $info[2] != 1) { 66642ea7f44SGerrit Uitslag return -1; // uploaded content did not match the file extension 6678cb1eb01SAndreas Gohr } elseif ($mime == 'image/jpeg' && $info[2] != 2) { 6688cb1eb01SAndreas Gohr return -1; 6698cb1eb01SAndreas Gohr } elseif ($mime == 'image/png' && $info[2] != 3) { 6708cb1eb01SAndreas Gohr return -1; 6718cb1eb01SAndreas Gohr } 6728cb1eb01SAndreas Gohr # fixme maybe check other images types as well 6736c16a3a9Sfiwswe } elseif (str_starts_with($mime, 'text/')) { 6748cb1eb01SAndreas Gohr global $TEXT; 6758cb1eb01SAndreas Gohr $TEXT = io_readFile($file); 6768cb1eb01SAndreas Gohr if (checkwordblock()) { 67742ea7f44SGerrit Uitslag return -2; //blocked by the spam blacklist 6788cb1eb01SAndreas Gohr } 6798cb1eb01SAndreas Gohr } 6808cb1eb01SAndreas Gohr return 0; 6818cb1eb01SAndreas Gohr} 6823df72098SAndreas Gohr 6833df72098SAndreas Gohr/** 68475030359SAndreas Gohr * Send a notify mail on uploads 68575030359SAndreas Gohr * 68675030359SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 68742ea7f44SGerrit Uitslag * 68842ea7f44SGerrit Uitslag * @param string $id media id 68942ea7f44SGerrit Uitslag * @param string $file path to file 69042ea7f44SGerrit Uitslag * @param string $mime mime type 69142ea7f44SGerrit Uitslag * @param bool|int $old_rev revision timestamp or false 69275030359SAndreas Gohr */ 693d868eb89SAndreas Gohrfunction media_notify($id, $file, $mime, $old_rev = false, $current_rev = false) 694d868eb89SAndreas Gohr{ 69575030359SAndreas Gohr global $conf; 69679a2d784SGerrit Uitslag if (empty($conf['notify'])) return; //notify enabled? 69775030359SAndreas Gohr 698704a815fSMichael Große $subscription = new MediaSubscriptionSender(); 69979a2d784SGerrit Uitslag $subscription->sendMediaDiff($conf['notify'], 'uploadmail', $id, $old_rev, $current_rev); 70075030359SAndreas Gohr} 70175030359SAndreas Gohr 70275030359SAndreas Gohr/** 7033df72098SAndreas Gohr * List all files in a given Media namespace 70442ea7f44SGerrit Uitslag * 70521d806cdSGerrit Uitslag * @param string $ns namespace 70642ea7f44SGerrit Uitslag * @param null|int $auth permission level 70742ea7f44SGerrit Uitslag * @param string $jump id 70842ea7f44SGerrit Uitslag * @param bool $fullscreenview 7098702de7fSGerrit Uitslag * @param bool|string $sort sorting order, false skips sorting 7103df72098SAndreas Gohr */ 711d868eb89SAndreas Gohrfunction media_filelist($ns, $auth = null, $jump = '', $fullscreenview = false, $sort = false) 712d868eb89SAndreas Gohr{ 7133df72098SAndreas Gohr global $conf; 7143df72098SAndreas Gohr global $lang; 7153df72098SAndreas Gohr $ns = cleanID($ns); 7163df72098SAndreas Gohr 7173df72098SAndreas Gohr // check auth our self if not given (needed for ajax calls) 7183df72098SAndreas Gohr if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 7193df72098SAndreas Gohr 720d9162c6cSKate Arzamastseva if (!$fullscreenview) echo '<h1 id="media__ns">:' . hsc($ns) . '</h1>' . NL; 7213df72098SAndreas Gohr 7223df72098SAndreas Gohr if ($auth < AUTH_READ) { 7233df72098SAndreas Gohr // FIXME: print permission warning here instead? 7243df72098SAndreas Gohr echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; 72556fe6664SAndreas Gohr } else { 72689274c0dSChristopher Smith if (!$fullscreenview) { 72789274c0dSChristopher Smith media_uploadform($ns, $auth); 72889274c0dSChristopher Smith media_searchform($ns); 72989274c0dSChristopher Smith } 7303df72098SAndreas Gohr 7313df72098SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $ns)); 73224870174SAndreas Gohr $data = []; 733dccd6b2bSAndreas Gohr search( 734dccd6b2bSAndreas Gohr $data, 735dccd6b2bSAndreas Gohr $conf['mediadir'], 736dccd6b2bSAndreas Gohr 'search_mediafiles', 737dccd6b2bSAndreas Gohr ['showmsg' => true, 'depth' => 1], 738dccd6b2bSAndreas Gohr $dir, 739dccd6b2bSAndreas Gohr 1, 740dccd6b2bSAndreas Gohr $sort 741dccd6b2bSAndreas Gohr ); 7423df72098SAndreas Gohr 743093fe67eSAndreas Gohr if ($data === []) { 7443df72098SAndreas Gohr echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; 7455b9353faSKate Arzamastseva } else { 7465b9353faSKate Arzamastseva if ($fullscreenview) { 747554a8c9fSAdrian Lang echo '<ul class="' . _media_get_list_type() . '">'; 7485b9353faSKate Arzamastseva } 7495b9353faSKate Arzamastseva foreach ($data as $item) { 7505b9353faSKate Arzamastseva if (!$fullscreenview) { 7514f33babfSAndreas Gohr //FIXME old call: media_printfile($item,$auth,$jump); 75279a2d784SGerrit Uitslag $display = new DisplayRow($item); 7539453716dSAndreas Gohr $display->scrollIntoView($jump == $item->getID()); 7544f33babfSAndreas Gohr $display->show(); 7555b9353faSKate Arzamastseva } else { 7564f33babfSAndreas Gohr //FIXME old call: media_printfile_thumbs($item,$auth,$jump); 7574f33babfSAndreas Gohr echo '<li>'; 75879a2d784SGerrit Uitslag $display = new DisplayTile($item); 7599453716dSAndreas Gohr $display->scrollIntoView($jump == $item->getID()); 7604f33babfSAndreas Gohr $display->show(); 7614f33babfSAndreas Gohr echo '</li>'; 7625b9353faSKate Arzamastseva } 7635b9353faSKate Arzamastseva } 76494add303SAnika Henke if ($fullscreenview) echo '</ul>' . NL; 7653df72098SAndreas Gohr } 76656fe6664SAndreas Gohr } 767d9162c6cSKate Arzamastseva} 768d9162c6cSKate Arzamastseva 769d9162c6cSKate Arzamastseva/** 770d9162c6cSKate Arzamastseva * Prints tabs for files list actions 771d9162c6cSKate Arzamastseva * 772d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 77395b451bcSAdrian Lang * @author Adrian Lang <mail@adrianlang.de> 77495b451bcSAdrian Lang * 775035e07f1SKate Arzamastseva * @param string $selected_tab - opened tab 776d9162c6cSKate Arzamastseva */ 77795b451bcSAdrian Lang 778d868eb89SAndreas Gohrfunction media_tabs_files($selected_tab = '') 779d868eb89SAndreas Gohr{ 780d9162c6cSKate Arzamastseva global $lang; 78124870174SAndreas Gohr $tabs = []; 7827d34963bSAndreas Gohr foreach ( 7837d34963bSAndreas Gohr [ 78424870174SAndreas Gohr 'files' => 'mediaselect', 78595b451bcSAdrian Lang 'upload' => 'media_uploadtab', 78624870174SAndreas Gohr 'search' => 'media_searchtab' 7877d34963bSAndreas Gohr ] as $tab => $caption 7887d34963bSAndreas Gohr ) { 78924870174SAndreas Gohr $tabs[$tab] = [ 79024870174SAndreas Gohr 'href' => media_managerURL(['tab_files' => $tab], '&'), 79124870174SAndreas Gohr 'caption' => $lang[$caption] 79224870174SAndreas Gohr ]; 79395b451bcSAdrian Lang } 794d9162c6cSKate Arzamastseva 79595b451bcSAdrian Lang html_tabs($tabs, $selected_tab); 796d9162c6cSKate Arzamastseva} 797d9162c6cSKate Arzamastseva 798d9162c6cSKate Arzamastseva/** 799d9162c6cSKate Arzamastseva * Prints tabs for files details actions 800d9162c6cSKate Arzamastseva * 801d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 802ebc28e69SAndreas Gohr * @param string $image filename of the current image 803ebc28e69SAndreas Gohr * @param string $selected_tab opened tab 804d9162c6cSKate Arzamastseva */ 805d868eb89SAndreas Gohrfunction media_tabs_details($image, $selected_tab = '') 806d868eb89SAndreas Gohr{ 807e5d185e1SKate Arzamastseva global $lang, $conf; 808d9162c6cSKate Arzamastseva 80924870174SAndreas Gohr $tabs = []; 81024870174SAndreas Gohr $tabs['view'] = [ 81124870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'view'], '&'), 81224870174SAndreas Gohr 'caption' => $lang['media_viewtab'] 81324870174SAndreas Gohr ]; 814d9162c6cSKate Arzamastseva 81524870174SAndreas Gohr [, $mime] = mimetype($image); 81679e79377SAndreas Gohr if ($mime == 'image/jpeg' && file_exists(mediaFN($image))) { 81724870174SAndreas Gohr $tabs['edit'] = [ 81824870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'edit'], '&'), 81924870174SAndreas Gohr 'caption' => $lang['media_edittab'] 82024870174SAndreas Gohr ]; 821dd9ba38eSKate Arzamastseva } 822e5d185e1SKate Arzamastseva if ($conf['mediarevisions']) { 82324870174SAndreas Gohr $tabs['history'] = [ 82424870174SAndreas Gohr 'href' => media_managerURL(['tab_details' => 'history'], '&'), 82524870174SAndreas Gohr 'caption' => $lang['media_historytab'] 82624870174SAndreas Gohr ]; 827e5d185e1SKate Arzamastseva } 828d9162c6cSKate Arzamastseva 82995b451bcSAdrian Lang html_tabs($tabs, $selected_tab); 830d9162c6cSKate Arzamastseva} 831d9162c6cSKate Arzamastseva 832d9162c6cSKate Arzamastseva/** 833d9162c6cSKate Arzamastseva * Prints options for the tab that displays a list of all files 834d9162c6cSKate Arzamastseva * 835d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 836d9162c6cSKate Arzamastseva */ 837d868eb89SAndreas Gohrfunction media_tab_files_options() 838d868eb89SAndreas Gohr{ 8398108113cSTom N Harris global $lang; 8408108113cSTom N Harris global $INPUT; 841b7e5821dSAndreas Gohr global $ID; 842b960c74fSSatoshi Sahara 843b960c74fSSatoshi Sahara $form = new Form([ 844b960c74fSSatoshi Sahara 'method' => 'get', 845b960c74fSSatoshi Sahara 'action' => wl($ID), 846b960c74fSSatoshi Sahara 'class' => 'options' 847b960c74fSSatoshi Sahara ]); 848b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 849b960c74fSSatoshi Sahara $form->setHiddenField('sectok', null); 850b960c74fSSatoshi Sahara $media_manager_params = media_managerURL([], '', false, true); 85138b2bf35SAnika Henke foreach ($media_manager_params as $pKey => $pVal) { 852b960c74fSSatoshi Sahara $form->setHiddenField($pKey, $pVal); 85338b2bf35SAnika Henke } 8548108113cSTom N Harris if ($INPUT->has('q')) { 855b960c74fSSatoshi Sahara $form->setHiddenField('q', $INPUT->str('q')); 856554a8c9fSAdrian Lang } 857b960c74fSSatoshi Sahara $form->addHTML('<ul>' . NL); 8587d34963bSAndreas Gohr foreach ( 8597d34963bSAndreas Gohr [ 86024870174SAndreas Gohr 'list' => ['listType', ['thumbs', 'rows']], 86124870174SAndreas Gohr 'sort' => ['sortBy', ['name', 'date']] 8627d34963bSAndreas Gohr ] as $group => $content 8637d34963bSAndreas Gohr ) { 864ec88e837SAndreas Gohr $checked = "_media_get_{$group}_type"; 865554a8c9fSAdrian Lang $checked = $checked(); 866d9162c6cSKate Arzamastseva 867b960c74fSSatoshi Sahara $form->addHTML('<li class="' . $content[0] . '">'); 86895b451bcSAdrian Lang foreach ($content[1] as $option) { 86924870174SAndreas Gohr $attrs = []; 870554a8c9fSAdrian Lang if ($checked == $option) { 87195b451bcSAdrian Lang $attrs['checked'] = 'checked'; 87295b451bcSAdrian Lang } 873b960c74fSSatoshi Sahara $radio = $form->addRadioButton( 874b960c74fSSatoshi Sahara $group . '_dwmedia', 875b960c74fSSatoshi Sahara $lang['media_' . $group . '_' . $option] 876b960c74fSSatoshi Sahara )->val($option)->id($content[0] . '__' . $option)->addClass($option); 877b960c74fSSatoshi Sahara $radio->attrs($attrs); 87895b451bcSAdrian Lang } 879b960c74fSSatoshi Sahara $form->addHTML('</li>' . NL); 88095b451bcSAdrian Lang } 881b960c74fSSatoshi Sahara $form->addHTML('<li>'); 882b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_apply'])->attr('type', 'submit'); 883b960c74fSSatoshi Sahara $form->addHTML('</li>' . NL); 884b960c74fSSatoshi Sahara $form->addHTML('</ul>' . NL); 885b960c74fSSatoshi Sahara $form->addTagClose('div'); 88626dfc232SAndreas Gohr echo $form->toHTML(); 887d9162c6cSKate Arzamastseva} 888d9162c6cSKate Arzamastseva 889d9162c6cSKate Arzamastseva/** 89087deddfaSKate Arzamastseva * Returns type of sorting for the list of files in media manager 89187deddfaSKate Arzamastseva * 89287deddfaSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 89342ea7f44SGerrit Uitslag * 89487deddfaSKate Arzamastseva * @return string - sort type 89587deddfaSKate Arzamastseva */ 896d868eb89SAndreas Gohrfunction _media_get_sort_type() 897d868eb89SAndreas Gohr{ 89824870174SAndreas Gohr return _media_get_display_param('sort', ['default' => 'name', 'date']); 89987deddfaSKate Arzamastseva} 900554a8c9fSAdrian Lang 9016ffaeda9SGerrit Uitslag/** 9026ffaeda9SGerrit Uitslag * Returns type of listing for the list of files in media manager 9036ffaeda9SGerrit Uitslag * 9046ffaeda9SGerrit Uitslag * @author Kate Arzamastseva <pshns@ukr.net> 90542ea7f44SGerrit Uitslag * 9066ffaeda9SGerrit Uitslag * @return string - list type 9076ffaeda9SGerrit Uitslag */ 908d868eb89SAndreas Gohrfunction _media_get_list_type() 909d868eb89SAndreas Gohr{ 91024870174SAndreas Gohr return _media_get_display_param('list', ['default' => 'thumbs', 'rows']); 91187deddfaSKate Arzamastseva} 912554a8c9fSAdrian Lang 9136ffaeda9SGerrit Uitslag/** 9146ffaeda9SGerrit Uitslag * Get display parameters 9156ffaeda9SGerrit Uitslag * 9166ffaeda9SGerrit Uitslag * @param string $param name of parameter 9176ffaeda9SGerrit Uitslag * @param array $values allowed values, where default value has index key 'default' 9186ffaeda9SGerrit Uitslag * @return string the parameter value 9196ffaeda9SGerrit Uitslag */ 920d868eb89SAndreas Gohrfunction _media_get_display_param($param, $values) 921d868eb89SAndreas Gohr{ 9228108113cSTom N Harris global $INPUT; 9238108113cSTom N Harris if (in_array($INPUT->str($param), $values)) { 924554a8c9fSAdrian Lang // FIXME: Set cookie 9258108113cSTom N Harris return $INPUT->str($param); 926554a8c9fSAdrian Lang } else { 9273629bc8cSAdrian Lang $val = get_doku_pref($param, $values['default']); 9283629bc8cSAdrian Lang if (!in_array($val, $values)) { 9293629bc8cSAdrian Lang $val = $values['default']; 9303629bc8cSAdrian Lang } 9313629bc8cSAdrian Lang return $val; 932554a8c9fSAdrian Lang } 93387deddfaSKate Arzamastseva} 93487deddfaSKate Arzamastseva 93587deddfaSKate Arzamastseva/** 936d9162c6cSKate Arzamastseva * Prints tab that displays a list of all files 937d9162c6cSKate Arzamastseva * 938d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 93942ea7f44SGerrit Uitslag * 94042ea7f44SGerrit Uitslag * @param string $ns 94142ea7f44SGerrit Uitslag * @param null|int $auth permission level 94242ea7f44SGerrit Uitslag * @param string $jump item id 943d9162c6cSKate Arzamastseva */ 944d868eb89SAndreas Gohrfunction media_tab_files($ns, $auth = null, $jump = '') 945d868eb89SAndreas Gohr{ 946d9162c6cSKate Arzamastseva global $lang; 947d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 948d9162c6cSKate Arzamastseva 949d9162c6cSKate Arzamastseva if ($auth < AUTH_READ) { 95088a71175SKate Arzamastseva echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; 951d9162c6cSKate Arzamastseva } else { 95295b451bcSAdrian Lang media_filelist($ns, $auth, $jump, true, _media_get_sort_type()); 953d9162c6cSKate Arzamastseva } 954d9162c6cSKate Arzamastseva} 955d9162c6cSKate Arzamastseva 956d9162c6cSKate Arzamastseva/** 957d9162c6cSKate Arzamastseva * Prints tab that displays uploading form 958d9162c6cSKate Arzamastseva * 959d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 96042ea7f44SGerrit Uitslag * 96142ea7f44SGerrit Uitslag * @param string $ns 96242ea7f44SGerrit Uitslag * @param null|int $auth permission level 96342ea7f44SGerrit Uitslag * @param string $jump item id 964d9162c6cSKate Arzamastseva */ 965d868eb89SAndreas Gohrfunction media_tab_upload($ns, $auth = null, $jump = '') 966d868eb89SAndreas Gohr{ 967d9162c6cSKate Arzamastseva global $lang; 968d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 969d9162c6cSKate Arzamastseva 97094add303SAnika Henke echo '<div class="upload">' . NL; 97195b451bcSAdrian Lang if ($auth >= AUTH_UPLOAD) { 97295b451bcSAdrian Lang echo '<p>' . $lang['mediaupload'] . '</p>'; 97395b451bcSAdrian Lang } 974d9162c6cSKate Arzamastseva media_uploadform($ns, $auth, true); 97594add303SAnika Henke echo '</div>' . NL; 976d9162c6cSKate Arzamastseva} 977d9162c6cSKate Arzamastseva 978d9162c6cSKate Arzamastseva/** 979d9162c6cSKate Arzamastseva * Prints tab that displays search form 980d9162c6cSKate Arzamastseva * 981d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 98242ea7f44SGerrit Uitslag * 98342ea7f44SGerrit Uitslag * @param string $ns 98442ea7f44SGerrit Uitslag * @param null|int $auth permission level 985d9162c6cSKate Arzamastseva */ 986d868eb89SAndreas Gohrfunction media_tab_search($ns, $auth = null) 987d868eb89SAndreas Gohr{ 9888108113cSTom N Harris global $INPUT; 989d9162c6cSKate Arzamastseva 9908108113cSTom N Harris $do = $INPUT->str('mediado'); 9918108113cSTom N Harris $query = $INPUT->str('q'); 99294add303SAnika Henke echo '<div class="search">' . NL; 993d9162c6cSKate Arzamastseva 994d9162c6cSKate Arzamastseva media_searchform($ns, $query, true); 9952dba8df4SAdrian Lang if ($do == 'searchlist' || $query) { 99695b451bcSAdrian Lang media_searchlist($query, $ns, $auth, true, _media_get_sort_type()); 99795b451bcSAdrian Lang } 99894add303SAnika Henke echo '</div>' . NL; 999d9162c6cSKate Arzamastseva} 1000d9162c6cSKate Arzamastseva 1001d9162c6cSKate Arzamastseva/** 1002d9162c6cSKate Arzamastseva * Prints tab that displays mediafile details 1003d9162c6cSKate Arzamastseva * 1004d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1005e0c26282SGerrit Uitslag * 1006e0c26282SGerrit Uitslag * @param string $image media id 1007e0c26282SGerrit Uitslag * @param string $ns 1008e0c26282SGerrit Uitslag * @param null|int $auth permission level 100942ea7f44SGerrit Uitslag * @param string|int $rev revision timestamp or empty string 1010d9162c6cSKate Arzamastseva */ 1011d868eb89SAndreas Gohrfunction media_tab_view($image, $ns, $auth = null, $rev = '') 1012d868eb89SAndreas Gohr{ 1013ebc28e69SAndreas Gohr global $lang; 1014d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 1015d9162c6cSKate Arzamastseva 1016e136d6ccSKate Arzamastseva if ($image && $auth >= AUTH_READ) { 1017*dd9e8e5eSAndreas Gohr $mf = new MediaFile($image, $rev); 1018*dd9e8e5eSAndreas Gohr echo (new Display($mf))->getDetailHtml(); 1019e136d6ccSKate Arzamastseva media_preview_buttons($image, $auth, $rev); 1020*dd9e8e5eSAndreas Gohr media_details($image, $auth, $rev, $mf->getMeta()); 1021e136d6ccSKate Arzamastseva } else { 102294add303SAnika Henke echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; 1023e136d6ccSKate Arzamastseva } 1024d9162c6cSKate Arzamastseva} 1025d9162c6cSKate Arzamastseva 1026d9162c6cSKate Arzamastseva/** 1027d9162c6cSKate Arzamastseva * Prints tab that displays form for editing mediafile metadata 1028d9162c6cSKate Arzamastseva * 1029d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1030e0c26282SGerrit Uitslag * 1031e0c26282SGerrit Uitslag * @param string $image media id 1032e0c26282SGerrit Uitslag * @param string $ns 1033e0c26282SGerrit Uitslag * @param null|int $auth permission level 1034d9162c6cSKate Arzamastseva */ 1035d868eb89SAndreas Gohrfunction media_tab_edit($image, $ns, $auth = null) 1036d868eb89SAndreas Gohr{ 1037d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 1038d9162c6cSKate Arzamastseva 10391eeeced2SKate Arzamastseva if ($image) { 104024870174SAndreas Gohr [, $mime] = mimetype($image); 104130fd72fbSKate Arzamastseva if ($mime == 'image/jpeg') media_metaform($image, $auth); 10421eeeced2SKate Arzamastseva } 1043d9162c6cSKate Arzamastseva} 1044d9162c6cSKate Arzamastseva 1045d9162c6cSKate Arzamastseva/** 1046d9162c6cSKate Arzamastseva * Prints tab that displays mediafile revisions 1047d9162c6cSKate Arzamastseva * 1048d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1049e0c26282SGerrit Uitslag * 1050e0c26282SGerrit Uitslag * @param string $image media id 1051e0c26282SGerrit Uitslag * @param string $ns 1052e0c26282SGerrit Uitslag * @param null|int $auth permission level 1053d9162c6cSKate Arzamastseva */ 1054d868eb89SAndreas Gohrfunction media_tab_history($image, $ns, $auth = null) 1055d868eb89SAndreas Gohr{ 1056d9162c6cSKate Arzamastseva global $lang; 10578108113cSTom N Harris global $INPUT; 10588108113cSTom N Harris 1059d9162c6cSKate Arzamastseva if (is_null($auth)) $auth = auth_quickaclcheck("$ns:*"); 10608108113cSTom N Harris $do = $INPUT->str('mediado'); 1061d9162c6cSKate Arzamastseva 10622e55802cSKate Arzamastseva if ($auth >= AUTH_READ && $image) { 10632e55802cSKate Arzamastseva if ($do == 'diff') { 106424870174SAndreas Gohr (new MediaDiff($image))->show(); //media_diff($image, $ns, $auth); 10652e55802cSKate Arzamastseva } else { 1066a46cc3dcSAndreas Gohr $first = $INPUT->int('first', -1); 106724870174SAndreas Gohr (new MediaRevisions($image))->show($first); 10682e55802cSKate Arzamastseva } 106988a71175SKate Arzamastseva } else { 107088a71175SKate Arzamastseva echo '<div class="nothing">' . $lang['media_perm_read'] . '</div>' . NL; 10712e55802cSKate Arzamastseva } 10723df72098SAndreas Gohr} 10733df72098SAndreas Gohr 10743df72098SAndreas Gohr/** 1075e136d6ccSKate Arzamastseva * Prints mediafile action buttons 1076e136d6ccSKate Arzamastseva * 1077e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1078e0c26282SGerrit Uitslag * 1079e0c26282SGerrit Uitslag * @param string $image media id 1080e0c26282SGerrit Uitslag * @param int $auth permission level 1081871895a7SSatoshi Sahara * @param int|string $rev revision timestamp, or empty string 1082e136d6ccSKate Arzamastseva */ 1083d868eb89SAndreas Gohrfunction media_preview_buttons($image, $auth, $rev = '') 1084d868eb89SAndreas Gohr{ 1085e5d185e1SKate Arzamastseva global $lang, $conf; 1086e136d6ccSKate Arzamastseva 1087871895a7SSatoshi Sahara echo '<ul class="actions">'; 10881eeeced2SKate Arzamastseva 108979e79377SAndreas Gohr if ($auth >= AUTH_DELETE && !$rev && file_exists(mediaFN($image))) { 1090e136d6ccSKate Arzamastseva // delete button 1091b960c74fSSatoshi Sahara $form = new Form([ 1092b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_delete', 1093b960c74fSSatoshi Sahara 'action' => media_managerURL(['delete' => $image], '&'), 1094b960c74fSSatoshi Sahara ]); 1095b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1096b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_delete'])->attr('type', 'submit'); 1097b960c74fSSatoshi Sahara $form->addTagClose('div'); 109895b451bcSAdrian Lang echo '<li>'; 1099b960c74fSSatoshi Sahara echo $form->toHTML(); 1100871895a7SSatoshi Sahara echo '</li>'; 1101e5d185e1SKate Arzamastseva } 1102e5d185e1SKate Arzamastseva 1103e5d185e1SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 1104e5d185e1SKate Arzamastseva if ($auth >= $auth_ow && !$rev) { 1105e136d6ccSKate Arzamastseva // upload new version button 1106b960c74fSSatoshi Sahara $form = new Form([ 1107b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_update', 1108b960c74fSSatoshi Sahara 'action' => media_managerURL(['image' => $image, 'mediado' => 'update'], '&'), 1109b960c74fSSatoshi Sahara ]); 1110b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1111b960c74fSSatoshi Sahara $form->addButton('', $lang['media_update'])->attr('type', 'submit'); 1112b960c74fSSatoshi Sahara $form->addTagClose('div'); 111395b451bcSAdrian Lang echo '<li>'; 1114b960c74fSSatoshi Sahara echo $form->toHTML(); 1115871895a7SSatoshi Sahara echo '</li>'; 111670c3cc9aSKate Arzamastseva } 1117e136d6ccSKate Arzamastseva 111879e79377SAndreas Gohr if ($auth >= AUTH_UPLOAD && $rev && $conf['mediarevisions'] && file_exists(mediaFN($image, $rev))) { 1119e136d6ccSKate Arzamastseva // restore button 1120b960c74fSSatoshi Sahara $form = new Form([ 1121b960c74fSSatoshi Sahara 'id' => 'mediamanager__btn_restore', 1122b960c74fSSatoshi Sahara 'action' => media_managerURL(['image' => $image], '&'), 1123b960c74fSSatoshi Sahara ]); 1124b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1125b960c74fSSatoshi Sahara $form->setHiddenField('mediado', 'restore'); 1126b960c74fSSatoshi Sahara $form->setHiddenField('rev', $rev); 1127b960c74fSSatoshi Sahara $form->addButton('', $lang['media_restore'])->attr('type', 'submit'); 1128b960c74fSSatoshi Sahara $form->addTagClose('div'); 112995b451bcSAdrian Lang echo '<li>'; 1130b960c74fSSatoshi Sahara echo $form->toHTML(); 1131871895a7SSatoshi Sahara echo '</li>'; 11329c1bd4bcSKate Arzamastseva } 1133e136d6ccSKate Arzamastseva 1134871895a7SSatoshi Sahara echo '</ul>'; 11352e55802cSKate Arzamastseva} 11362e55802cSKate Arzamastseva 11372e55802cSKate Arzamastseva/** 1138fa8e5c77SKate Arzamastseva * Returns the requested EXIF/IPTC tag from the image meta 1139fa8e5c77SKate Arzamastseva * 1140fa8e5c77SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1141e0c26282SGerrit Uitslag * 114242ea7f44SGerrit Uitslag * @param array $tags array with tags, first existing is returned 1143fa8e5c77SKate Arzamastseva * @param JpegMeta $meta 114442ea7f44SGerrit Uitslag * @param string $alt alternative value 1145fa8e5c77SKate Arzamastseva * @return string 1146fa8e5c77SKate Arzamastseva */ 1147d868eb89SAndreas Gohrfunction media_getTag($tags, $meta = false, $alt = '') 1148d868eb89SAndreas Gohr{ 1149871895a7SSatoshi Sahara if (!$meta) return $alt; 1150fa8e5c77SKate Arzamastseva $info = $meta->getField($tags); 1151871895a7SSatoshi Sahara if (!$info) return $alt; 1152fa8e5c77SKate Arzamastseva return $info; 1153fa8e5c77SKate Arzamastseva} 1154fa8e5c77SKate Arzamastseva 1155fa8e5c77SKate Arzamastseva/** 1156e136d6ccSKate Arzamastseva * Returns mediafile tags 11572e55802cSKate Arzamastseva * 11582e55802cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1159e0c26282SGerrit Uitslag * 1160e136d6ccSKate Arzamastseva * @param JpegMeta $meta 116142ea7f44SGerrit Uitslag * @return array list of tags of the mediafile 11622e55802cSKate Arzamastseva */ 1163d868eb89SAndreas Gohrfunction media_file_tags($meta) 1164d868eb89SAndreas Gohr{ 1165532850edSKate Arzamastseva // load the field descriptions 11663e98e685SKate Arzamastseva static $fields = null; 11673e98e685SKate Arzamastseva if (is_null($fields)) { 11683e98e685SKate Arzamastseva $config_files = getConfigFiles('mediameta'); 11693e98e685SKate Arzamastseva foreach ($config_files as $config_file) { 117079e79377SAndreas Gohr if (file_exists($config_file)) include($config_file); 1171532850edSKate Arzamastseva } 1172532850edSKate Arzamastseva } 11731eeeced2SKate Arzamastseva 117424870174SAndreas Gohr $tags = []; 1175dd9ba38eSKate Arzamastseva 117624870174SAndreas Gohr foreach ($fields as $tag) { 117724870174SAndreas Gohr $t = []; 117824870174SAndreas Gohr if (!empty($tag[0])) $t = [$tag[0]]; 11790e80bb5eSChristopher Smith if (isset($tag[3]) && is_array($tag[3])) $t = array_merge($t, $tag[3]); 1180e136d6ccSKate Arzamastseva $value = media_getTag($t, $meta); 118124870174SAndreas Gohr $tags[] = ['tag' => $tag, 'value' => $value]; 1182e136d6ccSKate Arzamastseva } 1183e136d6ccSKate Arzamastseva 1184e136d6ccSKate Arzamastseva return $tags; 1185e136d6ccSKate Arzamastseva} 1186e136d6ccSKate Arzamastseva 1187e136d6ccSKate Arzamastseva/** 1188e136d6ccSKate Arzamastseva * Prints mediafile tags 1189e136d6ccSKate Arzamastseva * 1190e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 119142ea7f44SGerrit Uitslag * 1192e0c26282SGerrit Uitslag * @param string $image image id 1193e0c26282SGerrit Uitslag * @param int $auth permission level 1194e0c26282SGerrit Uitslag * @param string|int $rev revision timestamp, or empty string 1195e0c26282SGerrit Uitslag * @param bool|JpegMeta $meta image object, or create one if false 1196e0c26282SGerrit Uitslag */ 1197d868eb89SAndreas Gohrfunction media_details($image, $auth, $rev = '', $meta = false) 1198d868eb89SAndreas Gohr{ 1199e136d6ccSKate Arzamastseva global $lang; 1200e136d6ccSKate Arzamastseva 1201e136d6ccSKate Arzamastseva if (!$meta) $meta = new JpegMeta(mediaFN($image, $rev)); 1202e136d6ccSKate Arzamastseva $tags = media_file_tags($meta); 1203e136d6ccSKate Arzamastseva 120494add303SAnika Henke echo '<dl>' . NL; 1205e136d6ccSKate Arzamastseva foreach ($tags as $tag) { 1206e136d6ccSKate Arzamastseva if ($tag['value']) { 1207e136d6ccSKate Arzamastseva $value = cleanText($tag['value']); 1208fde860beSGerrit Uitslag echo '<dt>' . $lang[$tag['tag'][1]] . '</dt><dd>'; 1209e136d6ccSKate Arzamastseva if ($tag['tag'][2] == 'date') echo dformat($value); 12103e98e685SKate Arzamastseva else echo hsc($value); 121194add303SAnika Henke echo '</dd>' . NL; 12121eeeced2SKate Arzamastseva } 1213e136d6ccSKate Arzamastseva } 121494add303SAnika Henke echo '</dl>' . NL; 121522e68399Sflammy echo '<dl>' . NL; 121622e68399Sflammy echo '<dt>' . $lang['reference'] . ':</dt>'; 121722e68399Sflammy $media_usage = ft_mediause($image, true); 121824870174SAndreas Gohr if ($media_usage !== []) { 121922e68399Sflammy foreach ($media_usage as $path) { 122022e68399Sflammy echo '<dd>' . html_wikilink($path) . '</dd>'; 122122e68399Sflammy } 122222e68399Sflammy } else { 122322e68399Sflammy echo '<dd>' . $lang['nothingfound'] . '</dd>'; 122422e68399Sflammy } 122522e68399Sflammy echo '</dl>' . NL; 12261eeeced2SKate Arzamastseva} 12272e55802cSKate Arzamastseva 12282e55802cSKate Arzamastseva/** 12292e55802cSKate Arzamastseva * Shows difference between two revisions of file 12302e55802cSKate Arzamastseva * 12312e55802cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 123242ea7f44SGerrit Uitslag * 1233e0c26282SGerrit Uitslag * @param string $image image id 1234e0c26282SGerrit Uitslag * @param string $ns 1235e0c26282SGerrit Uitslag * @param int $auth permission level 1236e0c26282SGerrit Uitslag * @param bool $fromajax 123779a2d784SGerrit Uitslag * 1238297071beSSatoshi Sahara * @deprecated 2020-12-31 1239e0c26282SGerrit Uitslag */ 1240d868eb89SAndreas Gohrfunction media_diff($image, $ns, $auth, $fromajax = false) 1241d868eb89SAndreas Gohr{ 124279a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::show()'); 124359e81a43SKate Arzamastseva} 124459e81a43SKate Arzamastseva 12456ffaeda9SGerrit Uitslag/** 12466ffaeda9SGerrit Uitslag * Callback for media file diff 12476ffaeda9SGerrit Uitslag * 124842ea7f44SGerrit Uitslag * @param array $data event data 124979a2d784SGerrit Uitslag * 1250297071beSSatoshi Sahara * @deprecated 2020-12-31 12516ffaeda9SGerrit Uitslag */ 1252d868eb89SAndreas Gohrfunction _media_file_diff($data) 1253d868eb89SAndreas Gohr{ 125479a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::show()'); 125559e81a43SKate Arzamastseva} 125659e81a43SKate Arzamastseva 125759e81a43SKate Arzamastseva/** 125859e81a43SKate Arzamastseva * Shows difference between two revisions of image 125959e81a43SKate Arzamastseva * 126059e81a43SKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1261e0c26282SGerrit Uitslag * 1262e0c26282SGerrit Uitslag * @param string $image 1263e0c26282SGerrit Uitslag * @param string|int $l_rev revision timestamp, or empty string 1264e0c26282SGerrit Uitslag * @param string|int $r_rev revision timestamp, or empty string 1265e0c26282SGerrit Uitslag * @param string $ns 1266e0c26282SGerrit Uitslag * @param int $auth permission level 1267e0c26282SGerrit Uitslag * @param bool $fromajax 1268297071beSSatoshi Sahara * @deprecated 2020-12-31 126959e81a43SKate Arzamastseva */ 1270d868eb89SAndreas Gohrfunction media_file_diff($image, $l_rev, $r_rev, $ns, $auth, $fromajax) 1271d868eb89SAndreas Gohr{ 127279a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::showFileDiff()'); 1273e136d6ccSKate Arzamastseva} 1274e136d6ccSKate Arzamastseva 1275e136d6ccSKate Arzamastseva/** 1276e136d6ccSKate Arzamastseva * Prints two images side by side 1277fa8e5c77SKate Arzamastseva * and slider 1278e136d6ccSKate Arzamastseva * 1279e136d6ccSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 128042ea7f44SGerrit Uitslag * 128142ea7f44SGerrit Uitslag * @param string $image image id 1282e0c26282SGerrit Uitslag * @param int $l_rev revision timestamp, or empty string 1283e0c26282SGerrit Uitslag * @param int $r_rev revision timestamp, or empty string 128442ea7f44SGerrit Uitslag * @param array $l_size array with width and height 128542ea7f44SGerrit Uitslag * @param array $r_size array with width and height 128650fc55feSKate Arzamastseva * @param string $type 1287297071beSSatoshi Sahara * @deprecated 2020-12-31 1288e136d6ccSKate Arzamastseva */ 1289d868eb89SAndreas Gohrfunction media_image_diff($image, $l_rev, $r_rev, $l_size, $r_size, $type) 1290d868eb89SAndreas Gohr{ 129179a2d784SGerrit Uitslag dbg_deprecated('see ' . MediaDiff::class . '::showImageDiff()'); 12921eeeced2SKate Arzamastseva} 12931eeeced2SKate Arzamastseva 12941eeeced2SKate Arzamastseva/** 12959c1bd4bcSKate Arzamastseva * Restores an old revision of a media file 12969c1bd4bcSKate Arzamastseva * 129742ea7f44SGerrit Uitslag * @param string $image media id 129842ea7f44SGerrit Uitslag * @param int $rev revision timestamp or empty string 12999c1bd4bcSKate Arzamastseva * @param int $auth 13009c1bd4bcSKate Arzamastseva * @return string - file's id 130142ea7f44SGerrit Uitslag * 13029c1bd4bcSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 13039c1bd4bcSKate Arzamastseva */ 1304d868eb89SAndreas Gohrfunction media_restore($image, $rev, $auth) 1305d868eb89SAndreas Gohr{ 1306e5d185e1SKate Arzamastseva global $conf; 130780525638SKate Arzamastseva if ($auth < AUTH_UPLOAD || !$conf['mediarevisions']) return false; 130892cac9a9SKate Arzamastseva $removed = (!file_exists(mediaFN($image)) && file_exists(mediaMetaFN($image, '.changes'))); 130992cac9a9SKate Arzamastseva if (!$image || (!file_exists(mediaFN($image)) && !$removed)) return false; 13109c1bd4bcSKate Arzamastseva if (!$rev || !file_exists(mediaFN($image, $rev))) return false; 131124870174SAndreas Gohr [, $imime, ] = mimetype($image); 1312dccd6b2bSAndreas Gohr $res = media_upload_finish( 1313dccd6b2bSAndreas Gohr mediaFN($image, $rev), 13149c1bd4bcSKate Arzamastseva mediaFN($image), 13159c1bd4bcSKate Arzamastseva $image, 13169c1bd4bcSKate Arzamastseva $imime, 13179c1bd4bcSKate Arzamastseva true, 1318dccd6b2bSAndreas Gohr 'copy' 1319dccd6b2bSAndreas Gohr ); 13209c1bd4bcSKate Arzamastseva if (is_array($res)) { 13219c1bd4bcSKate Arzamastseva msg($res[0], $res[1]); 13229c1bd4bcSKate Arzamastseva return false; 13239c1bd4bcSKate Arzamastseva } 13249c1bd4bcSKate Arzamastseva return $res; 13259c1bd4bcSKate Arzamastseva} 13269c1bd4bcSKate Arzamastseva 13279c1bd4bcSKate Arzamastseva/** 1328bf1f3ac4Ssarnowski * List all files found by the search request 1329c9f56829SAndreas Gohr * 1330c9f56829SAndreas Gohr * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1331c9f56829SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 1332d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1333c9f56829SAndreas Gohr * @triggers MEDIA_SEARCH 1334e0c26282SGerrit Uitslag * 1335e0c26282SGerrit Uitslag * @param string $query 1336e0c26282SGerrit Uitslag * @param string $ns 1337e0c26282SGerrit Uitslag * @param null|int $auth 1338e0c26282SGerrit Uitslag * @param bool $fullscreen 1339e0c26282SGerrit Uitslag * @param string $sort 1340bf1f3ac4Ssarnowski */ 1341d868eb89SAndreas Gohrfunction media_searchlist($query, $ns, $auth = null, $fullscreen = false, $sort = 'natural') 1342d868eb89SAndreas Gohr{ 1343bf1f3ac4Ssarnowski global $conf; 1344bf1f3ac4Ssarnowski global $lang; 13458e69fd30SKate Arzamastseva 1346bf1f3ac4Ssarnowski $ns = cleanID($ns); 134724870174SAndreas Gohr $evdata = [ 134856fe6664SAndreas Gohr 'ns' => $ns, 134924870174SAndreas Gohr 'data' => [], 135056fe6664SAndreas Gohr 'query' => $query 135124870174SAndreas Gohr ]; 13527ed31746SSzymon Olewniczak if (!blank($query)) { 1353e1d9dcc8SAndreas Gohr $evt = new Event('MEDIA_SEARCH', $evdata); 1354bf1f3ac4Ssarnowski if ($evt->advise_before()) { 135556fe6664SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $evdata['ns'])); 135676472096SSzymon Olewniczak $quoted = preg_quote($evdata['query'], '/'); 135776472096SSzymon Olewniczak //apply globbing 135824870174SAndreas Gohr $quoted = str_replace(['\*', '\?'], ['.*', '.'], $quoted, $count); 135923e31e76SSzymon Olewniczak 136023e31e76SSzymon Olewniczak //if we use globbing file name must match entirely but may be preceded by arbitrary namespace 136123e31e76SSzymon Olewniczak if ($count > 0) $quoted = '^([^:]*:)*' . $quoted . '$'; 136223e31e76SSzymon Olewniczak 136376472096SSzymon Olewniczak $pattern = '/' . $quoted . '/i'; 1364dccd6b2bSAndreas Gohr search( 1365dccd6b2bSAndreas Gohr $evdata['data'], 136656fe6664SAndreas Gohr $conf['mediadir'], 13674f33babfSAndreas Gohr 'search_mediafiles', 136824870174SAndreas Gohr ['showmsg' => false, 'pattern' => $pattern], 136900e3e394SChristopher Smith $dir, 137000e3e394SChristopher Smith 1, 1371dccd6b2bSAndreas Gohr $sort 1372dccd6b2bSAndreas Gohr ); 1373bf1f3ac4Ssarnowski } 1374bf1f3ac4Ssarnowski $evt->advise_after(); 1375bf1f3ac4Ssarnowski unset($evt); 137656fe6664SAndreas Gohr } 1377bf1f3ac4Ssarnowski 1378d9162c6cSKate Arzamastseva if (!$fullscreen) { 137956fe6664SAndreas Gohr echo '<h1 id="media__ns">' . sprintf($lang['searchmedia_in'], hsc($ns) . ':*') . '</h1>' . NL; 138056fe6664SAndreas Gohr media_searchform($ns, $query); 1381d9162c6cSKate Arzamastseva } 138256fe6664SAndreas Gohr 138356fe6664SAndreas Gohr if (!count($evdata['data'])) { 1384bf1f3ac4Ssarnowski echo '<div class="nothing">' . $lang['nothingfound'] . '</div>' . NL; 13855b9353faSKate Arzamastseva } else { 13865b9353faSKate Arzamastseva if ($fullscreen) { 1387554a8c9fSAdrian Lang echo '<ul class="' . _media_get_list_type() . '">'; 13885b9353faSKate Arzamastseva } 13895b9353faSKate Arzamastseva foreach ($evdata['data'] as $item) { 13904f33babfSAndreas Gohr if (!$fullscreen) { 13914f33babfSAndreas Gohr // FIXME old call: media_printfile($item,$item['perm'],'',true); 139279a2d784SGerrit Uitslag $display = new DisplayRow($item); 139379b00823SAndreas Gohr $display->relativeDisplay($ns); 13944f33babfSAndreas Gohr $display->show(); 13954f33babfSAndreas Gohr } else { 13964f33babfSAndreas Gohr // FIXME old call: media_printfile_thumbs($item,$item['perm'],false,true); 139779a2d784SGerrit Uitslag $display = new DisplayTile($item); 139879b00823SAndreas Gohr $display->relativeDisplay($ns); 13994f33babfSAndreas Gohr echo '<li>'; 14004f33babfSAndreas Gohr $display->show(); 14014f33babfSAndreas Gohr echo '</li>'; 14024f33babfSAndreas Gohr } 1403bf1f3ac4Ssarnowski } 140494add303SAnika Henke if ($fullscreen) echo '</ul>' . NL; 14055b9353faSKate Arzamastseva } 1406bf1f3ac4Ssarnowski} 1407bf1f3ac4Ssarnowski 1408bf1f3ac4Ssarnowski/** 1409c6571d58SAndreas Gohr * Display a media icon 1410c6571d58SAndreas Gohr * 141142ea7f44SGerrit Uitslag * @param string $filename media id 1412c6571d58SAndreas Gohr * @param string $size the size subfolder, if not specified 16x16 is used 141342ea7f44SGerrit Uitslag * @return string html 1414c6571d58SAndreas Gohr */ 1415d868eb89SAndreas Gohrfunction media_printicon($filename, $size = '') 1416d868eb89SAndreas Gohr{ 141724870174SAndreas Gohr [$ext] = mimetype(mediaFN($filename), false); 141823786fd7SKate Arzamastseva 141979e79377SAndreas Gohr if (file_exists(DOKU_INC . 'lib/images/fileicons/' . $size . '/' . $ext . '.png')) { 1420c6571d58SAndreas Gohr $icon = DOKU_BASE . 'lib/images/fileicons/' . $size . '/' . $ext . '.png'; 142123786fd7SKate Arzamastseva } else { 1422c6571d58SAndreas Gohr $icon = DOKU_BASE . 'lib/images/fileicons/' . $size . '/file.png'; 142323786fd7SKate Arzamastseva } 142423786fd7SKate Arzamastseva 1425421ec38eSKate Arzamastseva return '<img src="' . $icon . '" alt="' . $filename . '" class="icon" />'; 142623786fd7SKate Arzamastseva} 142723786fd7SKate Arzamastseva 14283df72098SAndreas Gohr/** 142942ea7f44SGerrit Uitslag * Build link based on the current, adding/rewriting parameters 1430d9162c6cSKate Arzamastseva * 1431d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 143242ea7f44SGerrit Uitslag * 1433ebc28e69SAndreas Gohr * @param array|bool $params 143442ea7f44SGerrit Uitslag * @param string $amp separator 143542ea7f44SGerrit Uitslag * @param bool $abs absolute url? 143642ea7f44SGerrit Uitslag * @param bool $params_array return the parmeters array? 143742ea7f44SGerrit Uitslag * @return string|array - link or link parameters 1438d9162c6cSKate Arzamastseva */ 1439d868eb89SAndreas Gohrfunction media_managerURL($params = false, $amp = '&', $abs = false, $params_array = false) 1440d868eb89SAndreas Gohr{ 1441d9162c6cSKate Arzamastseva global $ID; 14428108113cSTom N Harris global $INPUT; 1443d9162c6cSKate Arzamastseva 144424870174SAndreas Gohr $gets = ['do' => 'media']; 144524870174SAndreas Gohr $media_manager_params = ['tab_files', 'tab_details', 'image', 'ns', 'list', 'sort']; 144623846a98SKate Arzamastseva foreach ($media_manager_params as $x) { 14478108113cSTom N Harris if ($INPUT->has($x)) $gets[$x] = $INPUT->str($x); 144823846a98SKate Arzamastseva } 1449d9162c6cSKate Arzamastseva 1450d9162c6cSKate Arzamastseva if ($params) { 1451554a8c9fSAdrian Lang $gets = $params + $gets; 1452d9162c6cSKate Arzamastseva } 1453d9162c6cSKate Arzamastseva unset($gets['id']); 1454554a8c9fSAdrian Lang if (isset($gets['delete'])) { 14551eeeced2SKate Arzamastseva unset($gets['image']); 14561eeeced2SKate Arzamastseva unset($gets['tab_details']); 14571eeeced2SKate Arzamastseva } 1458d9162c6cSKate Arzamastseva 1459035e07f1SKate Arzamastseva if ($params_array) return $gets; 1460035e07f1SKate Arzamastseva 14616dd095f5SKate Arzamastseva return wl($ID, $gets, $abs, $amp); 1462d9162c6cSKate Arzamastseva} 1463d9162c6cSKate Arzamastseva 1464d9162c6cSKate Arzamastseva/** 14653df72098SAndreas Gohr * Print the media upload form if permissions are correct 14663df72098SAndreas Gohr * 14673df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1468d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1469e0c26282SGerrit Uitslag * 1470e0c26282SGerrit Uitslag * @param string $ns 1471e0c26282SGerrit Uitslag * @param int $auth permission level 1472e0c26282SGerrit Uitslag * @param bool $fullscreen 14733df72098SAndreas Gohr */ 1474d868eb89SAndreas Gohrfunction media_uploadform($ns, $auth, $fullscreen = false) 1475d868eb89SAndreas Gohr{ 14768108113cSTom N Harris global $lang; 14778108113cSTom N Harris global $conf; 14788108113cSTom N Harris global $INPUT; 14793df72098SAndreas Gohr 148088a71175SKate Arzamastseva if ($auth < AUTH_UPLOAD) { 148188a71175SKate Arzamastseva echo '<div class="nothing">' . $lang['media_perm_upload'] . '</div>' . NL; 148288a71175SKate Arzamastseva return; 148388a71175SKate Arzamastseva } 148492cac9a9SKate Arzamastseva $auth_ow = (($conf['mediarevisions']) ? AUTH_UPLOAD : AUTH_DELETE); 14853df72098SAndreas Gohr 148670c3cc9aSKate Arzamastseva $update = false; 148770c3cc9aSKate Arzamastseva $id = ''; 14888108113cSTom N Harris if ($auth >= $auth_ow && $fullscreen && $INPUT->str('mediado') == 'update') { 148970c3cc9aSKate Arzamastseva $update = true; 14908108113cSTom N Harris $id = cleanID($INPUT->str('image')); 149170c3cc9aSKate Arzamastseva } 149270c3cc9aSKate Arzamastseva 1493d00ec455SAndreas Gohr // The default HTML upload form 1494b960c74fSSatoshi Sahara $form = new Form([ 1495b960c74fSSatoshi Sahara 'id' => 'dw__upload', 1496b960c74fSSatoshi Sahara 'enctype' => 'multipart/form-data', 1497b960c74fSSatoshi Sahara 'action' => ($fullscreen) 1498b960c74fSSatoshi Sahara ? media_managerURL(['tab_files' => 'files', 'tab_details' => 'view'], '&') 1499b960c74fSSatoshi Sahara : DOKU_BASE . 'lib/exe/mediamanager.php', 1500b960c74fSSatoshi Sahara ]); 1501b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1502b960c74fSSatoshi Sahara $form->setHiddenField('ns', hsc($ns)); // FIXME hsc required? 1503b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1504b960c74fSSatoshi Sahara $form->addTextInput('upload', $lang['txt_upload'])->id('upload__file') 1505b960c74fSSatoshi Sahara ->attrs(['type' => 'file']); 1506b960c74fSSatoshi Sahara $form->addTagClose('p'); 1507b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1508b960c74fSSatoshi Sahara $form->addTextInput('mediaid', $lang['txt_filename'])->id('upload__name') 1509b960c74fSSatoshi Sahara ->val(noNS($id)); 1510b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_upload'])->attr('type', 'submit'); 1511b960c74fSSatoshi Sahara $form->addTagClose('p'); 151292cac9a9SKate Arzamastseva if ($auth >= $auth_ow) { 1513b960c74fSSatoshi Sahara $form->addTagOpen('p'); 151424870174SAndreas Gohr $attrs = []; 151570c3cc9aSKate Arzamastseva if ($update) $attrs['checked'] = 'checked'; 1516b960c74fSSatoshi Sahara $form->addCheckbox('ow', $lang['txt_overwrt'])->id('dw__ow')->val('1') 1517b960c74fSSatoshi Sahara ->addClass('check')->attrs($attrs); 1518b960c74fSSatoshi Sahara $form->addTagClose('p'); 1519b960c74fSSatoshi Sahara } 1520b960c74fSSatoshi Sahara $form->addTagClose('div'); 1521b960c74fSSatoshi Sahara 1522b960c74fSSatoshi Sahara if (!$fullscreen) { 1523b960c74fSSatoshi Sahara echo '<div class="upload">' . $lang['mediaupload'] . '</div>' . DOKU_LF; 1524b960c74fSSatoshi Sahara } else { 1525b960c74fSSatoshi Sahara echo DOKU_LF; 15263df72098SAndreas Gohr } 1527c472bad9SKate Arzamastseva 1528b960c74fSSatoshi Sahara echo '<div id="mediamanager__uploader">' . DOKU_LF; 1529c6977b3aSSatoshi Sahara echo $form->toHTML('Upload'); 1530b960c74fSSatoshi Sahara echo '</div>' . DOKU_LF; 1531f940e4a0SAndreas Gohr 1532f940e4a0SAndreas Gohr echo '<p class="maxsize">'; 1533f940e4a0SAndreas Gohr printf($lang['maxuploadsize'], filesize_h(media_getuploadsize())); 153456fc6b15SAnna Dabrowska echo ' <a class="allowedmime" href="#">' . $lang['allowedmime'] . '</a>'; 1535499d9bcdSAndreas Gohr echo ' <span>' . implode(', ', array_keys(getMimeTypes())) . '</span>'; 1536b960c74fSSatoshi Sahara echo '</p>' . DOKU_LF; 1537f940e4a0SAndreas Gohr} 1538f940e4a0SAndreas Gohr 1539f940e4a0SAndreas Gohr/** 1540f940e4a0SAndreas Gohr * Returns the size uploaded files may have 1541f940e4a0SAndreas Gohr * 1542f940e4a0SAndreas Gohr * This uses a conservative approach using the lowest number found 1543f940e4a0SAndreas Gohr * in any of the limiting ini settings 1544f940e4a0SAndreas Gohr * 1545f940e4a0SAndreas Gohr * @returns int size in bytes 1546f940e4a0SAndreas Gohr */ 1547d868eb89SAndreas Gohrfunction media_getuploadsize() 1548d868eb89SAndreas Gohr{ 1549f940e4a0SAndreas Gohr $okay = 0; 1550f940e4a0SAndreas Gohr 155124870174SAndreas Gohr $post = php_to_byte(@ini_get('post_max_size')); 155224870174SAndreas Gohr $suho = php_to_byte(@ini_get('suhosin.post.max_value_length')); 155324870174SAndreas Gohr $upld = php_to_byte(@ini_get('upload_max_filesize')); 1554f940e4a0SAndreas Gohr 155524870174SAndreas Gohr if ($post && ($post < $okay || $okay === 0)) $okay = $post; 1556f940e4a0SAndreas Gohr if ($suho && ($suho < $okay || $okay == 0)) $okay = $suho; 1557f940e4a0SAndreas Gohr if ($upld && ($upld < $okay || $okay == 0)) $okay = $upld; 1558f940e4a0SAndreas Gohr 1559f940e4a0SAndreas Gohr return $okay; 15609f5dde7fSMichael Klier} 15613df72098SAndreas Gohr 15623df72098SAndreas Gohr/** 1563bf1f3ac4Ssarnowski * Print the search field form 1564bf1f3ac4Ssarnowski * 1565bf1f3ac4Ssarnowski * @author Tobias Sarnowski <sarnowski@cosmocode.de> 1566d9162c6cSKate Arzamastseva * @author Kate Arzamastseva <pshns@ukr.net> 1567e0c26282SGerrit Uitslag * 1568e0c26282SGerrit Uitslag * @param string $ns 1569e0c26282SGerrit Uitslag * @param string $query 1570e0c26282SGerrit Uitslag * @param bool $fullscreen 1571bf1f3ac4Ssarnowski */ 1572d868eb89SAndreas Gohrfunction media_searchform($ns, $query = '', $fullscreen = false) 1573d868eb89SAndreas Gohr{ 1574bf1f3ac4Ssarnowski global $lang; 1575bf1f3ac4Ssarnowski 1576bf1f3ac4Ssarnowski // The default HTML search form 1577b960c74fSSatoshi Sahara $form = new Form([ 1578b960c74fSSatoshi Sahara 'id' => 'dw__mediasearch', 1579b960c74fSSatoshi Sahara 'action' => ($fullscreen) 1580b960c74fSSatoshi Sahara ? media_managerURL([], '&') 1581b960c74fSSatoshi Sahara : DOKU_BASE . 'lib/exe/mediamanager.php', 1582b960c74fSSatoshi Sahara ]); 1583b960c74fSSatoshi Sahara $form->addTagOpen('div')->addClass('no'); 1584b960c74fSSatoshi Sahara $form->setHiddenField('ns', $ns); 1585b960c74fSSatoshi Sahara $form->setHiddenField($fullscreen ? 'mediado' : 'do', 'searchlist'); 1586554a8c9fSAdrian Lang 1587b960c74fSSatoshi Sahara $form->addTagOpen('p'); 1588bde2a644SSatoshi Sahara $form->addTextInput('q', $lang['searchmedia']) 1589b960c74fSSatoshi Sahara ->attr('title', sprintf($lang['searchmedia_in'], hsc($ns) . ':*')) 1590b960c74fSSatoshi Sahara ->val($query); 1591bde2a644SSatoshi Sahara $form->addHTML(' '); 1592b960c74fSSatoshi Sahara $form->addButton('', $lang['btn_search'])->attr('type', 'submit'); 1593b960c74fSSatoshi Sahara $form->addTagClose('p'); 1594b960c74fSSatoshi Sahara $form->addTagClose('div'); 159526dfc232SAndreas Gohr echo $form->toHTML('SearchMedia'); 1596bf1f3ac4Ssarnowski} 1597bf1f3ac4Ssarnowski 1598bf1f3ac4Ssarnowski/** 15993df72098SAndreas Gohr * Build a tree outline of available media namespaces 16003df72098SAndreas Gohr * 16013df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1602e0c26282SGerrit Uitslag * 1603e0c26282SGerrit Uitslag * @param string $ns 16043df72098SAndreas Gohr */ 1605d868eb89SAndreas Gohrfunction media_nstree($ns) 1606d868eb89SAndreas Gohr{ 16073df72098SAndreas Gohr global $conf; 1608256ca81eSAndreas Gohr global $lang; 16093df72098SAndreas Gohr 16103df72098SAndreas Gohr // currently selected namespace 16113df72098SAndreas Gohr $ns = cleanID($ns); 16123df72098SAndreas Gohr if (empty($ns)) { 1613de3eb1d7SAdrian Lang global $ID; 1614dd90013aSMichael Hamann $ns = (string)getNS($ID); 16153df72098SAndreas Gohr } 1616dd90013aSMichael Hamann 1617dd90013aSMichael Hamann $ns_dir = utf8_encodeFN(str_replace(':', '/', $ns)); 16183df72098SAndreas Gohr 161924870174SAndreas Gohr $data = []; 162024870174SAndreas Gohr search($data, $conf['mediadir'], 'search_index', ['ns' => $ns_dir, 'nofiles' => true]); 16213df72098SAndreas Gohr 16223df72098SAndreas Gohr // wrap a list with the root level around the other namespaces 162324870174SAndreas Gohr array_unshift($data, ['level' => 0, 'id' => '', 'open' => 'true', 'label' => '[' . $lang['mediaroot'] . ']']); 16243df72098SAndreas Gohr 1625dd90013aSMichael Hamann // insert the current ns into the hierarchy if it isn't already part of it 1626dd90013aSMichael Hamann $ns_parts = explode(':', $ns); 1627dd90013aSMichael Hamann $tmp_ns = ''; 1628dd90013aSMichael Hamann $pos = 0; 1629de301a35SDamien Regad $insert = false; 1630dd90013aSMichael Hamann foreach ($ns_parts as $level => $part) { 1631186263b2SDamien Regad if ($tmp_ns) { 1632186263b2SDamien Regad $tmp_ns .= ':' . $part; 1633186263b2SDamien Regad } else { 1634186263b2SDamien Regad $tmp_ns = $part; 1635186263b2SDamien Regad } 1636dd90013aSMichael Hamann 1637de301a35SDamien Regad // find the namespace parts 16389988e853SDamien Regad while (array_key_exists($pos, $data) && $data[$pos]['id'] != $tmp_ns) { 163964159a61SAndreas Gohr if ( 164064159a61SAndreas Gohr $pos >= count($data) || 16412d85e841SAndreas Gohr ($data[$pos]['level'] <= $level + 1 && Sort::strcmp($data[$pos]['id'], $tmp_ns) > 0) 164264159a61SAndreas Gohr ) { 1643de301a35SDamien Regad $insert = true; 1644dd90013aSMichael Hamann break; 1645dd90013aSMichael Hamann } 1646dd90013aSMichael Hamann ++$pos; 1647dd90013aSMichael Hamann } 1648de301a35SDamien Regad // insert namespace in hierarchy; if not found in above loop, append it to the end 1649b3894732Ssplitbrain if ($insert || $pos === count($data)) { 1650de301a35SDamien Regad array_splice($data, $pos, 0, [['level' => $level + 1, 'id' => $tmp_ns, 'open' => 'true']]); 1651de301a35SDamien Regad } 1652dd90013aSMichael Hamann } 1653dd90013aSMichael Hamann 16543df72098SAndreas Gohr echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); 16553df72098SAndreas Gohr} 16563df72098SAndreas Gohr 16573df72098SAndreas Gohr/** 16583df72098SAndreas Gohr * Userfunction for html_buildlist 16593df72098SAndreas Gohr * 16603df72098SAndreas Gohr * Prints a media namespace tree item 16613df72098SAndreas Gohr * 16623df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 166342ea7f44SGerrit Uitslag * 166442ea7f44SGerrit Uitslag * @param array $item 166542ea7f44SGerrit Uitslag * @return string html 16663df72098SAndreas Gohr */ 1667d868eb89SAndreas Gohrfunction media_nstree_item($item) 1668d868eb89SAndreas Gohr{ 16698108113cSTom N Harris global $INPUT; 16703df72098SAndreas Gohr $pos = strrpos($item['id'], ':'); 16713df72098SAndreas Gohr $label = substr($item['id'], $pos > 0 ? $pos + 1 : 0); 16720e80bb5eSChristopher Smith if (empty($item['label'])) $item['label'] = $label; 16733df72098SAndreas Gohr 16743df72098SAndreas Gohr $ret = ''; 167524870174SAndreas Gohr if ($INPUT->str('do') != 'media') 16763df72098SAndreas Gohr $ret .= '<a href="' . DOKU_BASE . 'lib/exe/mediamanager.php?ns=' . idfilter($item['id']) . '" class="idx_dir">'; 1677b960c74fSSatoshi Sahara else $ret .= '<a href="' . media_managerURL(['ns' => idfilter($item['id'], false), 'tab_files' => 'files']) 167823846a98SKate Arzamastseva . '" class="idx_dir">'; 16793df72098SAndreas Gohr $ret .= $item['label']; 16803df72098SAndreas Gohr $ret .= '</a>'; 16813df72098SAndreas Gohr return $ret; 16823df72098SAndreas Gohr} 16833df72098SAndreas Gohr 16843df72098SAndreas Gohr/** 16853df72098SAndreas Gohr * Userfunction for html_buildlist 16863df72098SAndreas Gohr * 16873df72098SAndreas Gohr * Prints a media namespace tree item opener 16883df72098SAndreas Gohr * 16893df72098SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 169042ea7f44SGerrit Uitslag * 169142ea7f44SGerrit Uitslag * @param array $item 169242ea7f44SGerrit Uitslag * @return string html 16933df72098SAndreas Gohr */ 1694d868eb89SAndreas Gohrfunction media_nstree_li($item) 1695d868eb89SAndreas Gohr{ 16963df72098SAndreas Gohr $class = 'media level' . $item['level']; 16973df72098SAndreas Gohr if ($item['open']) { 16983df72098SAndreas Gohr $class .= ' open'; 16993df72098SAndreas Gohr $img = DOKU_BASE . 'lib/images/minus.gif'; 1700e260f93bSAnika Henke $alt = '−'; 17013df72098SAndreas Gohr } else { 17023df72098SAndreas Gohr $class .= ' closed'; 17033df72098SAndreas Gohr $img = DOKU_BASE . 'lib/images/plus.gif'; 17047af1b404SAnika Henke $alt = '+'; 17053df72098SAndreas Gohr } 1706231b8c34SPierre Spring // TODO: only deliver an image if it actually has a subtree... 17073df72098SAndreas Gohr return '<li class="' . $class . '">' . 17087af1b404SAnika Henke '<img src="' . $img . '" alt="' . $alt . '" />'; 17093df72098SAndreas Gohr} 171013c08e2fSMichael Klier 171113c08e2fSMichael Klier/** 1712b021f0b4SAndreas Gohr * Resizes or crop the given image to the given size 1713b021f0b4SAndreas Gohr * 1714b021f0b4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 1715b021f0b4SAndreas Gohr * 1716b021f0b4SAndreas Gohr * @param string $file filename, path to file 1717b021f0b4SAndreas Gohr * @param string $ext extension 1718b021f0b4SAndreas Gohr * @param int $w desired width 1719b021f0b4SAndreas Gohr * @param int $h desired height 1720b021f0b4SAndreas Gohr * @param bool $crop should a center crop be used? 1721b021f0b4SAndreas Gohr * @return string path to resized or original size if failed 1722b021f0b4SAndreas Gohr */ 1723b021f0b4SAndreas Gohrfunction media_mod_image($file, $ext, $w, $h = 0, $crop = false) 1724b021f0b4SAndreas Gohr{ 1725b021f0b4SAndreas Gohr global $conf; 1726d967ecd8SAndreas Gohr if (!$h) $h = 0; 1727b021f0b4SAndreas Gohr // we wont scale up to infinity 1728b021f0b4SAndreas Gohr if ($w > 2000 || $h > 2000) return $file; 1729b021f0b4SAndreas Gohr 1730b021f0b4SAndreas Gohr $operation = $crop ? 'crop' : 'resize'; 1731b021f0b4SAndreas Gohr 1732b021f0b4SAndreas Gohr $options = [ 1733b021f0b4SAndreas Gohr 'quality' => $conf['jpg_quality'], 1734b021f0b4SAndreas Gohr 'imconvert' => $conf['im_convert'], 1735b021f0b4SAndreas Gohr ]; 1736b021f0b4SAndreas Gohr 173724870174SAndreas Gohr $cache = new CacheImageMod($file, $w, $h, $ext, $crop); 1738b021f0b4SAndreas Gohr if (!$cache->useCache()) { 1739b021f0b4SAndreas Gohr try { 1740b021f0b4SAndreas Gohr Slika::run($file, $options) 1741b021f0b4SAndreas Gohr ->autorotate() 1742b021f0b4SAndreas Gohr ->$operation($w, $h) 1743b021f0b4SAndreas Gohr ->save($cache->cache, $ext); 1744b021f0b4SAndreas Gohr if ($conf['fperm']) @chmod($cache->cache, $conf['fperm']); 174524870174SAndreas Gohr } catch (Exception $e) { 1746b021f0b4SAndreas Gohr Logger::debug($e->getMessage()); 1747b021f0b4SAndreas Gohr return $file; 1748b021f0b4SAndreas Gohr } 1749b021f0b4SAndreas Gohr } 1750b021f0b4SAndreas Gohr 1751b021f0b4SAndreas Gohr return $cache->cache; 1752b021f0b4SAndreas Gohr} 1753b021f0b4SAndreas Gohr 1754b021f0b4SAndreas Gohr/** 175513c08e2fSMichael Klier * Resizes the given image to the given size 175613c08e2fSMichael Klier * 175713c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 175842ea7f44SGerrit Uitslag * 175942ea7f44SGerrit Uitslag * @param string $file filename, path to file 176042ea7f44SGerrit Uitslag * @param string $ext extension 176142ea7f44SGerrit Uitslag * @param int $w desired width 176242ea7f44SGerrit Uitslag * @param int $h desired height 176342ea7f44SGerrit Uitslag * @return string path to resized or original size if failed 176413c08e2fSMichael Klier */ 1765b021f0b4SAndreas Gohrfunction media_resize_image($file, $ext, $w, $h = 0) 1766b021f0b4SAndreas Gohr{ 1767b021f0b4SAndreas Gohr return media_mod_image($file, $ext, $w, $h, false); 1768d2bd34a5SAndreas Gohr} 176913c08e2fSMichael Klier 177013c08e2fSMichael Klier/** 1771d2bd34a5SAndreas Gohr * Center crops the given image to the wanted size 177213c08e2fSMichael Klier * 177313c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 177442ea7f44SGerrit Uitslag * 177542ea7f44SGerrit Uitslag * @param string $file filename, path to file 177642ea7f44SGerrit Uitslag * @param string $ext extension 177742ea7f44SGerrit Uitslag * @param int $w desired width 177842ea7f44SGerrit Uitslag * @param int $h desired height 177942ea7f44SGerrit Uitslag * @return string path to resized or original size if failed 178013c08e2fSMichael Klier */ 1781b021f0b4SAndreas Gohrfunction media_crop_image($file, $ext, $w, $h = 0) 1782b021f0b4SAndreas Gohr{ 1783b021f0b4SAndreas Gohr return media_mod_image($file, $ext, $w, $h, true); 178413c08e2fSMichael Klier} 178513c08e2fSMichael Klier 178613c08e2fSMichael Klier/** 17870f4e0092SChristopher Smith * Calculate a token to be used to verify fetch requests for resized or 17880f4e0092SChristopher Smith * cropped images have been internally generated - and prevent external 17890f4e0092SChristopher Smith * DDOS attacks via fetch 17900f4e0092SChristopher Smith * 17913c124064SAndreas Gohr * @author Christopher Smith <chris@jalakai.co.uk> 17923c124064SAndreas Gohr * 17930f4e0092SChristopher Smith * @param string $id id of the image 17940f4e0092SChristopher Smith * @param int $w resize/crop width 17950f4e0092SChristopher Smith * @param int $h resize/crop height 179642ea7f44SGerrit Uitslag * @return string token or empty string if no token required 17970f4e0092SChristopher Smith */ 1798d868eb89SAndreas Gohrfunction media_get_token($id, $w, $h) 1799d868eb89SAndreas Gohr{ 18000f4e0092SChristopher Smith // token is only required for modified images 1801cc036f74SKlap-in if ($w || $h || media_isexternal($id)) { 18023c124064SAndreas Gohr $token = $id; 18030f4e0092SChristopher Smith if ($w) $token .= '.' . $w; 18040f4e0092SChristopher Smith if ($h) $token .= '.' . $h; 18050f4e0092SChristopher Smith 180624870174SAndreas Gohr return substr(PassHash::hmac('md5', $token, auth_cookiesalt()), 0, 6); 18070f4e0092SChristopher Smith } 18080f4e0092SChristopher Smith 18090f4e0092SChristopher Smith return ''; 18100f4e0092SChristopher Smith} 18110f4e0092SChristopher Smith 18120f4e0092SChristopher Smith/** 181313c08e2fSMichael Klier * Download a remote file and return local filename 181413c08e2fSMichael Klier * 181513c08e2fSMichael Klier * returns false if download fails. Uses cached file if available and 181613c08e2fSMichael Klier * wanted 181713c08e2fSMichael Klier * 181813c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 181913c08e2fSMichael Klier * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 182042ea7f44SGerrit Uitslag * 182142ea7f44SGerrit Uitslag * @param string $url 182242ea7f44SGerrit Uitslag * @param string $ext extension 182342ea7f44SGerrit Uitslag * @param int $cache cachetime in seconds 182442ea7f44SGerrit Uitslag * @return false|string path to cached file 182513c08e2fSMichael Klier */ 1826d868eb89SAndreas Gohrfunction media_get_from_URL($url, $ext, $cache) 1827d868eb89SAndreas Gohr{ 182813c08e2fSMichael Klier global $conf; 182913c08e2fSMichael Klier 183013c08e2fSMichael Klier // if no cache or fetchsize just redirect 183113c08e2fSMichael Klier if ($cache == 0) return false; 183213c08e2fSMichael Klier if (!$conf['fetchsize']) return false; 183313c08e2fSMichael Klier 183413c08e2fSMichael Klier $local = getCacheName(strtolower($url), ".media.$ext"); 183513c08e2fSMichael Klier $mtime = @filemtime($local); // 0 if not exists 183613c08e2fSMichael Klier 183713c08e2fSMichael Klier //decide if download needed: 18387d34963bSAndreas Gohr if ( 18397d34963bSAndreas Gohr ($mtime == 0) || // cache does not exist 184013c08e2fSMichael Klier ($cache != -1 && $mtime < time() - $cache) // 'recache' and cache has expired 184113c08e2fSMichael Klier ) { 184213c08e2fSMichael Klier if (media_image_download($url, $local)) { 184313c08e2fSMichael Klier return $local; 184413c08e2fSMichael Klier } else { 184513c08e2fSMichael Klier return false; 184613c08e2fSMichael Klier } 184713c08e2fSMichael Klier } 184813c08e2fSMichael Klier 184913c08e2fSMichael Klier //if cache exists use it else 185013c08e2fSMichael Klier if ($mtime) return $local; 185113c08e2fSMichael Klier 185213c08e2fSMichael Klier //else return false 185313c08e2fSMichael Klier return false; 185413c08e2fSMichael Klier} 185513c08e2fSMichael Klier 185613c08e2fSMichael Klier/** 185713c08e2fSMichael Klier * Download image files 185813c08e2fSMichael Klier * 185913c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 186042ea7f44SGerrit Uitslag * 186142ea7f44SGerrit Uitslag * @param string $url 186242ea7f44SGerrit Uitslag * @param string $file path to file in which to put the downloaded content 186342ea7f44SGerrit Uitslag * @return bool 186413c08e2fSMichael Klier */ 1865d868eb89SAndreas Gohrfunction media_image_download($url, $file) 1866d868eb89SAndreas Gohr{ 186713c08e2fSMichael Klier global $conf; 186813c08e2fSMichael Klier $http = new DokuHTTPClient(); 1869a5951419SAndreas Gohr $http->keep_alive = false; // we do single ops here, no need for keep-alive 1870a5951419SAndreas Gohr 187113c08e2fSMichael Klier $http->max_bodysize = $conf['fetchsize']; 187213c08e2fSMichael Klier $http->timeout = 25; //max. 25 sec 187313c08e2fSMichael Klier $http->header_regexp = '!\r\nContent-Type: image/(jpe?g|gif|png)!i'; 187413c08e2fSMichael Klier 187513c08e2fSMichael Klier $data = $http->get($url); 187613c08e2fSMichael Klier if (!$data) return false; 187713c08e2fSMichael Klier 187879e79377SAndreas Gohr $fileexists = file_exists($file); 187913c08e2fSMichael Klier $fp = @fopen($file, "w"); 188013c08e2fSMichael Klier if (!$fp) return false; 188113c08e2fSMichael Klier fwrite($fp, $data); 188213c08e2fSMichael Klier fclose($fp); 188324870174SAndreas Gohr if (!$fileexists && $conf['fperm']) chmod($file, $conf['fperm']); 188413c08e2fSMichael Klier 188513c08e2fSMichael Klier // check if it is really an image 188613c08e2fSMichael Klier $info = @getimagesize($file); 188713c08e2fSMichael Klier if (!$info) { 188813c08e2fSMichael Klier @unlink($file); 188913c08e2fSMichael Klier return false; 189013c08e2fSMichael Klier } 189113c08e2fSMichael Klier 189213c08e2fSMichael Klier return true; 189313c08e2fSMichael Klier} 189413c08e2fSMichael Klier 189513c08e2fSMichael Klier/** 189613c08e2fSMichael Klier * resize images using external ImageMagick convert program 189713c08e2fSMichael Klier * 189813c08e2fSMichael Klier * @author Pavel Vitis <Pavel.Vitis@seznam.cz> 189913c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 190042ea7f44SGerrit Uitslag * 190142ea7f44SGerrit Uitslag * @param string $ext extension 190242ea7f44SGerrit Uitslag * @param string $from filename path to file 190342ea7f44SGerrit Uitslag * @param int $from_w original width 190442ea7f44SGerrit Uitslag * @param int $from_h original height 190542ea7f44SGerrit Uitslag * @param string $to path to resized file 190642ea7f44SGerrit Uitslag * @param int $to_w desired width 190742ea7f44SGerrit Uitslag * @param int $to_h desired height 190842ea7f44SGerrit Uitslag * @return bool 190913c08e2fSMichael Klier */ 1910d868eb89SAndreas Gohrfunction media_resize_imageIM($ext, $from, $from_w, $from_h, $to, $to_w, $to_h) 1911d868eb89SAndreas Gohr{ 191213c08e2fSMichael Klier global $conf; 191313c08e2fSMichael Klier 191413c08e2fSMichael Klier // check if convert is configured 191513c08e2fSMichael Klier if (!$conf['im_convert']) return false; 191613c08e2fSMichael Klier 191713c08e2fSMichael Klier // prepare command 191813c08e2fSMichael Klier $cmd = $conf['im_convert']; 191913c08e2fSMichael Klier $cmd .= ' -resize ' . $to_w . 'x' . $to_h . '!'; 192013c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 192113c08e2fSMichael Klier $cmd .= ' -quality ' . $conf['jpg_quality']; 192213c08e2fSMichael Klier } 192313c08e2fSMichael Klier $cmd .= " $from $to"; 192413c08e2fSMichael Klier 192513c08e2fSMichael Klier @exec($cmd, $out, $retval); 192613c08e2fSMichael Klier if ($retval == 0) return true; 192713c08e2fSMichael Klier return false; 192813c08e2fSMichael Klier} 192913c08e2fSMichael Klier 193013c08e2fSMichael Klier/** 193113c08e2fSMichael Klier * crop images using external ImageMagick convert program 193213c08e2fSMichael Klier * 193313c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 193442ea7f44SGerrit Uitslag * 193542ea7f44SGerrit Uitslag * @param string $ext extension 193642ea7f44SGerrit Uitslag * @param string $from filename path to file 193742ea7f44SGerrit Uitslag * @param int $from_w original width 193842ea7f44SGerrit Uitslag * @param int $from_h original height 193942ea7f44SGerrit Uitslag * @param string $to path to resized file 194042ea7f44SGerrit Uitslag * @param int $to_w desired width 194142ea7f44SGerrit Uitslag * @param int $to_h desired height 194242ea7f44SGerrit Uitslag * @param int $ofs_x offset of crop centre 194342ea7f44SGerrit Uitslag * @param int $ofs_y offset of crop centre 194442ea7f44SGerrit Uitslag * @return bool 1945d2bd34a5SAndreas Gohr * @deprecated 2020-09-01 194613c08e2fSMichael Klier */ 1947d868eb89SAndreas Gohrfunction media_crop_imageIM($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x, $ofs_y) 1948d868eb89SAndreas Gohr{ 194913c08e2fSMichael Klier global $conf; 1950d2bd34a5SAndreas Gohr dbg_deprecated('splitbrain\\Slika'); 195113c08e2fSMichael Klier 195213c08e2fSMichael Klier // check if convert is configured 195313c08e2fSMichael Klier if (!$conf['im_convert']) return false; 195413c08e2fSMichael Klier 195513c08e2fSMichael Klier // prepare command 195613c08e2fSMichael Klier $cmd = $conf['im_convert']; 195713c08e2fSMichael Klier $cmd .= ' -crop ' . $to_w . 'x' . $to_h . '+' . $ofs_x . '+' . $ofs_y; 195813c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 195913c08e2fSMichael Klier $cmd .= ' -quality ' . $conf['jpg_quality']; 196013c08e2fSMichael Klier } 196113c08e2fSMichael Klier $cmd .= " $from $to"; 196213c08e2fSMichael Klier 196313c08e2fSMichael Klier @exec($cmd, $out, $retval); 196413c08e2fSMichael Klier if ($retval == 0) return true; 196513c08e2fSMichael Klier return false; 196613c08e2fSMichael Klier} 196713c08e2fSMichael Klier 196813c08e2fSMichael Klier/** 196913c08e2fSMichael Klier * resize or crop images using PHP's libGD support 197013c08e2fSMichael Klier * 197113c08e2fSMichael Klier * @author Andreas Gohr <andi@splitbrain.org> 197213c08e2fSMichael Klier * @author Sebastian Wienecke <s_wienecke@web.de> 197342ea7f44SGerrit Uitslag * 197442ea7f44SGerrit Uitslag * @param string $ext extension 197542ea7f44SGerrit Uitslag * @param string $from filename path to file 197642ea7f44SGerrit Uitslag * @param int $from_w original width 197742ea7f44SGerrit Uitslag * @param int $from_h original height 197842ea7f44SGerrit Uitslag * @param string $to path to resized file 197942ea7f44SGerrit Uitslag * @param int $to_w desired width 198042ea7f44SGerrit Uitslag * @param int $to_h desired height 198142ea7f44SGerrit Uitslag * @param int $ofs_x offset of crop centre 198242ea7f44SGerrit Uitslag * @param int $ofs_y offset of crop centre 198342ea7f44SGerrit Uitslag * @return bool 1984d2bd34a5SAndreas Gohr * @deprecated 2020-09-01 198513c08e2fSMichael Klier */ 1986d868eb89SAndreas Gohrfunction media_resize_imageGD($ext, $from, $from_w, $from_h, $to, $to_w, $to_h, $ofs_x = 0, $ofs_y = 0) 1987d868eb89SAndreas Gohr{ 198813c08e2fSMichael Klier global $conf; 1989d2bd34a5SAndreas Gohr dbg_deprecated('splitbrain\\Slika'); 199013c08e2fSMichael Klier 199113c08e2fSMichael Klier if ($conf['gdlib'] < 1) return false; //no GDlib available or wanted 199213c08e2fSMichael Klier 199313c08e2fSMichael Klier // check available memory 199413c08e2fSMichael Klier if (!is_mem_available(($from_w * $from_h * 4) + ($to_w * $to_h * 4))) { 199513c08e2fSMichael Klier return false; 199613c08e2fSMichael Klier } 199713c08e2fSMichael Klier 199813c08e2fSMichael Klier // create an image of the given filetype 199959bc3b48SGerrit Uitslag $image = false; 200013c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 200113c08e2fSMichael Klier if (!function_exists("imagecreatefromjpeg")) return false; 200213c08e2fSMichael Klier $image = @imagecreatefromjpeg($from); 200313c08e2fSMichael Klier } elseif ($ext == 'png') { 200413c08e2fSMichael Klier if (!function_exists("imagecreatefrompng")) return false; 200513c08e2fSMichael Klier $image = @imagecreatefrompng($from); 200613c08e2fSMichael Klier } elseif ($ext == 'gif') { 200713c08e2fSMichael Klier if (!function_exists("imagecreatefromgif")) return false; 200813c08e2fSMichael Klier $image = @imagecreatefromgif($from); 200913c08e2fSMichael Klier } 201013c08e2fSMichael Klier if (!$image) return false; 201113c08e2fSMichael Klier 201259bc3b48SGerrit Uitslag $newimg = false; 201313c08e2fSMichael Klier if (($conf['gdlib'] > 1) && function_exists("imagecreatetruecolor") && $ext != 'gif') { 201413c08e2fSMichael Klier $newimg = @imagecreatetruecolor($to_w, $to_h); 201513c08e2fSMichael Klier } 201613c08e2fSMichael Klier if (!$newimg) $newimg = @imagecreate($to_w, $to_h); 201713c08e2fSMichael Klier if (!$newimg) { 201813c08e2fSMichael Klier imagedestroy($image); 201913c08e2fSMichael Klier return false; 202013c08e2fSMichael Klier } 202113c08e2fSMichael Klier 202213c08e2fSMichael Klier //keep png alpha channel if possible 202313c08e2fSMichael Klier if ($ext == 'png' && $conf['gdlib'] > 1 && function_exists('imagesavealpha')) { 202413c08e2fSMichael Klier imagealphablending($newimg, false); 202513c08e2fSMichael Klier imagesavealpha($newimg, true); 202613c08e2fSMichael Klier } 202713c08e2fSMichael Klier 202813c08e2fSMichael Klier //keep gif transparent color if possible 202913c08e2fSMichael Klier if ($ext == 'gif' && function_exists('imagefill') && function_exists('imagecolorallocate')) { 203013c08e2fSMichael Klier if (function_exists('imagecolorsforindex') && function_exists('imagecolortransparent')) { 203113c08e2fSMichael Klier $transcolorindex = @imagecolortransparent($image); 203213c08e2fSMichael Klier if ($transcolorindex >= 0) { //transparent color exists 203313c08e2fSMichael Klier $transcolor = @imagecolorsforindex($image, $transcolorindex); 203464159a61SAndreas Gohr $transcolorindex = @imagecolorallocate( 203564159a61SAndreas Gohr $newimg, 203664159a61SAndreas Gohr $transcolor['red'], 203764159a61SAndreas Gohr $transcolor['green'], 203864159a61SAndreas Gohr $transcolor['blue'] 203964159a61SAndreas Gohr ); 204013c08e2fSMichael Klier @imagefill($newimg, 0, 0, $transcolorindex); 204113c08e2fSMichael Klier @imagecolortransparent($newimg, $transcolorindex); 204213c08e2fSMichael Klier } else { //filling with white 204313c08e2fSMichael Klier $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 204413c08e2fSMichael Klier @imagefill($newimg, 0, 0, $whitecolorindex); 204513c08e2fSMichael Klier } 204613c08e2fSMichael Klier } else { //filling with white 204713c08e2fSMichael Klier $whitecolorindex = @imagecolorallocate($newimg, 255, 255, 255); 204813c08e2fSMichael Klier @imagefill($newimg, 0, 0, $whitecolorindex); 204913c08e2fSMichael Klier } 205013c08e2fSMichael Klier } 205113c08e2fSMichael Klier 205213c08e2fSMichael Klier //try resampling first 205313c08e2fSMichael Klier if (function_exists("imagecopyresampled")) { 205413c08e2fSMichael Klier if (!@imagecopyresampled($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h)) { 205513c08e2fSMichael Klier imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 205613c08e2fSMichael Klier } 205713c08e2fSMichael Klier } else { 205813c08e2fSMichael Klier imagecopyresized($newimg, $image, 0, 0, $ofs_x, $ofs_y, $to_w, $to_h, $from_w, $from_h); 205913c08e2fSMichael Klier } 206013c08e2fSMichael Klier 206113c08e2fSMichael Klier $okay = false; 206213c08e2fSMichael Klier if ($ext == 'jpg' || $ext == 'jpeg') { 206313c08e2fSMichael Klier if (!function_exists('imagejpeg')) { 206413c08e2fSMichael Klier $okay = false; 206513c08e2fSMichael Klier } else { 206613c08e2fSMichael Klier $okay = imagejpeg($newimg, $to, $conf['jpg_quality']); 206713c08e2fSMichael Klier } 206813c08e2fSMichael Klier } elseif ($ext == 'png') { 206913c08e2fSMichael Klier if (!function_exists('imagepng')) { 207013c08e2fSMichael Klier $okay = false; 207113c08e2fSMichael Klier } else { 207213c08e2fSMichael Klier $okay = imagepng($newimg, $to); 207313c08e2fSMichael Klier } 207413c08e2fSMichael Klier } elseif ($ext == 'gif') { 207513c08e2fSMichael Klier if (!function_exists('imagegif')) { 207613c08e2fSMichael Klier $okay = false; 207713c08e2fSMichael Klier } else { 207813c08e2fSMichael Klier $okay = imagegif($newimg, $to); 207913c08e2fSMichael Klier } 208013c08e2fSMichael Klier } 208113c08e2fSMichael Klier 208279a2d784SGerrit Uitslag // destroy GD image resources 208379a2d784SGerrit Uitslag imagedestroy($image); 208479a2d784SGerrit Uitslag imagedestroy($newimg); 208513c08e2fSMichael Klier 208613c08e2fSMichael Klier return $okay; 208713c08e2fSMichael Klier} 208813c08e2fSMichael Klier 20893d7a9e0aSAnika Henke/** 20903d7a9e0aSAnika Henke * Return other media files with the same base name 209179e53fe5SAnika Henke * but different extensions. 20923d7a9e0aSAnika Henke * 20933d7a9e0aSAnika Henke * @param string $src - ID of media file 209442ea7f44SGerrit Uitslag * @param string[] $exts - alternative extensions to find other files for 209542ea7f44SGerrit Uitslag * @return array - array(mime type => file ID) 20963d7a9e0aSAnika Henke * 20973d7a9e0aSAnika Henke * @author Anika Henke <anika@selfthinker.org> 20983d7a9e0aSAnika Henke */ 2099d868eb89SAndreas Gohrfunction media_alternativefiles($src, $exts) 2100d868eb89SAndreas Gohr{ 21013d7a9e0aSAnika Henke 210224870174SAndreas Gohr $files = []; 2103a19c9aa0SGerrit Uitslag [$srcExt, /* srcMime */] = mimetype($src); 21043d7a9e0aSAnika Henke $filebase = substr($src, 0, -1 * (strlen($srcExt) + 1)); 21053d7a9e0aSAnika Henke 21063d7a9e0aSAnika Henke foreach ($exts as $ext) { 21073d7a9e0aSAnika Henke $fileid = $filebase . '.' . $ext; 21083d7a9e0aSAnika Henke $file = mediaFN($fileid); 21093d7a9e0aSAnika Henke if (file_exists($file)) { 2110a19c9aa0SGerrit Uitslag [/* fileExt */, $fileMime] = mimetype($file); 211179e53fe5SAnika Henke $files[$fileMime] = $fileid; 211299f943f6SAnika Henke } 21133d7a9e0aSAnika Henke } 21143d7a9e0aSAnika Henke return $files; 21153d7a9e0aSAnika Henke} 21163d7a9e0aSAnika Henke 2117f50634f0SAnika Henke/** 2118f50634f0SAnika Henke * Check if video/audio is supported to be embedded. 2119f50634f0SAnika Henke * 2120b83a74f1SAnika Henke * @param string $mime - mimetype of media file 212142ea7f44SGerrit Uitslag * @param string $type - type of media files to check ('video', 'audio', or null for all) 2122f50634f0SAnika Henke * @return boolean 2123f50634f0SAnika Henke * 2124f50634f0SAnika Henke * @author Anika Henke <anika@selfthinker.org> 2125f50634f0SAnika Henke */ 2126ed823bcdSAndreas Gohrfunction media_supportedav($mime, $type = null) 2127d868eb89SAndreas Gohr{ 212824870174SAndreas Gohr $supportedAudio = [ 2129f50634f0SAnika Henke 'ogg' => 'audio/ogg', 2130f50634f0SAnika Henke 'mp3' => 'audio/mpeg', 213124870174SAndreas Gohr 'wav' => 'audio/wav' 213224870174SAndreas Gohr ]; 213324870174SAndreas Gohr $supportedVideo = [ 2134f50634f0SAnika Henke 'webm' => 'video/webm', 2135f50634f0SAnika Henke 'ogv' => 'video/ogg', 213624870174SAndreas Gohr 'mp4' => 'video/mp4' 213724870174SAndreas Gohr ]; 2138f50634f0SAnika Henke if ($type == 'audio') { 2139f50634f0SAnika Henke $supportedAv = $supportedAudio; 2140f50634f0SAnika Henke } elseif ($type == 'video') { 2141f50634f0SAnika Henke $supportedAv = $supportedVideo; 2142f50634f0SAnika Henke } else { 2143f50634f0SAnika Henke $supportedAv = array_merge($supportedAudio, $supportedVideo); 2144f50634f0SAnika Henke } 2145f50634f0SAnika Henke return in_array($mime, $supportedAv); 2146f50634f0SAnika Henke} 2147f50634f0SAnika Henke 21480877a1f1SSchplurtz le Déboulonné/** 21490877a1f1SSchplurtz le Déboulonné * Return track media files with the same base name 21500877a1f1SSchplurtz le Déboulonné * but extensions that indicate kind and lang. 21510877a1f1SSchplurtz le Déboulonné * ie for foo.webm search foo.sub.lang.vtt, foo.cap.lang.vtt... 21520877a1f1SSchplurtz le Déboulonné * 21530877a1f1SSchplurtz le Déboulonné * @param string $src - ID of media file 215401299338SSchplurtz le Déboulonné * @return array - array(mediaID => array( kind, srclang )) 21550877a1f1SSchplurtz le Déboulonné * 21560877a1f1SSchplurtz le Déboulonné * @author Schplurtz le Déboulonné <Schplurtz@laposte.net> 21570877a1f1SSchplurtz le Déboulonné */ 2158d868eb89SAndreas Gohrfunction media_trackfiles($src) 2159d868eb89SAndreas Gohr{ 216024870174SAndreas Gohr $kinds = [ 21610877a1f1SSchplurtz le Déboulonné 'sub' => 'subtitles', 21620877a1f1SSchplurtz le Déboulonné 'cap' => 'captions', 21630877a1f1SSchplurtz le Déboulonné 'des' => 'descriptions', 21640877a1f1SSchplurtz le Déboulonné 'cha' => 'chapters', 21650877a1f1SSchplurtz le Déboulonné 'met' => 'metadata' 216624870174SAndreas Gohr ]; 21670877a1f1SSchplurtz le Déboulonné 216824870174SAndreas Gohr $files = []; 21690877a1f1SSchplurtz le Déboulonné $re = '/\\.(sub|cap|des|cha|met)\\.([^.]+)\\.vtt$/'; 21700877a1f1SSchplurtz le Déboulonné $baseid = pathinfo($src, PATHINFO_FILENAME); 21710877a1f1SSchplurtz le Déboulonné $pattern = mediaFN($baseid) . '.*.*.vtt'; 21720877a1f1SSchplurtz le Déboulonné $list = glob($pattern); 21730877a1f1SSchplurtz le Déboulonné foreach ($list as $track) { 21740877a1f1SSchplurtz le Déboulonné if (preg_match($re, $track, $matches)) { 217524870174SAndreas Gohr $files[$baseid . '.' . $matches[1] . '.' . $matches[2] . '.vtt'] = [$kinds[$matches[1]], $matches[2]]; 21760877a1f1SSchplurtz le Déboulonné } 21770877a1f1SSchplurtz le Déboulonné } 21780877a1f1SSchplurtz le Déboulonné return $files; 21790877a1f1SSchplurtz le Déboulonné} 21800877a1f1SSchplurtz le Déboulonné 2181365be586SAndreas Gohr/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ 2182