/** * Use favicon.ico from data/media root directory if it exists, otherwise use * the one in the template's image directory. * * @author Anika Henke <*****@*****.**> */ function _tpl_getFavicon() { if (file_exists(mediaFN('favicon.ico'))) { return ml('favicon.ico'); } return DOKU_TPL . 'images/favicon.ico'; }
/** * Main function to determine the avatar to use */ function _getAvatarURL($user, &$title, &$size) { global $auth; if (!$size || !is_int($size)) { $size = $this->getConf('size'); } // check first if a local image for the given user exists $userinfo = $auth->getUserData($user); if (is_array($userinfo)) { if ($userinfo['name'] && !$title) { $title = hsc($userinfo['name']); } $avatar = $this->getConf('namespace') . ':' . $user; $formats = array('.png', '.jpg', '.gif'); foreach ($formats as $format) { $img = mediaFN($avatar . $format); if (!@file_exists($img)) { continue; } $src = ml($avatar . $format, array('w' => $size, 'h' => $size)); break; } if (!$src) { $mail = $userinfo['mail']; } } else { $mail = $user; } if (!$src) { $seed = md5($mail); if (function_exists('imagecreatetruecolor')) { // we take the monster ID as default $file = 'monsterid.php?seed=' . $seed . '&size=' . $size . '&.png'; } else { // GDlib is not availble - resort to default images switch ($size) { case 20: case 40: case 80: $file = 'images/default_' . $size . '.png'; break; default: $file = 'images/default_120.png'; } } $default = ml(DOKU_URL . '/lib/plugins/avatar/' . $file, 'cache=recache', true, '&', true); // do not pass invalid or empty emails to gravatar site... if (mail_isvalid($mail) && $size <= 80) { $src = ml('http://www.gravatar.com/avatar.php?' . 'gravatar_id=' . $seed . '&default=' . urlencode($default) . '&size=' . $size . '&rating=' . $this->getConf('rating') . '&.jpg', 'cache=recache'); // show only default image if invalid or empty email given } else { $src = $default; } } if (!$title) { $title = obfuscate($mail); } return $src; }
/** * returns a recipe to link to the media file */ protected function recipe($project, $file) { $name = $file->name(); $id = $project->name() . ':' . $name; $media_name = mediaFN($id); if ($media_name) { return "ln -s {$media_name} {$name}"; } return NULL; }
public function make($file) { $media = mediaFN($file->id()); $path = $file->file_path(); if (file_exists($path)) { unlink($path); } symlink($media, $path); return true; }
function delete_media($md5) { $epub = $this->cache['current_books'][$md5]['epub']; $file = mediaFN($this->cache['current_books'][$md5]['epub']); if (file_exists($file)) { if (unlink($file)) { return "Removed: " . $epub; } else { return "error unlinking {$epub}"; } } return "File not found: " . $this->cache['current_books'][$md5]['epub']; }
function settings_plugin_siteexport_settings($functions) { global $ID; $functions->debug->setDebugLevel($this->getConf('debugLevel')); $functions->debug->setDebugFile($this->getConf('debugFile')); if (empty($_REQUEST['pattern'])) { $params = $_REQUEST; $this->pattern = $functions->requestParametersToCacheHash($params); } else { // Set the pattern $this->pattern = $_REQUEST['pattern']; } $this->isCLI = !$_SERVER['REMOTE_ADDR'] && 'cli' == php_sapi_name(); $this->cachetime = $this->getConf('cachetime'); if (!empty($_REQUEST['disableCache'])) { $this->cachetime = intval($_REQUEST['disableCache']) == 1 ? 0 : $this->cachetime; } // Load Variables $this->origZipFile = $this->getConf('zipfilename'); $this->ignoreNon200 = $this->getConf('ignoreNon200'); // ID $this->downloadZipFile = $functions->getSpecialExportFileName($this->origZipFile, $this->pattern); // $this->eclipseZipFile = $functions->getSpecialExportFileName(getNS($this->origZipFile) . ':' . $this->origEclipseZipFile, $this->pattern); $this->zipFile = mediaFN($this->downloadZipFile); $this->tmpDir = mediaFN(getNS($this->origZipFile)); $this->exportLinkedPages = intval($_REQUEST['exportLinkedPages']) == 1 ? true : false; $this->namespace = $functions->getNamespaceFromID($_REQUEST['ns'], $PAGE); $this->addParams = !empty($_REQUEST['addParams']); $this->useTOCFile = !empty($_REQUEST['useTocFile']); // set export Namespace - which is a virtual Root $pg = noNS($ID); if (empty($this->namespace)) { $this->namespace = $functions->getNamespaceFromID(getNS($ID), $pg); } $this->exportNamespace = !empty($_REQUEST['ens']) && preg_match("%^" . $functions->getNamespaceFromID($_REQUEST['ens'], $pg) . "%", $this->namespace) ? $functions->getNamespaceFromID($_REQUEST['ens'], $pg) : $this->namespace; $this->TOCMapWithoutTranslation = intval($_REQUEST['TOCMapWithoutTranslation']) == 1 ? true : false; // Strip params that should be forwarded $this->additionalParameters = $_REQUEST; $functions->removeWikiVariables($this->additionalParameters, true); $tmpID = $ID; $ID = $this->origZipFile; $INFO = pageinfo(); if (!$this->isCLI) { // Workaround for the cron which cannot authenticate but has access to everything. if ($INFO['perm'] < AUTH_DELETE) { list($USER, $PASS) = $functions->basic_authentication(); auth_login($USER, $PASS); } } $ID = $tmpID; }
/** * native image request which doesn't require a token * try: with a token & without a token * expect: (for both) header with mime-type, content matching source image filesize & no error response */ function test_no_token_required() { $this->width = $this->height = 0; // no width & height, means image request at native dimensions $any_token = 'tok=' . media_get_token('junk', 200, 100) . '&'; $no_token = ''; $bytes = filesize(mediaFN($this->media)); foreach (array($any_token, $no_token) as $token) { $response = $this->fetchResponse($token); $this->assertTrue((bool) $response->getHeader('Content-Type')); $this->assertEquals(strlen($response->getContent()), $bytes); $status_code = $response->getStatusCode(); $this->assertTrue(is_null($status_code) || 200 == $status_code); } }
public function test_move_wiki_namespace() { $this->markTestSkipped('This test is failing.'); global $AUTH_ACL; $AUTH_ACL[] = "wiki:*\t@ALL\t16"; idx_addPage('wiki:dokuwiki'); idx_addPage('wiki:syntax'); /** @var helper_plugin_move $move */ $move = plugin_load('helper', 'move'); $opts = array('ns' => 'wiki', 'newns' => 'foo', 'contenttomove' => 'both'); $this->assertSame(3, $move->start_namespace_move($opts)); $this->assertSame(1, $move->continue_namespace_move()); $this->assertSame(0, $move->continue_namespace_move()); $this->assertFileExists(wikiFN('foo:dokuwiki')); $this->assertFileNotExists(wikiFN('wiki:syntax')); $this->assertFileExists(mediaFN('foo:dokuwiki-128.png')); }
public function internalmedia($src, $title = NULL, $align = NULL, $width = NULL, $height = NULL, $cache = NULL, $linking = NULL, $return = false) { global $ID; list($src, $hash) = explode('#', $src, 2); resolve_mediaid(getNS($ID), $src, $exists); $noLink = false; $render = $linking == 'linkonly' ? false : true; $link = $this->_getMediaLinkConf($src, $title, $align, $width, $height, $cache, $render); list($ext, $mime, $dl) = mimetype($src, false); if (substr($mime, 0, 5) == 'image' && $render) { if ($linking == NULL || $linking == '' || $linking == 'details') { $linking = 'direct'; } $link['url'] = ml($src, array('id' => $ID, 'cache' => $cache), $linking == 'direct'); } elseif ($mime == 'application/x-shockwave-flash' && $render) { // don't link flash movies $noLink = true; } else { // add file icons $class = preg_replace('/[^_\\-a-z0-9]+/i', '_', $ext); $link['class'] .= ' mediafile mf_' . $class; $link['url'] = ml($src, array('id' => $ID, 'cache' => $cache), true); if ($exists) { $link['title'] .= ' (' . filesize_h(filesize(mediaFN($src))) . ')'; } } if ($hash) { $link['url'] .= '#' . $hash; } //markup non existing files if (!$exists) { $link['class'] .= ' wikilink2'; } //output formatted if ($linking == 'nolink' || $noLink) { $this->doc .= $link['name']; } else { $this->doc .= $this->_formatLink($link); } }
/** * Handle the match */ function handle($match, $state, $pos, Doku_Handler $handler) { global $ID; $data = array('width' => 500, 'height' => 250, 'align' => 0, 'initialZoom' => 1, 'tileBaseUri' => DOKU_BASE . 'lib/plugins/panoview/tiles.php', 'tileSize' => 256, 'maxZoom' => 10, 'blankTile' => DOKU_BASE . 'lib/plugins/panoview/gfx/blank.gif', 'loadingTile' => DOKU_BASE . 'lib/plugins/panoview/gfx/progress.gif'); $match = substr($match, 11, -2); //strip markup from start and end // alignment $data['align'] = 0; if (substr($match, 0, 1) == ' ') { $data['align'] += 1; } if (substr($match, -1, 1) == ' ') { $data['align'] += 2; } // extract params list($img, $params) = explode('?', $match, 2); $img = trim($img); // resolving relatives $data['image'] = resolve_id(getNS($ID), $img); $file = mediaFN($data['image']); list($data['imageWidth'], $data['imageHeight']) = @getimagesize($file); // calculate maximum zoom $data['maxZoom'] = ceil(sqrt(max($data['imageWidth'], $data['imageHeight']) / $data['tileSize'])); // size if (preg_match('/\\b(\\d+)[xX](\\d+)\\b/', $params, $match)) { $data['width'] = $match[1]; $data['height'] = $match[2]; } // initial zoom if (preg_match('/\\b[zZ](\\d+)\\b/', $params, $match)) { $data['initialZoom'] = $match[1]; } if ($data['initialZoom'] < 0) { $data['initialZoom'] = 0; } if ($data['initialZoom'] > $data['maxZoom']) { $data['initialZoom'] = $data['maxZoom']; } return $data; }
/** * Gets a local scalable copy of the SVG with its dimensions * * @param $id * @param int $cachetime * @return bool|array either array($file, $width, $height) or false if no cache available */ public function getAdjustedSVG($id, $cachetime = -1) { $info = $this->getInfo(); $cachefile = getCacheName($id . $info['date'], '.svg'); $cachedate = @filemtime($cachefile); if ($cachedate && $cachetime < time() - $cachedate) { list($width, $height) = $this->readSVGsize($cachefile); return array($cachefile, $width, $height); } // still here, create a new cache file if (preg_match('/^https?:\\/\\//i', $id)) { io_download($id, $cachefile); #FIXME make max size configurable } else { @copy(mediaFN($id), $cachefile); } clearstatcache(false, $cachefile); // adjust the size in the cache file if (file_exists($cachefile)) { list($width, $height) = $this->readSVGsize($cachefile, true); return array($cachefile, $width, $height); } return false; }
function copy_media($media, $external = false) { $name = epub_clean_name(str_replace(':', '_', basename($media))); $ret_name = $name; $mime_type = mimetype($name); list($type, $ext) = explode('/', $mime_type[1]); if ($type !== 'image') { return; } if ($external) { if (!$this->allow_url_fopen) { return; } $tmp = str_replace('https://', "", $media); $tmp = str_replace('http://', "", $media); $tmp = str_replace('www.', "", $tmp); if ($this->isWin) { $tmp = preg_replace('/^[A-Z]:/', "", $tmp); } $tmp = ltrim($tmp, '/\\/'); $elems = explode('/', $tmp); if ($this->isWin) { $elems = explode('\\', $tmp); } if (count($elems && $elems[0])) { $elems[0] = preg_replace('#/\\W#', '_', $elems[0]); $name = $elems[0] . "_" . $name; } } if (!preg_match("/^Images/", $name)) { $name = "Images/{$name}"; } $file = $this->oebps . $name; if (file_exists($file)) { return $name; } if (!$external) { $media = mediaFN($media); } if (copy($media, $file)) { epub_write_item($name, $mime_type[1]); return $name; } else { if (!$this->isWin && epub_save_image($media, $file)) { epub_write_item($name, $mime_type[1]); return $name; } } return false; }
/** * Returns a list of recent media changes since give timestamp * * @author Michael Hamann <*****@*****.**> * @author Michael Klier <*****@*****.**> */ function getRecentMediaChanges($timestamp) { if (strlen($timestamp) != 10) { throw new RemoteException('The provided value is not a valid timestamp', 311); } $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES); $changes = array(); foreach ($recents as $recent) { $change = array(); $change['name'] = $recent['id']; $change['lastModified'] = $this->api->toDate($recent['date']); $change['author'] = $recent['user']; $change['version'] = $recent['date']; $change['perms'] = $recent['perms']; $change['size'] = @filesize(mediaFN($recent['id'])); array_push($changes, $change); } if (!empty($changes)) { return $changes; } else { // in case we still have nothing at this point throw new RemoteException('There are no changes in the specified timeframe', 321); } }
/** * Check for media for preconditions and return correct status code * * READ: MEDIA, MIME, EXT, CACHE * WRITE: MEDIA, FILE, array( STATUS, STATUSMESSAGE ) * * @author Gerry Weissbach <*****@*****.**> * @param $media reference to the media id * @param $file reference to the file variable * @returns array(STATUS, STATUSMESSAGE) */ function checkFileStatus(&$media, &$file) { global $MIME, $EXT, $CACHE; //media to local file if (preg_match('#^(https?)://#i', $media)) { //check hash if (substr(md5(auth_cookiesalt() . $media), 0, 6) != $_REQUEST['hash']) { return array(412, 'Precondition Failed'); } //handle external images if (strncmp($MIME, 'image/', 6) == 0) { $file = media_get_from_URL($media, $EXT, $CACHE); } if (!$file) { //download failed - redirect to original URL return array(302, $media); } } else { $media = cleanID($media); if (empty($media)) { return array(400, 'Bad request'); } //check permissions (namespace only) if (auth_quickaclcheck(getNS($media) . ':X') < AUTH_READ) { return array(403, 'Forbidden'); } $file = mediaFN($media); } //check file existance if (!@file_exists($file)) { return array(404, 'Not Found'); } return array(200, null); }
/** * Returns a full media id * * @author Andreas Gohr <*****@*****.**> * * @param string $ns namespace which is context of id * @param string &$page (reference) relative media id, updated to resolved id * @param bool &$exists (reference) updated with existance of media */ function resolve_mediaid($ns, &$page, &$exists, $rev = '', $date_at = false) { $page = resolve_id($ns, $page); if ($rev !== '' && $date_at) { $medialog = new MediaChangeLog($page); $medialog_rev = $medialog->getLastRevisionAt($rev); if ($medialog_rev !== false) { $rev = $medialog_rev; } } $file = mediaFN($page, $rev); $exists = @file_exists($file); }
foreach (explode(' ', 'basedir userewrite baseurl useslash') as $x) { print '$' . "conf['{$x}'] = '" . $conf[$x] . "';\n"; } foreach (explode(' ', 'DOCUMENT_ROOT HTTP_HOST SCRIPT_FILENAME PHP_SELF ' . 'REQUEST_URI SCRIPT_NAME PATH_INFO PATH_TRANSLATED') as $x) { print '$' . "_SERVER['{$x}'] = '" . $_SERVER[$x] . "';\n"; } print "getID('media'): " . getID('media') . "\n"; print "getID('media',false): " . getID('media', false) . "\n"; print '</pre>'; } $ERROR = false; // check image permissions $AUTH = auth_quickaclcheck($IMG); if ($AUTH >= AUTH_READ) { // check if image exists $SRC = mediaFN($IMG); if (!@file_exists($SRC)) { //doesn't exist! header("HTTP/1.0 404 File not Found"); $ERROR = 'File not found'; } } else { // no auth $ERROR = p_locale_xhtml('denied'); } // this makes some general infos available as well as the info about the // "parent" page $INFO = pageinfo(); //start output and load template header('Content-Type: text/html; charset=utf-8'); include template('detail.php');
/** * display recent changes * * @author Andreas Gohr <*****@*****.**> * @author Matthias Grimm <*****@*****.**> * @author Ben Coburn <*****@*****.**> * @author Kate Arzamastseva <*****@*****.**> */ function html_recent($first = 0, $show_changes = 'both') { global $conf; global $lang; global $ID; /* we need to get one additionally log entry to be able to * decide if this is the last page or is there another one. * This is the cheapest solution to get this information. */ $flags = 0; if ($show_changes == 'mediafiles' && $conf['mediarevisions']) { $flags = RECENTS_MEDIA_CHANGES; } elseif ($show_changes == 'pages') { $flags = 0; } elseif ($conf['mediarevisions']) { $show_changes = 'both'; $flags = RECENTS_MEDIA_PAGES_MIXED; } $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags); if (count($recents) == 0 && $first != 0) { $first = 0; $recents = getRecents($first, $conf['recent'] + 1, getNS($ID), $flags); } $hasNext = false; if (count($recents) > $conf['recent']) { $hasNext = true; array_pop($recents); // remove extra log entry } print p_locale_xhtml('recent'); if (getNS($ID) != '') { print '<div class="level1"><p>' . sprintf($lang['recent_global'], getNS($ID), wl('', 'do=recent')) . '</p></div>'; } $form = new Doku_Form(array('id' => 'dw__recent', 'method' => 'GET')); $form->addHidden('sectok', null); $form->addHidden('do', 'recent'); $form->addHidden('id', $ID); if ($conf['mediarevisions']) { $form->addElement(form_makeListboxField('show_changes', array('pages' => $lang['pages_changes'], 'mediafiles' => $lang['media_changes'], 'both' => $lang['both_changes']), $show_changes, $lang['changes_type'], '', '', array('class' => 'quickselect'))); $form->addElement(form_makeButton('submit', 'recent', $lang['btn_apply'])); } $form->addElement(form_makeOpenTag('ul')); foreach ($recents as $recent) { $date = dformat($recent['date']); if ($recent['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT) { $form->addElement(form_makeOpenTag('li', array('class' => 'minor'))); } else { $form->addElement(form_makeOpenTag('li')); } $form->addElement(form_makeOpenTag('div', array('class' => 'li'))); if ($recent['media']) { $form->addElement(media_printicon($recent['id'])); } else { $icon = DOKU_BASE . 'lib/images/fileicons/file.png'; $form->addElement('<img src="' . $icon . '" alt="' . $filename . '" class="icon" />'); } $form->addElement(form_makeOpenTag('span', array('class' => 'date'))); $form->addElement($date); $form->addElement(form_makeCloseTag('span')); if ($recent['media']) { $diff = count(getRevisions($recent['id'], 0, 1, 8192, true)) && @file_exists(mediaFN($recent['id'])); if ($diff) { $href = media_managerURL(array('tab_details' => 'history', 'mediado' => 'diff', 'image' => $recent['id'], 'ns' => getNS($recent['id'])), '&'); } } else { $href = wl($recent['id'], "do=diff", false, '&'); } if ($recent['media'] && !$diff) { $form->addElement('<img src="' . DOKU_BASE . 'lib/images/blank.gif" width="15" height="11" alt="" />'); } else { $form->addElement(form_makeOpenTag('a', array('class' => 'diff_link', 'href' => $href))); $form->addElement(form_makeTag('img', array('src' => DOKU_BASE . 'lib/images/diff.png', 'width' => 15, 'height' => 11, 'title' => $lang['diff'], 'alt' => $lang['diff']))); $form->addElement(form_makeCloseTag('a')); } if ($recent['media']) { $href = media_managerURL(array('tab_details' => 'history', 'image' => $recent['id'], 'ns' => getNS($recent['id'])), '&'); } else { $href = wl($recent['id'], "do=revisions", false, '&'); } $form->addElement(form_makeOpenTag('a', array('class' => 'revisions_link', 'href' => $href))); $form->addElement(form_makeTag('img', array('src' => DOKU_BASE . 'lib/images/history.png', 'width' => 12, 'height' => 14, 'title' => $lang['btn_revs'], 'alt' => $lang['btn_revs']))); $form->addElement(form_makeCloseTag('a')); if ($recent['media']) { $href = media_managerURL(array('tab_details' => 'view', 'image' => $recent['id'], 'ns' => getNS($recent['id'])), '&'); $class = file_exists(mediaFN($recent['id'])) ? 'wikilink1' : ($class = 'wikilink2'); $form->addElement(form_makeOpenTag('a', array('class' => $class, 'href' => $href))); $form->addElement($recent['id']); $form->addElement(form_makeCloseTag('a')); } else { $form->addElement(html_wikilink(':' . $recent['id'], useHeading('navigation') ? null : $recent['id'])); } $form->addElement(form_makeOpenTag('span', array('class' => 'sum'))); $form->addElement(' – ' . htmlspecialchars($recent['sum'])); $form->addElement(form_makeCloseTag('span')); $form->addElement(form_makeOpenTag('span', array('class' => 'user'))); if ($recent['user']) { $form->addElement(editorinfo($recent['user'])); if (auth_ismanager()) { $form->addElement(' (' . $recent['ip'] . ')'); } } else { $form->addElement($recent['ip']); } $form->addElement(form_makeCloseTag('span')); $form->addElement(form_makeCloseTag('div')); $form->addElement(form_makeCloseTag('li')); } $form->addElement(form_makeCloseTag('ul')); $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav'))); $last = $first + $conf['recent']; if ($first > 0) { $first -= $conf['recent']; if ($first < 0) { $first = 0; } $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav-prev'))); $form->addElement(form_makeTag('input', array('type' => 'submit', 'name' => 'first[' . $first . ']', 'value' => $lang['btn_newer'], 'accesskey' => 'n', 'title' => $lang['btn_newer'] . ' [N]', 'class' => 'button show'))); $form->addElement(form_makeCloseTag('div')); } if ($hasNext) { $form->addElement(form_makeOpenTag('div', array('class' => 'pagenav-next'))); $form->addElement(form_makeTag('input', array('type' => 'submit', 'name' => 'first[' . $last . ']', 'value' => $lang['btn_older'], 'accesskey' => 'p', 'title' => $lang['btn_older'] . ' [P]', 'class' => 'button show'))); $form->addElement(form_makeCloseTag('div')); } $form->addElement(form_makeCloseTag('div')); html_form('recent', $form); }
/** * Gathers all page and media data for given namespaces. * * @namespaces array() of namespaces * @depth Search depth * @include_media Determines if media should be regarded, Values: 'ns','all','none'. * @use_cached_pages Determines if only cached pages should be used. If this option is turned off, the operation will cache all non-cached pages within the namespace. * @use_first_header Determines if the first header is used for title of the pages. * * @return array with pages and media: array('pages'=>pages, 'media'=>media). */ function gather_data($namespaces, $depth = 0, $include_media = 'none', $use_cached_pages = true, $use_first_header = false) { global $conf; $transplugin = plugin_load('helper', 'translation'); $pages = array(); $media = array(); // Loop through the namespaces foreach ($namespaces as $ns) { // Get the media of the namespace if ($include_media == 'ns') { $this->get_media($media, $ns, $depth); } // Get the pages of the namespace $this->get_pages($pages, $ns, $depth, $use_first_header); } // Loop through the pages to get links and media foreach ($pages as $pid => $item) { // get instructions $ins = p_cached_instructions(wikiFN($pid), $use_cached_pages, $pid); // find links and media usage foreach ($ins as $i) { $mid = null; // Internal link? if ($i[0] == 'internallink') { $id = $i[1][0]; $exists = true; resolve_pageid($item['ns'], $id, $exists); list($id) = explode('#', $id, 2); if ($id == $pid) { continue; } // skip self references if ($exists && isset($pages[$id])) { $pages[$pid]['links'][] = $id; } if (is_array($i[1][1]) && $i[1][1]['type'] == 'internalmedia') { $mid = $i[1][1]['src']; // image link } else { continue; // we're done here } } if ($i[0] == 'internalmedia') { $mid = $i[1][0]; } if (is_null($mid)) { continue; } if ($include_media == 'none') { continue; } // no media wanted $exists = true; resolve_mediaid($item['ns'], $mid, $exists); list($mid) = explode('#', $mid, 2); $mid = cleanID($mid); if ($exists) { if ($include_media == 'all') { if (!isset($media[$mid])) { //add node $media[$mid] = array('size' => filesize(mediaFN($mid)), 'time' => filemtime(mediaFN($mid)), 'ns' => getNS($mid), 'title' => noNS($mid)); } $pages[$pid]['media'][] = $mid; } elseif (isset($media[$mid])) { $pages[$pid]['media'][] = $mid; } } } // clean up duplicates $pages[$pid]['links'] = array_unique($pages[$pid]['links']); $pages[$pid]['media'] = array_unique($pages[$pid]['media']); } return array('pages' => $pages, 'media' => $media); }
/** * Return a list of page revisions numbers * Does not guarantee that the revision exists in the attic, * only that a line with the date exists in the changelog. * By default the current revision is skipped. * * id: the page of interest * first: skip the first n changelog lines * num: number of revisions to return * * The current revision is automatically skipped when the page exists. * See $INFO['meta']['last_change'] for the current revision. * * For efficiency, the log lines are parsed and cached for later * calls to getRevisionInfo. Large changelog files are read * backwards in chunks until the requested number of changelog * lines are recieved. * * @author Ben Coburn <*****@*****.**> * @author Kate Arzamastseva <*****@*****.**> */ function getRevisions($id, $first, $num, $chunk_size = 8192, $media = false) { global $cache_revinfo; $cache =& $cache_revinfo; if (!isset($cache[$id])) { $cache[$id] = array(); } $revs = array(); $lines = array(); $count = 0; if ($media) { $file = mediaMetaFN($id, '.changes'); } else { $file = metaFN($id, '.changes'); } $num = max($num, 0); $chunk_size = max($chunk_size, 0); if ($first < 0) { $first = 0; } else { if (!$media && @file_exists(wikiFN($id)) || $media && @file_exists(mediaFN($id))) { // skip current revision if the page exists $first = max($first + 1, 0); } } if (!@file_exists($file)) { return $revs; } if (filesize($file) < $chunk_size || $chunk_size == 0) { // read whole file $lines = file($file); if ($lines === false) { return $revs; } } else { // read chunks backwards $fp = fopen($file, 'rb'); // "file pointer" if ($fp === false) { return $revs; } fseek($fp, 0, SEEK_END); $tail = ftell($fp); // chunk backwards $finger = max($tail - $chunk_size, 0); while ($count < $num + $first) { fseek($fp, $finger); $nl = $finger; if ($finger > 0) { fgets($fp); // slip the finger forward to a new line $nl = ftell($fp); } // was the chunk big enough? if not, take another bite if ($nl > 0 && $tail <= $nl) { $finger = max($finger - $chunk_size, 0); continue; } else { $finger = $nl; } // read chunk $chunk = ''; $read_size = max($tail - $finger, 0); // found chunk size $got = 0; while ($got < $read_size && !feof($fp)) { $tmp = @fread($fp, max($read_size - $got, 0)); if ($tmp === false) { break; } //error state $got += strlen($tmp); $chunk .= $tmp; } $tmp = explode("\n", $chunk); array_pop($tmp); // remove trailing newline // combine with previous chunk $count += count($tmp); $lines = array_merge($tmp, $lines); // next chunk if ($finger == 0) { break; } else { $tail = $finger; $finger = max($tail - $chunk_size, 0); } } fclose($fp); } // skip parsing extra lines $num = max(min(count($lines) - $first, $num), 0); if ($first > 0 && $num > 0) { $lines = array_slice($lines, max(count($lines) - $first - $num, 0), $num); } else { if ($first > 0 && $num == 0) { $lines = array_slice($lines, 0, max(count($lines) - $first, 0)); } else { if ($first == 0 && $num > 0) { $lines = array_slice($lines, max(count($lines) - $num, 0)); } } } // handle lines in reverse order for ($i = count($lines) - 1; $i >= 0; $i--) { $tmp = parseChangelogLine($lines[$i]); if ($tmp !== false) { $cache[$id][$tmp['date']] = $tmp; $revs[] = $tmp['date']; } } return $revs; }
/** * Send the diff for some media change * * @fixme this should embed thumbnails of images in HTML version * @param string $subscriber_mail The target mail address * @param string $template Mail template ('uploadmail', ...) * @param string $id Media file for which the notification is * @param int|bool $rev Old revision if any * @return bool true if successfully sent */ public function send_media_diff($subscriber_mail, $template, $id, $rev = false) { global $conf; $file = mediaFN($id); list($mime, $ext) = mimetype($id); $trep = array('MIME' => $mime, 'MEDIA' => ml($id, '', true, '&', true), 'SIZE' => filesize_h(filesize($file))); if ($rev && $conf['mediarevisions']) { $trep['OLD'] = ml($id, "rev={$rev}", true, '&', true); } else { $trep['OLD'] = '---'; } $headers = array('Message-Id' => $this->getMessageID($id, @filemtime($file))); if ($rev) { $headers['In-Reply-To'] = $this->getMessageID($id, $rev); } $this->send($subscriber_mail, 'upload', $id, $template, $trep, null, $headers); }
/** * Tries to find a ressource file in the given locations. * * If a given location starts with a colon it is assumed to be a media * file, otherwise it is assumed to be relative to the current template * * @param array $search locations to look at * @param bool $abs if to use absolute URL * @param array &$imginfo filled with getimagesize() * @return string * @author Andreas Gohr <*****@*****.**> */ function tpl_getMediaFile($search, $abs = false, &$imginfo = null) { $img = ''; $file = ''; $ismedia = false; // loop through candidates until a match was found: foreach ($search as $img) { if (substr($img, 0, 1) == ':') { $file = mediaFN($img); $ismedia = true; } else { $file = tpl_incdir() . $img; $ismedia = false; } if (file_exists($file)) { break; } } // fetch image data if requested if (!is_null($imginfo)) { $imginfo = getimagesize($file); } // build URL if ($ismedia) { $url = ml($img, '', true, '', $abs); } else { $url = tpl_basedir() . $img; if ($abs) { $url = DOKU_URL . substr($url, strlen(DOKU_REL)); } } return $url; }
/** * Callback function to automatically embed images referenced in HTML templates * * @param array $matches * @return string placeholder */ protected function autoembed_cb($matches) { static $embeds = 0; $embeds++; // get file and mime type $media = cleanID($matches[1]); list(, $mime) = mimetype($media); $file = mediaFN($media); if (!file_exists($file)) { return $matches[0]; } //bad reference, keep as is // attach it and set placeholder $this->attachFile($file, $mime, '', 'autoembed' . $embeds); return '%%autoembed' . $embeds . '%%'; }
/** * Override the mpdf _getImage function * * This function takes care of gathering the image data from HTTP or * local files before passing the data back to mpdf's original function * making sure that only cached file paths are passed to mpdf. It also * takes care of checking image ACls. */ function _getImage(&$file, $firsttime = true, $allowvector = true, $orig_srcpath = false) { global $conf; // build regex to parse URL back to media info $re = preg_quote(ml('xxx123yyy', '', true, '&', true), '/'); $re = str_replace('xxx123yyy', '([^&\\?]*)', $re); // extract the real media from a fetch.php uri and determine mime if (preg_match("/^{$re}/", $file, $m) || preg_match('/[&\\?]media=([^&\\?]*)/', $file, $m)) { $media = rawurldecode($m[1]); list($ext, $mime) = mimetype($media); } else { list($ext, $mime) = mimetype($file); } // local files $local = ''; if (substr($file, 0, 9) == 'dw2pdf://') { // support local files passed from plugins $local = substr($file, 9); } elseif (!preg_match('/(\\.php|\\?)/', $file)) { $re = preg_quote(DOKU_URL, '/'); // directly access local files instead of using HTTP, skip dynamic content $local = preg_replace("/^{$re}/i", DOKU_INC, $file); } if (substr($mime, 0, 6) == 'image/') { if (!empty($media)) { // any size restrictions? $w = $h = 0; if (preg_match('/[\\?&]w=(\\d+)/', $file, $m)) { $w = $m[1]; } if (preg_match('/[\\?&]h=(\\d+)/', $file, $m)) { $h = $m[1]; } if (media_isexternal($media)) { $local = media_get_from_URL($media, $ext, -1); if (!$local) { $local = $media; } // let mpdf try again } else { $media = cleanID($media); //check permissions (namespace only) if (auth_quickaclcheck(getNS($media) . ':X') < AUTH_READ) { $file = ''; } $local = mediaFN($media); } //handle image resizing/cropping if ($w && file_exists($local)) { if ($h) { $local = media_crop_image($local, $ext, $w, $h); } else { $local = media_resize_image($local, $ext, $w, $h); } } } elseif (media_isexternal($file)) { // fixed external URLs $local = media_get_from_URL($file, $ext, $conf['cachetime']); } if ($local) { $file = $local; $orig_srcpath = $local; } } return parent::_getImage($file, $firsttime, $allowvector, $orig_srcpath); }
/** * Check for media for preconditions and return correct status code * * READ: MEDIA, MIME, EXT, CACHE * WRITE: MEDIA, FILE, array( STATUS, STATUSMESSAGE ) * * @author Gerry Weissbach <*****@*****.**> * * @param string $media reference to the media id * @param string $file reference to the file variable * @param string $rev * @param int $width * @param int $height * @return array as array(STATUS, STATUSMESSAGE) */ function checkFileStatus(&$media, &$file, $rev = '', $width = 0, $height = 0) { global $MIME, $EXT, $CACHE, $INPUT; //media to local file if (media_isexternal($media)) { //check token for external image and additional for resized and cached images if (media_get_token($media, $width, $height) !== $INPUT->str('tok')) { return array(412, 'Precondition Failed'); } //handle external images if (strncmp($MIME, 'image/', 6) == 0) { $file = media_get_from_URL($media, $EXT, $CACHE); } if (!$file) { //download failed - redirect to original URL return array(302, $media); } } else { $media = cleanID($media); if (empty($media)) { return array(400, 'Bad request'); } // check token for resized images if (($width || $height) && media_get_token($media, $width, $height) !== $INPUT->str('tok')) { return array(412, 'Precondition Failed'); } //check permissions (namespace only) if (auth_quickaclcheck(getNS($media) . ':X') < AUTH_READ) { return array(403, 'Forbidden'); } $file = mediaFN($media, $rev); } //check file existance if (!file_exists($file)) { return array(404, 'Not Found'); } return array(200, null); }
/** * Renders internal and external media * * @author Andreas Gohr <*****@*****.**> * @param string $src media ID * @param string $title descriptive text * @param string $align left|center|right * @param int $width width of media in pixel * @param int $height height of media in pixel * @param string $cache cache|recache|nocache * @param bool $render should the media be embedded inline or just linked * @return string */ function _media($src, $title = null, $align = null, $width = null, $height = null, $cache = null, $render = true) { $ret = ''; list($ext, $mime) = mimetype($src); if (substr($mime, 0, 5) == 'image') { // first get the $title if (!is_null($title)) { $title = $this->_xmlEntities($title); } elseif ($ext == 'jpg' || $ext == 'jpeg') { //try to use the caption from IPTC/EXIF require_once DOKU_INC . 'inc/JpegMeta.php'; $jpeg = new JpegMeta(mediaFN($src)); if ($jpeg !== false) { $cap = $jpeg->getTitle(); } if (!empty($cap)) { $title = $this->_xmlEntities($cap); } } if (!$render) { // if the picture is not supposed to be rendered // return the title of the picture if (!$title) { // just show the sourcename $title = $this->_xmlEntities(utf8_basename(noNS($src))); } return $title; } //add image tag $ret .= '<img src="' . ml($src, array('w' => $width, 'h' => $height, 'cache' => $cache, 'rev' => $this->_getLastMediaRevisionAt($src))) . '"'; $ret .= ' class="media' . $align . '"'; if ($title) { $ret .= ' title="' . $title . '"'; $ret .= ' alt="' . $title . '"'; } else { $ret .= ' alt=""'; } if (!is_null($width)) { $ret .= ' width="' . $this->_xmlEntities($width) . '"'; } if (!is_null($height)) { $ret .= ' height="' . $this->_xmlEntities($height) . '"'; } $ret .= ' />'; } elseif (media_supportedav($mime, 'video') || media_supportedav($mime, 'audio')) { // first get the $title $title = !is_null($title) ? $this->_xmlEntities($title) : false; if (!$render) { // if the file is not supposed to be rendered // return the title of the file (just the sourcename if there is no title) return $title ? $title : $this->_xmlEntities(utf8_basename(noNS($src))); } $att = array(); $att['class'] = "media{$align}"; if ($title) { $att['title'] = $title; } if (media_supportedav($mime, 'video')) { //add video $ret .= $this->_video($src, $width, $height, $att); } if (media_supportedav($mime, 'audio')) { //add audio $ret .= $this->_audio($src, $att); } } elseif ($mime == 'application/x-shockwave-flash') { if (!$render) { // if the flash is not supposed to be rendered // return the title of the flash if (!$title) { // just show the sourcename $title = utf8_basename(noNS($src)); } return $this->_xmlEntities($title); } $att = array(); $att['class'] = "media{$align}"; if ($align == 'right') { $att['align'] = 'right'; } if ($align == 'left') { $att['align'] = 'left'; } $ret .= html_flashobject(ml($src, array('cache' => $cache), true, '&'), $width, $height, array('quality' => 'high'), null, $att, $this->_xmlEntities($title)); } elseif ($title) { // well at least we have a title to display $ret .= $this->_xmlEntities($title); } else { // just show the sourcename $ret .= $this->_xmlEntities(utf8_basename(noNS($src))); } return $ret; }
public function test_render_aggregation_video() { $R = new \Doku_Renderer_xhtml(); // local video requires an existing file to be rendered. we fake one $fake = mediaFN('foo.mp4'); touch($fake); $media = new Media(array('width' => 150, 'height' => 160, 'agg_width' => 180, 'agg_height' => 190, 'mime' => '')); $media->renderValue('foo.mp4', $R, 'xhtml'); $pq = \phpQuery::newDocument($R->doc); $a = $pq->find('a'); $vid = $pq->find('video'); $src = $pq->find('source'); $this->assertContains('fetch.php', $a->attr('href')); // direct link goes to fetch $this->assertContains('fetch.php', $src->attr('src')); // direct link goes to fetch $this->assertEquals(150, $vid->attr('width')); // video param $this->assertEquals(160, $vid->attr('height')); // video param }
/** * List all mediafiles in a namespace * * @author Andreas Gohr <*****@*****.**> */ function search_media(&$data, $base, $file, $type, $lvl, $opts) { //we do nothing with directories if ($type == 'd') { if (!$opts['depth']) { return true; } // recurse forever $depth = substr_count($file, '/'); if ($depth >= $opts['depth']) { return false; } // depth reached return true; } $info = array(); $info['id'] = pathID($file, true); if ($info['id'] != cleanID($info['id'])) { if ($opts['showmsg']) { msg(hsc($info['id']) . ' is not a valid file name for DokuWiki - skipped', -1); } return false; // skip non-valid files } //check ACL for namespace (we have no ACL for mediafiles) $info['perm'] = auth_quickaclcheck(getNS($info['id']) . ':*'); if (!$opts['skipacl'] && $info['perm'] < AUTH_READ) { return false; } //check pattern filter if ($opts['pattern'] && !@preg_match($opts['pattern'], $info['id'])) { return false; } $info['file'] = basename($file); $info['size'] = filesize($base . '/' . $file); $info['mtime'] = filemtime($base . '/' . $file); $info['writable'] = is_writable($base . '/' . $file); if (preg_match("/\\.(jpe?g|gif|png)\$/", $file)) { $info['isimg'] = true; $info['meta'] = new JpegMeta($base . '/' . $file); } else { $info['isimg'] = false; } if ($opts['hash']) { $info['hash'] = md5(io_readFile(mediaFN($info['id']), false)); } $data[] = $info; return false; }
function strip_dir($dir, $fn) { global $conf; return end(explode($dir . '/', $fn, 2)); } switch ($argv[1]) { case 'cleanID': echo cleanID($argv[2]); break; case 'wikiFN': if ($argc > 3 && $argv[3]) { echo strip_dir($conf['olddir'], wikiFN($argv[2], $argv[3])); } else { echo strip_dir($conf['datadir'], wikiFN($argv[2])); } break; case 'mediaFN': echo strip_dir($conf['mediadir'], mediaFN($argv[2])); break; case 'metaFN': echo strip_dir($conf['metadir'], metaFN($argv[2], $argv[3])); break; case 'getNS': echo getNS($argv[2]); break; case 'getId': echo getId(); break; default: die("Unknown knob: {$argv[1]}"); }
function buildfilelink($ext, $prefix = '') { $ret['id'] = $prefix . $this->_pageid . '.' . $ext; $ret['file'] = mediaFN($ret['id']); $ret['link'] = ml($ret['id']); return $ret; }
/** * Returns a full media id * * @author Andreas Gohr <*****@*****.**> */ function resolve_mediaid($ns, &$page, &$exists) { $page = resolve_id($ns, $page); $file = mediaFN($page); $exists = @file_exists($file); }