Пример #1
0
 /**
  * When we display a namespace, we want to:
  * - link to it's main page (if such a page exists)
  * - get the id of this main page (if the option is active)
  *
  * @param         $ns  A structure which represents a namespace
  */
 function prepareFile(&$ns)
 {
     $idMainPage = $this->getMainPageId($ns);
     $ns['title'] = $this->buildTitle($idMainPage, noNS($ns['id']));
     $ns['id'] = $this->buildIdToLinkTo($idMainPage, $ns['id']);
     $ns['sort'] = $this->buildSortAttribute($ns['title'], $ns['id'], $ns['mtime']);
 }
Пример #2
0
 function saved(&$event, $param)
 {
     global $ID;
     global $PROJECTS_REMAKE;
     if (auth_quickaclcheck($ID) <= AUTH_READ) {
         return;
     }
     $project = Project::project();
     if ($project == NULL) {
         return;
     }
     $file = $event->data['current']['ProjectFile'];
     $name = noNS($ID);
     if ($file == NULL) {
         // check whether the file is deleted
         if ($project->file($name) == NULL) {
             return;
         }
         // it was int he project
         if (!$project->remove_file($name)) {
             msg('Other users are currently updating the project. Please save this page later.');
             $evemt->data['current']['internal']['cache'] = false;
         }
         return;
     }
     if (!$project->update_file($file)) {
         msg('Other users are currently updating the project. Please save this page later.');
         $evemt->data['current']['internal']['cache'] = false;
     }
 }
Пример #3
0
/**
 * Searches for matching pagenames
 *
 * @author Andreas Gohr <*****@*****.**>
 */
function ajax_qsearch()
{
    global $conf;
    global $lang;
    $query = cleanID($_POST['q']);
    if (empty($query)) {
        $query = cleanID($_GET['q']);
    }
    if (empty($query)) {
        return;
    }
    require_once DOKU_INC . 'inc/html.php';
    require_once DOKU_INC . 'inc/fulltext.php';
    $data = array();
    $data = ft_pageLookup($query);
    if (!count($data)) {
        return;
    }
    print '<strong>' . $lang['quickhits'] . '</strong>';
    print '<ul>';
    foreach ($data as $id) {
        print '<li>';
        $ns = getNS($id);
        if ($ns) {
            $name = shorten(noNS($id), ' (' . $ns . ')', 30);
        } else {
            $name = $id;
        }
        print html_wikilink(':' . $id, $name);
        print '</li>';
    }
    print '</ul>';
}
 function pagefromtemplate(&$event, $param)
 {
     if (strlen(trim($_REQUEST['newpagetemplate'])) > 0) {
         global $conf;
         global $INFO;
         global $ID;
         $tpl = io_readFile(wikiFN($_REQUEST['newpagetemplate']));
         if ($this->getConf('userreplace')) {
             $stringvars = array_map(create_function('$v', 'return explode(",",$v,2);'), explode(';', $_REQUEST['newpagevars']));
             foreach ($stringvars as $value) {
                 $tpl = str_replace(trim($value[0]), trim($value[1]), $tpl);
             }
         }
         if ($this->getConf('standardreplace')) {
             // replace placeholders
             $file = noNS($ID);
             $page = strtr($file, '_', ' ');
             $tpl = str_replace(array('@ID@', '@NS@', '@FILE@', '@!FILE@', '@!FILE!@', '@PAGE@', '@!PAGE@', '@!!PAGE@', '@!PAGE!@', '@USER@', '@NAME@', '@MAIL@', '@DATE@'), array($ID, getNS($ID), $file, utf8_ucfirst($file), utf8_strtoupper($file), $page, utf8_ucfirst($page), utf8_ucwords($page), utf8_strtoupper($page), $_SERVER['REMOTE_USER'], $INFO['userinfo']['name'], $INFO['userinfo']['mail'], $conf['dformat']), $tpl);
             // we need the callback to work around strftime's char limit
             $tpl = preg_replace_callback('/%./', create_function('$m', 'return strftime($m[0]);'), $tpl);
         }
         $event->result = $tpl;
         $event->preventDefault();
     }
 }
Пример #5
0
 private function buildSortAttribute($pageTitle, $pageId)
 {
     if ($this->sortPageById) {
         return noNS($pageId);
     } else {
         return $pageTitle;
     }
 }
Пример #6
0
 /**
  * The constructor, this creates a new project.
  * Taking an array that specifies the path a project.
  * This array is created from the wiki namespace path
  */
 public function __construct($ID)
 {
     $this->ID = $ID;
     $this->project_path = DOKU_DATA . implode('/', explode(":", $ID)) . '/';
     $this->project_file = $this->project_path . noNS($this->ID) . '.project';
     $this->mutex = new Mutex($this->project_file);
     $this->version_string = PROJECTS_VERSION;
     $this->create();
 }
Пример #7
0
 /**
  * Sets a new title in the database;
  *
  * @param string|null $title set null to derive from PID
  */
 public function setTitle($title)
 {
     if ($title === null) {
         $title = noNS($this->pid);
     }
     // only one of these will succeed
     $sql = "UPDATE OR IGNORE titles SET title = ? WHERE pid = ?";
     $this->sqlite->query($sql, array($title, $this->pid));
     $sql = "INSERT OR IGNORE INTO titles (title, pid) VALUES (?,?)";
     $this->sqlite->query($sql, array($title, $this->pid));
     $this->title = $title;
 }
function indexmenu_search_index(&$data, $base, $file, $type, $lvl, $opts)
{
    global $conf;
    $ret = true;
    $item = array();
    if ($type == 'f' && !preg_match('#\\.txt$#', $file)) {
        // don't add
        return false;
    }
    // get page id by filename
    $id = pathID($file);
    // check hiddens
    if ($type == 'f' && isHiddenPage($id)) {
        return false;
    }
    //  bugfix for the
    //  /ns/
    //  /<ns>.txt
    //  case, need to force the 'directory' type
    if ($type == 'f' && file_exists(dirname(wikiFN($id . ":" . noNS($id))))) {
        $type = 'd';
    }
    // page target id = global id
    $target = $id;
    if ($type == 'd') {
        // this will check 3 kinds of headpage:
        // 1. /<ns>/<ns>.txt
        // 2. /<ns>/
        //    /<ns>.txt
        // 3. /<ns>/
        //    /<ns>/<start_page>
        $nsa = array($id . ":" . noNS($id), $id, $id . ":" . $conf['start']);
        $nspage = false;
        foreach ($nsa as $nsp) {
            if (@file_exists(wikiFN($nsp)) && auth_quickaclcheck($nsp) >= AUTH_READ) {
                $nspage = $nsp;
                break;
            }
        }
        //headpage exists
        if ($nspage) {
            $target = $nspage;
        } else {
            // open namespace index, if headpage does not exists
            $target = $target . ':';
        }
    }
    $data[] = array('id' => $id, 'date' => @filectime(wikiFN($target)), 'type' => $type, 'target' => $target, 'title' => $conf['useheading'] && ($title = p_get_first_heading($target)) ? $title : $id, 'level' => $lvl);
    if (substr_count($id, ":") > 2) {
        $ret = 0;
    }
    return $ret;
}
Пример #9
0
 /**
  * Check if the user wants a file to be displayed.
  * Filters consider the "id" and not the "title". Therefore, the treatment is the same for files and for subnamespace.
  * Moreover, filters remain valid even if the title of a page is changed.
  *
  * @param Array  $excludedFiles  A list of files that shouldn't be displayed
  * @param string $file
  * @return bool
  */
 function isFileWanted($file) {
     $wanted = true;
     $noNSId = noNS($file['id']);
     $wanted &= (!in_array($noNSId, $this->excludedFiles));
     foreach($this->pregOn as $preg) {
         $wanted &= preg_match($preg, $noNSId);
     }
     foreach($this->pregOff as $preg) {
         $wanted &= !preg_match($preg, $noNSId);
     }
     return $wanted;
 }
Пример #10
0
 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;
 }
Пример #11
0
 public function xhtml()
 {
     global $ID;
     $ns = getNS($ID);
     list($files, $subprojects) = Projects_file::project_files($ns);
     $generated = array();
     $source = array();
     foreach ($files as $id => $file) {
         if ($file->type() == 'source') {
             $source[$id] = $file;
         } elseif ($file->type() == 'generated') {
             $generated[$id] = $file;
         }
     }
     ksort($generated);
     ksort($source);
     sort($subprojects);
     echo '<h1>Source files</h1>' . DOKU_LF;
     echo '<ul>' . DOKU_LF;
     echo '<li>' . create_button('source') . '</li>' . DOKU_LF;
     foreach ($source as $id => $file) {
         echo '<li>' . html_wikilink($id) . ': ' . download_button($id) . ', ' . delete_button($id) . '</li>' . DOKU_LF;
     }
     echo '</ul>' . DOKU_LF;
     echo '<h1>Generated files</h1>' . DOKU_LF;
     echo '<ul>' . DOKU_LF;
     echo '<li>' . create_button('generated') . '</li>' . DOKU_LF;
     foreach ($generated as $id => $file) {
         $make = make_button($id, $file->status() == PROJECTS_MADE);
         echo '<li>' . html_wikilink($id) . ': ' . download_button($id) . ', ' . delete_button($id) . ', ' . $make . '</li>' . DOKU_LF;
     }
     echo '</ul>' . DOKU_LF;
     echo '<h1>Subprojects</h1>' . DOKU_LF;
     echo '<ul>' . DOKU_LF;
     echo '<li>' . create_button($ID, 'project') . '</li>' . DOKU_LF;
     foreach ($subprojects as $sub) {
         echo '<li><a href="' . wl($sub . ':', array('do' => 'manage_files')) . '">' . noNS($sub) . '</a></li>' . DOKU_LF;
     }
     echo '</ul>' . DOKU_LF;
     if ($ns) {
         $name = getNS($ns);
         $id = $name . ':';
         if (!$name) {
             $id = '/';
             $name = '/ (root)';
         }
         echo '<h1>Parent projects</h1>' . DOKU_LF;
         echo '<ul><li><a href="' . wl($id, array('do' => 'manage_files')) . '">' . $name . '</a></li></ul>' . DOKU_LF;
     }
 }
Пример #12
0
 public function handle_common_pagetpl_load(Doku_Event &$event, $param)
 {
     global $conf;
     if (empty($event->data['tplfile'])) {
         $path = dirname(wikiFN($event->data['id']));
         $len = strlen(rtrim($conf['datadir'], '/'));
         $dir = substr($path, strrpos($path, '/') + 1);
         $blnFirst = true;
         $blnFirstDir = true;
         while (strLen($path) >= $len) {
             if ($blnFirst == true && @file_exists($path . '/_' . noNS($event->data['id']) . '.txt')) {
                 $event->data['tplfile'] = $path . '/_' . noNS($event->data['id'] . '.txt');
                 break;
             } elseif (@file_exists($path . '/__' . noNS($event->data['id']) . '.txt')) {
                 $event->data['tplfile'] = $path . '/__' . noNS($event->data['id'] . '.txt');
                 break;
             } elseif ($blnFirst == true && @file_exists($path . '/_template.txt')) {
                 $event->data['tplfile'] = $path . '/_template.txt';
                 break;
             } elseif ($blnFirst == false && $blnFirstDir == true && @file_exists($path . '/~_' . $dir . '.txt') && noNS($event->data['id']) == 'start') {
                 $event->data['tplfile'] = $path . '/~_' . $dir . '.txt';
                 break;
             } elseif ($blnFirst == false && $blnFirstDir == true && @file_exists($path . '/~' . $dir . '.txt')) {
                 $event->data['tplfile'] = $path . '/~' . $dir . '.txt';
                 break;
             } elseif ($blnFirst == false && @file_exists($path . '/~~_' . $dir . '.txt') && noNS($event->data['id']) == 'start') {
                 $event->data['tplfile'] = $path . '/~~_' . $dir . '.txt';
                 break;
             } elseif ($blnFirst == false && @file_exists($path . '/~~' . $dir . '.txt')) {
                 $event->data['tplfile'] = $path . '/~~' . $dir . '.txt';
                 break;
             } elseif (@file_exists($path . '/__template.txt')) {
                 $event->data['tplfile'] = $path . '/__template.txt';
                 break;
             }
             $path = substr($path, 0, strrpos($path, '/'));
             if ($blnFirst == false) {
                 $blnFirstDir = false;
             }
             $blnFirst = false;
         }
     }
 }
Пример #13
0
 private function show()
 {
     global $REV;
     global $ID;
     $path = wikiFN($ID);
     if (file_exists($path) || $REV) {
         return FALSE;
     }
     ob_start();
     echo '<h1>Page "' . noNS($ID) . '" Does Not Exist</h1>' . DOKU_LF;
     echo '<ul><li>Create a:</li>' . DOKU_LF;
     echo '<ul>' . DOKU_LF;
     echo '<li><a href="' . wl($ID, array('do' => 'create', 'type' => 'source')) . '">' . 'source file</a></li>' . DOKU_LF;
     echo '<li><a href="' . wl($ID, array('do' => 'create', 'type' => 'generated')) . '">' . 'generated file</a></li>' . DOKU_LF;
     echo '<li><a href="' . wl($ID, array('do' => 'edit')) . '">' . 'plain wiki page</a></li>' . DOKU_LF;
     echo '</ul>' . DOKU_LF;
     echo '<li>Manage <a href="' . wl($ID, array('do' => 'manage_files')) . '">other files</a></li>' . DOKU_LF;
     echo '</ul>' . DOKU_LF;
     trigger_event('TPL_CONTENT_DISPLAY', $html_output, 'ptln');
     return TRUE;
 }
 /**
  * Saves the name of the uploaded media file to a meta file
  */
 function _saveMeta(&$event)
 {
     global $conf;
     $id = $event->data[2];
     $filename_tidy = noNS($id);
     // retrieve original filename
     if (isset($_GET['qqfile'])) {
         // via ajax uploader
         $filename_orig = (string) $_GET['qqfile'];
     } elseif (isset($_POST['mediaid'])) {
         if (isset($_FILES['qqfile']['name'])) {
             // via ajax uploader
             $filename_orig = (string) $_FILES['qqfile']['name'];
         } elseif (isset($_FILES['upload']['name'])) {
             // via old-fashioned upload form
             $filename_orig = (string) $_FILES['upload']['name'];
         } else {
             return;
         }
         // check if filename is specified
         $specified_name = (string) $_POST['mediaid'];
         if ($specified_name !== '') {
             $filename_orig = $specified_name;
         }
     } else {
         return;
     }
     $filename_safe = $this->common->_sanitizeFileName($filename_orig);
     // no need to save original filename
     if ($filename_tidy === $filename_safe) {
         return;
     }
     // fallback if suspicious characters found
     if ($filename_orig !== $filename_safe) {
         return;
     }
     // save original filename to meta file
     io_saveFile(mediaMetaFN($id, '.filename'), serialize(array('filename' => $filename_safe)));
 }
Пример #15
0
    public function test_movePageWithRelativeMedia() {
        global $ID;

        $ID = 'mediareltest:foo';
        saveWikiText($ID,
            '{{ myimage.png}} [[:start|{{ testimage.png?200x800 }}]] [[bar|{{testimage.gif?400x200}}]]
[[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{testimage.jpg}}]]
[[doku>wiki:foo|{{foo.gif?200x3000}}]]', 'Test setup');
        idx_addPage($ID);

        $opts = array();
        $opts['ns']   = getNS($ID);
        $opts['name'] = noNS($ID);
        $opts['newns'] = '';
        $opts['newname'] = 'foo';
        /** @var helper_plugin_move $move */
        $move = plugin_load('helper', 'move');
        $this->assertTrue($move->move_page($opts));

        $this->assertEquals('{{ mediareltest:myimage.png}} [[:start|{{ mediareltest:testimage.png?200x800 }}]] [[mediareltest:bar|{{mediareltest:testimage.gif?400x200}}]]
[[doku>wiki:dokuwiki|{{wiki:logo.png}}]] [[http://www.example.com|{{mediareltest:testimage.jpg}}]]
[[doku>wiki:foo|{{mediareltest:foo.gif?200x3000}}]]', rawWiki('foo'));
    }
Пример #16
0
 private function button_rename_use($range)
 {
     global $ID;
     if (auth_quickaclcheck($ID) < AUTH_EDIT) {
         return '';
     }
     $self = noNS($ID);
     $project = Project::project();
     if ($project == NULL) {
         return '';
     }
     $files = array('');
     foreach (array_keys($project->files()) as $file) {
         if ($file != $self) {
             $files[] = $file;
         }
     }
     $form = new Doku_Form("change_use");
     $form->addHidden('do', 'change_use');
     $form->addHidden('range', $range);
     $form->addElement(form_makeMenuField('use', $files, '', '', '', '', array("onchange" => "submit();")));
     return $form->getForm();
 }
Пример #17
0
/**
 * Returns the pagetemplate contents for the ID's namespace
 *
 * @author Andreas Gohr <*****@*****.**>
 */
function pageTemplate($data)
{
    $id = $data[0];
    global $conf;
    global $INFO;
    $tpl = io_readFile(dirname(wikiFN($id)) . '/_template.txt');
    $tpl = str_replace('@ID@', $id, $tpl);
    $tpl = str_replace('@NS@', getNS($id), $tpl);
    $tpl = str_replace('@PAGE@', strtr(noNS($id), '_', ' '), $tpl);
    $tpl = str_replace('@USER@', $_SERVER['REMOTE_USER'], $tpl);
    $tpl = str_replace('@NAME@', $INFO['userinfo']['name'], $tpl);
    $tpl = str_replace('@MAIL@', $INFO['userinfo']['mail'], $tpl);
    $tpl = str_replace('@DATE@', date($conf['dformat']), $tpl);
    return $tpl;
}
Пример #18
0
/**
 * Run a search and display the result
 *
 * @author Andreas Gohr <*****@*****.**>
 */
function html_search()
{
    global $conf;
    global $QUERY;
    global $ID;
    global $lang;
    $intro = p_locale_xhtml('searchpage');
    // allow use of placeholder in search intro
    $intro = str_replace(array('@QUERY@', '@SEARCH@'), array(hsc(rawurlencode($QUERY)), hsc($QUERY)), $intro);
    echo $intro;
    flush();
    //show progressbar
    print '<div class="centeralign" id="dw__loading">' . NL;
    print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL;
    print 'showLoadBar();' . NL;
    print '//--><!]]></script>' . NL;
    print '<br /></div>' . NL;
    flush();
    //do quick pagesearch
    $data = array();
    $data = ft_pageLookup($QUERY, true, useHeading('navigation'));
    if (count($data)) {
        print '<div class="search_quickresult">';
        print '<h3>' . $lang['quickhits'] . ':</h3>';
        print '<ul class="search_quickhits">';
        foreach ($data as $id => $title) {
            print '<li> ';
            if (useHeading('navigation')) {
                $name = $title;
            } else {
                $ns = getNS($id);
                if ($ns) {
                    $name = shorten(noNS($id), ' (' . $ns . ')', 30);
                } else {
                    $name = $id;
                }
            }
            print html_wikilink(':' . $id, $name);
            print '</li> ';
        }
        print '</ul> ';
        //clear float (see http://www.complexspiral.com/publications/containing-floats/)
        print '<div class="clearer"></div>';
        print '</div>';
    }
    flush();
    //do fulltext search
    $data = ft_pageSearch($QUERY, $regex);
    if (count($data)) {
        $num = 1;
        foreach ($data as $id => $cnt) {
            print '<div class="search_result">';
            print html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $regex);
            if ($cnt !== 0) {
                print ': <span class="search_cnt">' . $cnt . ' ' . $lang['hits'] . '</span><br />';
                if ($num < FT_SNIPPET_NUMBER) {
                    // create snippets for the first number of matches only
                    print '<div class="search_snippet">' . ft_snippet($id, $regex) . '</div>';
                }
                $num++;
            }
            print '</div>';
            flush();
        }
    } else {
        print '<div class="nothing">' . $lang['nothingfound'] . '</div>';
    }
    //hide progressbar
    print '<script type="text/javascript" charset="utf-8"><!--//--><![CDATA[//><!--' . NL;
    print 'hideLoadBar("dw__loading");' . NL;
    print '//--><!]]></script>' . NL;
    flush();
}
Пример #19
0
 /**
  * Embed audio in HTML
  *
  * @author Anika Henke <*****@*****.**>
  *
  * @param string $src       - ID of audio to embed
  * @param array  $atts      - additional attributes for the <audio> tag
  * @return string
  */
 function _audio($src, $atts = array())
 {
     $files = array();
     $isExternal = media_isexternal($src);
     if ($isExternal) {
         // take direct source for external files
         list(, $srcMime) = mimetype($src);
         $files[$srcMime] = $src;
     } else {
         // prepare alternative formats
         $extensions = array('ogg', 'mp3', 'wav');
         $files = media_alternativefiles($src, $extensions);
     }
     $out = '';
     // open audio tag
     $out .= '<audio ' . buildAttributes($atts) . ' controls="controls">' . NL;
     $fallback = '';
     // output source for each alternative audio format
     foreach ($files as $mime => $file) {
         if ($isExternal) {
             $url = $file;
             $linkType = 'externalmedia';
         } else {
             $url = ml($file, '', true, '&');
             $linkType = 'internalmedia';
         }
         $title = $atts['title'] ? $atts['title'] : $this->_xmlEntities(utf8_basename(noNS($file)));
         $out .= '<source src="' . hsc($url) . '" type="' . $mime . '" />' . NL;
         // alternative content (just a link to the file)
         $fallback .= $this->{$linkType}($file, $title, null, null, null, $cache = null, $linking = 'linkonly', $return = true);
     }
     // finish
     $out .= $fallback;
     $out .= '</audio>' . NL;
     return $out;
 }
Пример #20
0
 /**
  * Returns a list of pages with a certain tag; very similar to ft_backlinks()
  *
  * @param string $ns A namespace to which all pages need to belong, "." for only the root namespace
  * @param int    $num The maximum number of pages that shall be returned
  * @param string $tag The tag that shall be searched
  * @return array The list of pages
  *
  * @author  Esther Brunner <*****@*****.**>
  */
 function getTopic($ns = '', $num = NULL, $tag = '')
 {
     if (!$tag) {
         $tag = $_REQUEST['tag'];
     }
     $tag = $this->_parseTagList($tag, true);
     $result = array();
     // find the pages using topic.idx
     $pages = $this->_tagIndexLookup($tag);
     if (!count($pages)) {
         return $result;
     }
     foreach ($pages as $page) {
         // exclude pages depending on ACL and namespace
         if ($this->_notVisible($page, $ns)) {
             continue;
         }
         $tags = $this->_getSubjectMetadata($page);
         // don't trust index
         if (!$this->_checkPageTags($tags, $tag)) {
             continue;
         }
         // get metadata
         $meta = p_get_metadata($page);
         $perm = auth_quickaclcheck($page);
         // skip drafts unless for users with create privilege
         $draft = $meta['type'] == 'draft';
         if ($draft && $perm < AUTH_CREATE) {
             continue;
         }
         $title = $meta['title'];
         $date = $this->sort == 'mdate' ? $meta['date']['modified'] : $meta['date']['created'];
         $taglinks = $this->tagLinks($tags);
         // determine the sort key
         if ($this->sort == 'id') {
             $key = $page;
         } elseif ($this->sort == 'ns') {
             $pos = strrpos($page, ':');
             if ($pos === false) {
                 $key = "" . $page;
             } else {
                 $key = substr_replace($page, "", $pos, 1);
             }
             $key = str_replace(':', "", $key);
         } elseif ($this->sort == 'pagename') {
             $key = noNS($page);
         } elseif ($this->sort == 'title') {
             $key = utf8_strtolower($title);
             if (empty($key)) {
                 $key = str_replace('_', ' ', noNS($page));
             }
         } else {
             $key = $date;
         }
         // make sure that the key is unique
         $key = $this->_uniqueKey($key, $result);
         $result[$key] = array('id' => $page, 'title' => $title, 'date' => $date, 'user' => $meta['creator'], 'desc' => $meta['description']['abstract'], 'cat' => $tags[0], 'tags' => $taglinks, 'perm' => $perm, 'exists' => true, 'draft' => $draft);
         if ($num && count($result) >= $num) {
             break;
         }
     }
     // finally sort by sort key
     if ($this->getConf('sortorder') == 'ascending') {
         ksort($result);
     } else {
         krsort($result);
     }
     return $result;
 }
Пример #21
0
 /**
  * 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);
 }
Пример #22
0
 /**
  * Print a toc preview
  *
  * @author Samuele Tognini <*****@*****.**>
  * @author Andreas Gohr <*****@*****.**>
  */
 function print_toc($id)
 {
     require_once DOKU_INC . 'inc/parser/xhtml.php';
     $id = cleanID($id);
     if (auth_quickaclcheck($id) < AUTH_READ) {
         return;
     }
     $meta = p_get_metadata($id);
     $toc = $meta['description']['tableofcontents'];
     $out .= '<div class="tocheader toctoggle">' . DOKU_LF;
     if (count($toc) > 1) {
         $out .= $this->render_toc($toc);
     } else {
         $out .= '<a href="' . wl($id) . '">';
         $out .= $meta['title'] ? htmlspecialchars($meta['title']) : htmlspecialchars(noNS($id));
         $out .= '</a>' . DOKU_LF;
         if ($meta['description']['abstract']) {
             $out .= '</div>' . DOKU_LF;
             $out .= '<div class="indexmenu_toc_inside">' . DOKU_LF;
             $out .= p_render('xhtml', p_get_instructions($meta['description']['abstract']), $info);
             $out .= '</div>' . DOKU_LF;
         }
     }
     $out .= '</div>' . DOKU_LF;
     return $out;
 }
Пример #23
0
/**
 * List matching namespaces and pages for the link wizard
 *
 * @author Andreas Gohr <*****@*****.**>
 */
function ajax_linkwiz()
{
    global $conf;
    global $lang;
    $q = ltrim($_POST['q'], ':');
    $id = noNS($q);
    $ns = getNS($q);
    $ns = cleanID($ns);
    $id = cleanID($id);
    $nsd = utf8_encodeFN(str_replace(':', '/', $ns));
    $idd = utf8_encodeFN(str_replace(':', '/', $id));
    $data = array();
    if ($q && !$ns) {
        // use index to lookup matching pages
        $pages = array();
        $pages = ft_pageLookup($id, true);
        // result contains matches in pages and namespaces
        // we now extract the matching namespaces to show
        // them seperately
        $dirs = array();
        foreach ($pages as $pid => $title) {
            if (strpos(noNS($pid), $id) === false) {
                // match was in the namespace
                $dirs[getNS($pid)] = 1;
                // assoc array avoids dupes
            } else {
                // it is a matching page, add it to the result
                $data[] = array('id' => $pid, 'title' => $title, 'type' => 'f');
            }
            unset($pages[$pid]);
        }
        foreach ($dirs as $dir => $junk) {
            $data[] = array('id' => $dir, 'type' => 'd');
        }
    } else {
        $opts = array('depth' => 1, 'listfiles' => true, 'listdirs' => true, 'pagesonly' => true, 'firsthead' => true, 'sneakyacl' => $conf['sneaky_index']);
        if ($id) {
            $opts['filematch'] = '^.*\\/' . $id;
        }
        if ($id) {
            $opts['dirmatch'] = '^.*\\/' . $id;
        }
        search($data, $conf['datadir'], 'search_universal', $opts, $nsd);
        // add back to upper
        if ($ns) {
            array_unshift($data, array('id' => getNS($ns), 'type' => 'u'));
        }
    }
    // fixme sort results in a useful way ?
    if (!count($data)) {
        echo $lang['nothingfound'];
        exit;
    }
    // output the found data
    $even = 1;
    foreach ($data as $item) {
        $even *= -1;
        //zebra
        if (($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) {
            $item['id'] .= ':';
        }
        $link = wl($item['id']);
        echo '<div class="' . ($even > 0 ? 'even' : 'odd') . ' type_' . $item['type'] . '">';
        if ($item['type'] == 'u') {
            $name = $lang['upperns'];
        } else {
            $name = htmlspecialchars($item['id']);
        }
        echo '<a href="' . $link . '" title="' . htmlspecialchars($item['id']) . '" class="wikilink1">' . $name . '</a>';
        if ($item['title']) {
            echo '<span>' . htmlspecialchars($item['title']) . '</span>';
        }
        echo '</div>';
    }
}
Пример #24
0
 /**
  * Item formatter for the tree view
  *
  * User function for html_buildlist()
  *
  * @author Andreas Gohr <*****@*****.**>
  */
 function _html_list_acl($item)
 {
     global $ID;
     $ret = '';
     // what to display
     if ($item['label']) {
         $base = $item['label'];
     } else {
         $base = ':' . $item['id'];
         $base = substr($base, strrpos($base, ':') + 1);
     }
     // highlight?
     if ($item['type'] == $this->current_item['type'] && $item['id'] == $this->current_item['id']) {
         $cl = ' cur';
     }
     // namespace or page?
     if ($item['type'] == 'd') {
         if ($item['open']) {
             $img = DOKU_BASE . 'lib/images/minus.gif';
             $alt = '−';
         } else {
             $img = DOKU_BASE . 'lib/images/plus.gif';
             $alt = '+';
         }
         $ret .= '<img src="' . $img . '" alt="' . $alt . '" />';
         $ret .= '<a href="' . wl('', $this->_get_opts(array('ns' => $item['id'], 'sectok' => getSecurityToken()))) . '" class="idx_dir' . $cl . '">';
         $ret .= $base;
         $ret .= '</a>';
     } else {
         $ret .= '<a href="' . wl('', $this->_get_opts(array('id' => $item['id'], 'ns' => '', 'sectok' => getSecurityToken()))) . '" class="wikilink1' . $cl . '">';
         $ret .= noNS($item['id']);
         $ret .= '</a>';
     }
     return $ret;
 }
Пример #25
0
/**
 * Index item formatter
 *
 * User function for html_buildlist()
 *
 * @author Andreas Gohr <*****@*****.**>
 *
 * @param array $item
 * @return string
 */
function html_list_index($item)
{
    global $ID, $conf;
    // prevent searchbots needlessly following links
    $nofollow = $ID != $conf['start'] || $conf['sitemap'] ? ' rel="nofollow"' : '';
    $ret = '';
    $base = ':' . $item['id'];
    $base = substr($base, strrpos($base, ':') + 1);
    if ($item['type'] == 'd') {
        // FS#2766, no need for search bots to follow namespace links in the index
        $ret .= '<a href="' . wl($ID, 'idx=' . rawurlencode($item['id'])) . '" title="' . $item['id'] . '" class="idx_dir"' . $nofollow . '><strong>';
        $ret .= $base;
        $ret .= '</strong></a>';
    } else {
        // default is noNSorNS($id), but we want noNS($id) when useheading is off FS#2605
        $ret .= html_wikilink(':' . $item['id'], useHeading('navigation') ? null : noNS($item['id']));
    }
    return $ret;
}
Пример #26
0
 /**
  * Renders internal and external media
  *
  * @author Andreas Gohr <*****@*****.**>
  */
 function _media($src, $title = NULL, $align = NULL, $width = NULL, $height = NULL, $cache = NULL, $render = true)
 {
     $ret = '';
     list($ext, $mime, $dl) = 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 ($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)) . '"';
         $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 ($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;
 }
Пример #27
0
function _ft_pageLookup(&$data)
{
    // split out original parameterrs
    $id = $data['id'];
    $pageonly = $data['pageonly'];
    global $conf;
    $id = preg_quote($id, '/');
    $pages = file($conf['indexdir'] . '/page.idx');
    if ($id) {
        $pages = array_values(preg_grep('/' . $id . '/', $pages));
    }
    $cnt = count($pages);
    for ($i = 0; $i < $cnt; $i++) {
        if ($pageonly) {
            if (!preg_match('/' . $id . '/', noNS($pages[$i]))) {
                unset($pages[$i]);
                continue;
            }
        }
        if (!page_exists($pages[$i])) {
            unset($pages[$i]);
            continue;
        }
    }
    $pages = array_filter($pages, 'isVisiblePage');
    // discard hidden pages
    if (!count($pages)) {
        return array();
    }
    // check ACL permissions
    foreach (array_keys($pages) as $idx) {
        if (auth_quickaclcheck(trim($pages[$idx])) < AUTH_READ) {
            unset($pages[$idx]);
        }
    }
    $pages = array_map('trim', $pages);
    usort($pages, 'ft_pagesorter');
    return $pages;
}
Пример #28
0
echo DOKU_TPL;
?>
design.css" />
</head>

<body>
<div class="dokuwiki">
  <?php 
html_msgarea();
?>

  <h1><?php 
echo hsc($lang['metaedit']);
?>
 <code><?php 
echo hsc(noNS($IMG));
?>
</code></h1>

  <div class="mediaedit">
		<?php 
?>
<?php/* everything in meta array is tried to save and read */?>

 		<div class="data">
			<form action="<?php 
echo DOKU_BASE;
?>
lib/exe/media.php" accept-charset="utf-8" method="post">
				<input type="hidden" name="edit" value="<?php 
echo hsc($IMG);
Пример #29
0
/**
 * Returns the pages that use a given media file
 *
 * Does a quick lookup with the fulltext index, then
 * evaluates the instructions of the found pages
 *
 * Aborts after $max found results
 */
function ft_mediause($id, $max)
{
    if (!$max) {
        $max = 1;
    }
    // need to find at least one
    $result = array();
    // quick lookup of the mediafile
    // FIXME use metadata key lookup
    $media = noNS($id);
    $matches = idx_lookup(idx_tokenizer($media));
    $docs = array_keys(ft_resultCombine(array_values($matches)));
    if (!count($docs)) {
        return $result;
    }
    // go through all found pages
    $found = 0;
    $pcre = preg_quote($media, '/');
    foreach ($docs as $doc) {
        $ns = getNS($doc);
        preg_match_all('/\\{\\{([^|}]*' . $pcre . '[^|}]*)(|[^}]+)?\\}\\}/i', rawWiki($doc), $matches);
        foreach ($matches[1] as $img) {
            $img = trim($img);
            if (preg_match('/^https?:\\/\\//i', $img)) {
                continue;
            }
            // skip external images
            list($img) = explode('?', $img);
            // remove any parameters
            resolve_mediaid($ns, $img, $exists);
            // resolve the possibly relative img
            if ($img == $id) {
                // we have a match
                $result[] = $doc;
                $found++;
                break;
            }
        }
        if ($found >= $max) {
            break;
        }
    }
    sort($result);
    return $result;
}
Пример #30
0
/**
 * Saves a wikitext by calling io_writeWikiPage.
 * Also directs changelog and attic updates.
 *
 * @author Andreas Gohr <*****@*****.**>
 * @author Ben Coburn <*****@*****.**>
 */
function saveWikiText($id, $text, $summary, $minor = false)
{
    /* Note to developers:
         This code is subtle and delicate. Test the behavior of
         the attic and changelog with dokuwiki and external edits
         after any changes. External edits change the wiki page
         directly without using php or dokuwiki.
       */
    global $conf;
    global $lang;
    global $REV;
    // ignore if no changes were made
    if ($text == rawWiki($id, '')) {
        return;
    }
    $file = wikiFN($id);
    $old = @filemtime($file);
    // from page
    $wasRemoved = trim($text) == '';
    // check for empty or whitespace only
    $wasCreated = !@file_exists($file);
    $wasReverted = $REV == true;
    $newRev = false;
    $oldRev = getRevisions($id, -1, 1, 1024);
    // from changelog
    $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
    if (!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old >= $oldRev) {
        // add old revision to the attic if missing
        saveOldRevision($id);
        // add a changelog entry if this edit came from outside dokuwiki
        if ($old > $oldRev) {
            addLogEntry($old, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit' => true));
            // remove soon to be stale instructions
            $cache = new cache_instructions($id, $file);
            $cache->removeCache();
        }
    }
    if ($wasRemoved) {
        // Send "update" event with empty data, so plugins can react to page deletion
        $data = array(array($file, '', false), getNS($id), noNS($id), false);
        trigger_event('IO_WIKIPAGE_WRITE', $data);
        // pre-save deleted revision
        @touch($file);
        clearstatcache();
        $newRev = saveOldRevision($id);
        // remove empty file
        @unlink($file);
        // don't remove old meta info as it should be saved, plugins can use IO_WIKIPAGE_WRITE for removing their metadata...
        // purge non-persistant meta data
        p_purge_metadata($id);
        $del = true;
        // autoset summary on deletion
        if (empty($summary)) {
            $summary = $lang['deleted'];
        }
        // remove empty namespaces
        io_sweepNS($id, 'datadir');
        io_sweepNS($id, 'mediadir');
    } else {
        // save file (namespace dir is created in io_writeWikiPage)
        io_writeWikiPage($file, $text, $id);
        // pre-save the revision, to keep the attic in sync
        $newRev = saveOldRevision($id);
        $del = false;
    }
    // select changelog line type
    $extra = '';
    $type = DOKU_CHANGE_TYPE_EDIT;
    if ($wasReverted) {
        $type = DOKU_CHANGE_TYPE_REVERT;
        $extra = $REV;
    } else {
        if ($wasCreated) {
            $type = DOKU_CHANGE_TYPE_CREATE;
        } else {
            if ($wasRemoved) {
                $type = DOKU_CHANGE_TYPE_DELETE;
            } else {
                if ($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) {
                    $type = DOKU_CHANGE_TYPE_MINOR_EDIT;
                }
            }
        }
    }
    //minor edits only for logged in users
    addLogEntry($newRev, $id, $type, $summary, $extra);
    // send notify mails
    notify($id, 'admin', $old, $summary, $minor);
    notify($id, 'subscribers', $old, $summary, $minor);
    // update the purgefile (timestamp of the last time anything within the wiki was changed)
    io_saveFile($conf['cachedir'] . '/purgefile', time());
    // if useheading is enabled, purge the cache of all linking pages
    if (useHeading('content')) {
        $pages = ft_backlinks($id);
        foreach ($pages as $page) {
            $cache = new cache_renderer($page, wikiFN($page), 'xhtml');
            $cache->removeCache();
        }
    }
}