diff options
Diffstat (limited to 'lib/exe')
-rw-r--r-- | lib/exe/ajax.php | 458 | ||||
-rw-r--r-- | lib/exe/css.php | 90 | ||||
-rw-r--r-- | lib/exe/fetch.php | 2 | ||||
-rw-r--r-- | lib/exe/indexer.php | 183 | ||||
-rw-r--r-- | lib/exe/js.php | 5 | ||||
-rw-r--r-- | lib/exe/mediamanager.php | 22 | ||||
-rw-r--r-- | lib/exe/opensearch.php | 2 | ||||
-rw-r--r-- | lib/exe/xmlrpc.php | 167 |
8 files changed, 351 insertions, 578 deletions
diff --git a/lib/exe/ajax.php b/lib/exe/ajax.php index e9c59ca5d..7d594dc04 100644 --- a/lib/exe/ajax.php +++ b/lib/exe/ajax.php @@ -8,7 +8,7 @@ //fix for Opera XMLHttpRequests if(!count($_POST) && !empty($HTTP_RAW_POST_DATA)){ - parse_str($HTTP_RAW_POST_DATA, $_POST); + parse_str($HTTP_RAW_POST_DATA, $_POST); } if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); @@ -20,25 +20,25 @@ header('Content-Type: text/html; charset=utf-8'); //call the requested function -if(isset($_POST['call'])) - $call = $_POST['call']; -else if(isset($_GET['call'])) - $call = $_GET['call']; -else - exit; - +if(isset($_POST['call'])){ + $call = $_POST['call']; +}else if(isset($_GET['call'])){ + $call = $_GET['call']; +}else{ + exit; +} $callfn = 'ajax_'.$call; if(function_exists($callfn)){ - $callfn(); + $callfn(); }else{ - $evt = new Doku_Event('AJAX_CALL_UNKNOWN', $call); - if ($evt->advise_before()) { - print "AJAX call '".htmlspecialchars($call)."' unknown!\n"; - exit; - } - $evt->advise_after(); - unset($evt); + $evt = new Doku_Event('AJAX_CALL_UNKNOWN', $call); + if ($evt->advise_before()) { + print "AJAX call '".htmlspecialchars($call)."' unknown!\n"; + exit; + } + $evt->advise_after(); + unset($evt); } /** @@ -47,33 +47,33 @@ if(function_exists($callfn)){ * @author Andreas Gohr <andi@splitbrain.org> */ function ajax_qsearch(){ - global $conf; - global $lang; - - $query = $_POST['q']; - if(empty($query)) $query = $_GET['q']; - if(empty($query)) return; - - $data = ft_pageLookup($query, true, useHeading('navigation')); - - if(!count($data)) return; - - print '<strong>'.$lang['quickhits'].'</strong>'; - print '<ul>'; - foreach($data as $id => $title){ - if (useHeading('navigation')) { - $name = $title; - } else { - $ns = getNS($id); - if($ns){ - $name = shorten(noNS($id), ' ('.$ns.')',30); - }else{ - $name = $id; + global $conf; + global $lang; + + $query = $_POST['q']; + if(empty($query)) $query = $_GET['q']; + if(empty($query)) return; + + $data = ft_pageLookup($query, true, useHeading('navigation')); + + if(!count($data)) return; + + print '<strong>'.$lang['quickhits'].'</strong>'; + print '<ul>'; + foreach($data as $id => $title){ + if (useHeading('navigation')) { + $name = $title; + } else { + $ns = getNS($id); + if($ns){ + $name = noNS($id).' ('.$ns.')'; + }else{ + $name = $id; + } } + echo '<li>' . html_wikilink(':'.$id,$name) . '</li>'; } - echo '<li>' . html_wikilink(':'.$id,$name) . '</li>'; - } - print '</ul>'; + print '</ul>'; } /** @@ -83,36 +83,36 @@ function ajax_qsearch(){ * @author Mike Frysinger <vapier@gentoo.org> */ function ajax_suggestions() { - global $conf; - global $lang; - - $query = cleanID($_POST['q']); - if(empty($query)) $query = cleanID($_GET['q']); - if(empty($query)) return; - - $data = array(); - $data = ft_pageLookup($query); - if(!count($data)) return; - $data = array_keys($data); - - // limit results to 15 hits - $data = array_slice($data, 0, 15); - $data = array_map('trim',$data); - $data = array_map('noNS',$data); - $data = array_unique($data); - sort($data); - - /* now construct a json */ - $suggestions = array( - $query, // the original query - $data, // some suggestions - array(), // no description - array() // no urls - ); - $json = new JSON(); - - header('Content-Type: application/x-suggestions+json'); - print $json->encode($suggestions); + global $conf; + global $lang; + + $query = cleanID($_POST['q']); + if(empty($query)) $query = cleanID($_GET['q']); + if(empty($query)) return; + + $data = array(); + $data = ft_pageLookup($query); + if(!count($data)) return; + $data = array_keys($data); + + // limit results to 15 hits + $data = array_slice($data, 0, 15); + $data = array_map('trim',$data); + $data = array_map('noNS',$data); + $data = array_unique($data); + sort($data); + + /* now construct a json */ + $suggestions = array( + $query, // the original query + $data, // some suggestions + array(), // no description + array() // no urls + ); + $json = new JSON(); + + header('Content-Type: application/x-suggestions+json'); + print $json->encode($suggestions); } /** @@ -121,32 +121,32 @@ function ajax_suggestions() { * Andreas Gohr <andi@splitbrain.org> */ function ajax_lock(){ - global $conf; - global $lang; - $id = cleanID($_POST['id']); - if(empty($id)) return; - - if(!checklock($id)){ - lock($id); - echo 1; - } - - if($conf['usedraft'] && $_POST['wikitext']){ - $client = $_SERVER['REMOTE_USER']; - if(!$client) $client = clientIP(true); + global $conf; + global $lang; + $id = cleanID($_POST['id']); + if(empty($id)) return; + + if(!checklock($id)){ + lock($id); + echo 1; + } - $draft = array('id' => $id, - 'prefix' => substr($_POST['prefix'], 0, -1), - 'text' => $_POST['wikitext'], - 'suffix' => $_POST['suffix'], - 'date' => (int) $_POST['date'], - 'client' => $client, - ); - $cname = getCacheName($draft['client'].$id,'.draft'); - if(io_saveFile($cname,serialize($draft))){ - echo $lang['draftdate'].' '.dformat(); + if($conf['usedraft'] && $_POST['wikitext']){ + $client = $_SERVER['REMOTE_USER']; + if(!$client) $client = clientIP(true); + + $draft = array('id' => $id, + 'prefix' => substr($_POST['prefix'], 0, -1), + 'text' => $_POST['wikitext'], + 'suffix' => $_POST['suffix'], + 'date' => (int) $_POST['date'], + 'client' => $client, + ); + $cname = getCacheName($draft['client'].$id,'.draft'); + if(io_saveFile($cname,serialize($draft))){ + echo $lang['draftdate'].' '.dformat(); + } } - } } @@ -156,14 +156,14 @@ function ajax_lock(){ * @author Andreas Gohr <andi@splitbrain.org> */ function ajax_draftdel(){ - $id = cleanID($_REQUEST['id']); - if(empty($id)) return; + $id = cleanID($_REQUEST['id']); + if(empty($id)) return; - $client = $_SERVER['REMOTE_USER']; - if(!$client) $client = clientIP(true); + $client = $_SERVER['REMOTE_USER']; + if(!$client) $client = clientIP(true); - $cname = getCacheName($client.$id,'.draft'); - @unlink($cname); + $cname = getCacheName($client.$id,'.draft'); + @unlink($cname); } /** @@ -172,22 +172,22 @@ function ajax_draftdel(){ * @author Andreas Gohr <andi@splitbrain.org> */ function ajax_medians(){ - global $conf; - - // wanted namespace - $ns = cleanID($_POST['ns']); - $dir = utf8_encodeFN(str_replace(':','/',$ns)); - - $lvl = count(explode(':',$ns)); - - $data = array(); - search($data,$conf['mediadir'],'search_index',array('nofiles' => true),$dir); - foreach($data as $item){ - $item['level'] = $lvl+1; - echo media_nstree_li($item); - echo media_nstree_item($item); - echo '</li>'; - } + global $conf; + + // wanted namespace + $ns = cleanID($_POST['ns']); + $dir = utf8_encodeFN(str_replace(':','/',$ns)); + + $lvl = count(explode(':',$ns)); + + $data = array(); + search($data,$conf['mediadir'],'search_index',array('nofiles' => true),$dir); + foreach($data as $item){ + $item['level'] = $lvl+1; + echo media_nstree_li($item); + echo media_nstree_item($item); + echo '</li>'; + } } /** @@ -196,11 +196,11 @@ function ajax_medians(){ * @author Andreas Gohr <andi@splitbrain.org> */ function ajax_medialist(){ - global $conf; - global $NS; + global $conf; + global $NS; - $NS = $_POST['ns']; - tpl_mediaContent(true); + $NS = $_POST['ns']; + tpl_mediaContent(true); } /** @@ -209,24 +209,24 @@ function ajax_medialist(){ * @author Andreas Gohr <andi@splitbrain.org> */ function ajax_index(){ - global $conf; - - // wanted namespace - $ns = cleanID($_POST['idx']); - $dir = utf8_encodeFN(str_replace(':','/',$ns)); - - $lvl = count(explode(':',$ns)); - - $data = array(); - search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir); - foreach($data as $item){ - $item['level'] = $lvl+1; - echo html_li_index($item); - echo '<div class="li">'; - echo html_list_index($item); - echo '</div>'; - echo '</li>'; - } + global $conf; + + // wanted namespace + $ns = cleanID($_POST['idx']); + $dir = utf8_encodeFN(str_replace(':','/',$ns)); + + $lvl = count(explode(':',$ns)); + + $data = array(); + search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir); + foreach($data as $item){ + $item['level'] = $lvl+1; + echo html_li_index($item); + echo '<div class="li">'; + echo html_list_index($item); + echo '</div>'; + echo '</li>'; + } } /** @@ -235,108 +235,106 @@ function ajax_index(){ * @author Andreas Gohr <gohr@cosmocode.de> */ 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', - ); - } + global $conf; + global $lang; + + $q = ltrim(trim($_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', - )); - } - } + }else{ - // fixme sort results in a useful way ? + $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', + )); + } + } - if(!count($data)){ - echo $lang['nothingfound']; - exit; - } + // fixme sort results in a useful way ? - // output the found data - $even = 1; - foreach($data as $item){ - $even *= -1; //zebra + if(!count($data)){ + echo $lang['nothingfound']; + exit; + } - if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':'; - $link = wl($item['id']); + // output the found data + $even = 1; + foreach($data as $item){ + $even *= -1; //zebra - echo '<div class="'.(($even > 0)?'even':'odd').' type_'.$item['type'].'">'; + 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']); - } + if($item['type'] == 'u'){ + $name = $lang['upperns']; + }else{ + $name = htmlspecialchars($item['id']); + } - echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>'; + echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>'; - if($item['title']){ - echo '<span>'.htmlspecialchars($item['title']).'</span>'; + if($item['title']){ + echo '<span>'.htmlspecialchars($item['title']).'</span>'; + } + echo '</div>'; } - echo '</div>'; - } } -//Setup VIM: ex: et ts=2 enc=utf-8 : +//Setup VIM: ex: et ts=2 : diff --git a/lib/exe/css.php b/lib/exe/css.php index 76f40c7bb..03f900034 100644 --- a/lib/exe/css.php +++ b/lib/exe/css.php @@ -30,10 +30,10 @@ function css_out(){ global $lang; global $config_cascade; - $style = ''; + $mediatype = 'screen'; if (isset($_REQUEST['s']) && in_array($_REQUEST['s'], array('all', 'print', 'feed'))) { - $style = $_REQUEST['s']; + $mediatype = $_REQUEST['s']; } $tpl = trim(preg_replace('/[^\w-]+/','',$_REQUEST['t'])); @@ -46,7 +46,7 @@ function css_out(){ } // The generated script depends on some dynamic options - $cache = getCacheName('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$style,'.css'); + $cache = getCacheName('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$tplinc.$mediatype,'.css'); // load template styles $tplstyles = array(); @@ -60,27 +60,29 @@ function css_out(){ // Array of needed files and their web locations, the latter ones // are needed to fix relative paths in the stylesheets $files = array(); - //if (isset($tplstyles['all'])) $files = array_merge($files, $tplstyles['all']); - if(!empty($style)){ - $files[DOKU_INC.'lib/styles/'.$style.'.css'] = DOKU_BASE.'lib/styles/'; - // load plugin, template, user styles - $files = array_merge($files, css_pluginstyles($style)); - if (isset($tplstyles[$style])) $files = array_merge($files, $tplstyles[$style]); - - if(isset($config_cascade['userstyle'][$style])){ - $files[$config_cascade['userstyle'][$style]] = DOKU_BASE; - } - }else{ - $files[DOKU_INC.'lib/styles/style.css'] = DOKU_BASE.'lib/styles/'; - // load plugin, template, user styles - $files = array_merge($files, css_pluginstyles('screen')); - if (isset($tplstyles['screen'])) $files = array_merge($files, $tplstyles['screen']); + // load core styles + $files[DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/'; + // load plugin styles + $files = array_merge($files, css_pluginstyles($mediatype)); + // load template styles + if (isset($tplstyles[$mediatype])) { + $files = array_merge($files, $tplstyles[$mediatype]); + } + // if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility + if (isset($config_cascade['userstyle']['default'])) { + $config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default']; + } + // load user styles + if(isset($config_cascade['userstyle'][$mediatype])){ + $files[$config_cascade['userstyle'][$mediatype]] = DOKU_BASE; + } + // load rtl styles + // @todo: this currently adds the rtl styles only to the 'screen' media type + // but 'print' and 'all' should also be supported + if ($mediatype=='screen') { if($lang['direction'] == 'rtl'){ if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']); } - if(isset($config_cascade['userstyle']['default'])){ - $files[$config_cascade['userstyle']['default']] = DOKU_BASE; - } } // check cache age & handle conditional request @@ -123,6 +125,9 @@ function css_out(){ // apply style replacements $css = css_applystyle($css,$tplinc); + // place all @import statements at the top of the file + $css = css_moveimports($css); + // compress whitespace and comments if($conf['compress']){ $css = css_compress($css); @@ -199,7 +204,7 @@ function css_interwiki(){ // default style echo 'a.interwiki {'; echo ' background: transparent url('.DOKU_BASE.'lib/images/interwiki.png) 0px 1px no-repeat;'; - echo ' padding-left: 16px;'; + echo ' padding: 1px 0px 1px 16px;'; echo '}'; // additional styles when icon available @@ -264,7 +269,8 @@ function css_loadfile($file,$location=''){ $css = io_readFile($file); if(!$location) return $css; - $css = preg_replace('#(url\([ \'"]*)((?!/|http://|https://| |\'|"))#','\\1'.$location.'\\3',$css); + $css = preg_replace('#(url\([ \'"]*)(?!/|http://|https://| |\'|")#','\\1'.$location,$css); + $css = preg_replace('#(@import\s+[\'"])(?!/|http://|https://)#', '\\1'.$location, $css); return $css; } @@ -274,20 +280,15 @@ function css_loadfile($file,$location=''){ * * @author Andreas Gohr <andi@splitbrain.org> */ -function css_pluginstyles($mode='screen'){ +function css_pluginstyles($mediatype='screen'){ global $lang; $list = array(); $plugins = plugin_list(); foreach ($plugins as $p){ - if($mode == 'all'){ - $list[DOKU_PLUGIN."$p/all.css"] = DOKU_BASE."lib/plugins/$p/"; - }elseif($mode == 'print'){ - $list[DOKU_PLUGIN."$p/print.css"] = DOKU_BASE."lib/plugins/$p/"; - }elseif($mode == 'feed'){ - $list[DOKU_PLUGIN."$p/feed.css"] = DOKU_BASE."lib/plugins/$p/"; - }else{ + $list[DOKU_PLUGIN."$p/$mediatype.css"] = DOKU_BASE."lib/plugins/$p/"; + // alternative for screen.css + if ($mediatype=='screen') { $list[DOKU_PLUGIN."$p/style.css"] = DOKU_BASE."lib/plugins/$p/"; - $list[DOKU_PLUGIN."$p/screen.css"] = DOKU_BASE."lib/plugins/$p/"; } if($lang['direction'] == 'rtl'){ $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/"; @@ -297,6 +298,29 @@ function css_pluginstyles($mode='screen'){ } /** + * Move all @import statements in a combined stylesheet to the top so they + * aren't ignored by the browser. + * + * @author Gabriel Birke <birke@d-scribe.de> + */ +function css_moveimports($css) +{ + if(!preg_match_all('/@import\s+(?:url\([^)]+\)|"[^"]+")\s*[^;]*;\s*/', $css, $matches, PREG_OFFSET_CAPTURE)) { + return $css; + } + $newCss = ""; + $imports = ""; + $offset = 0; + foreach($matches[0] as $match) { + $newCss .= substr($css, $offset, $match[1] - $offset); + $imports .= $match[0]; + $offset = $match[1] + strlen($match[0]); + } + $newCss .= substr($css, $offset); + return $imports.$newCss; +} + +/** * Very simple CSS optimizer * * @author Andreas Gohr <andi@splitbrain.org> @@ -330,4 +354,4 @@ function css_comment_cb($matches){ return $matches[0]; } -//Setup VIM: ex: et ts=4 enc=utf-8 : +//Setup VIM: ex: et ts=4 : diff --git a/lib/exe/fetch.php b/lib/exe/fetch.php index 680fd9ae4..3ad4f1937 100644 --- a/lib/exe/fetch.php +++ b/lib/exe/fetch.php @@ -198,4 +198,4 @@ function calc_cache($cache){ return -1; //cache endless } -//Setup VIM: ex: et ts=2 enc=utf-8 : +//Setup VIM: ex: et ts=2 : diff --git a/lib/exe/indexer.php b/lib/exe/indexer.php index 3a9673ed6..95e2af05b 100644 --- a/lib/exe/indexer.php +++ b/lib/exe/indexer.php @@ -11,9 +11,6 @@ require_once(DOKU_INC.'inc/init.php'); session_write_close(); //close session if(!defined('NL')) define('NL',"\n"); -// Version tag used to force rebuild on upgrade -define('INDEXER_VERSION', 2); - // keep running after browser closes connection @ignore_user_abort(true); @@ -34,7 +31,6 @@ $tmp = array(); // No event data $evt = new Doku_Event('INDEXER_TASKS_RUN', $tmp); if ($evt->advise_before()) { runIndexer() or - metaUpdate() or runSitemapper() or sendDigest() or runTrimRecentChanges() or @@ -137,86 +133,8 @@ function runIndexer(){ if(!$ID) return false; - // check if indexing needed - $idxtag = metaFN($ID,'.indexed'); - if(@file_exists($idxtag)){ - if(io_readFile($idxtag) >= INDEXER_VERSION){ - $last = @filemtime($idxtag); - if($last > @filemtime(wikiFN($ID))){ - print "runIndexer(): index for $ID up to date".NL; - return false; - } - } - } - - // try to aquire a lock - $lock = $conf['lockdir'].'/_indexer.lock'; - while(!@mkdir($lock,$conf['dmode'])){ - usleep(50); - if(time()-@filemtime($lock) > 60*5){ - // looks like a stale lock - remove it - @rmdir($lock); - print "runIndexer(): stale lock removed".NL; - }else{ - print "runIndexer(): indexer locked".NL; - return false; - } - } - if($conf['dperm']) chmod($lock, $conf['dperm']); - // do the work - idx_addPage($ID); - - // we're finished - save and free lock - io_saveFile(metaFN($ID,'.indexed'),INDEXER_VERSION); - @rmdir($lock); - print "runIndexer(): finished".NL; - return true; -} - -/** - * Will render the metadata for the page if not exists yet - * - * This makes sure pages which are created from outside DokuWiki will - * gain their data when viewed for the first time. - */ -function metaUpdate(){ - global $ID; - print "metaUpdate(): started".NL; - - if(!$ID) return false; - $file = metaFN($ID, '.meta'); - echo "meta file: $file".NL; - - // rendering needed? - if (@file_exists($file)) return false; - if (!@file_exists(wikiFN($ID))) return false; - - global $conf; - - // gather some additional info from changelog - $info = io_grep($conf['changelog'], - '/^(\d+)\t(\d+\.\d+\.\d+\.\d+)\t'.preg_quote($ID,'/').'\t([^\t]+)\t([^\t\n]+)/', - 0,true); - - $meta = array(); - if(!empty($info)){ - $meta['date']['created'] = $info[0][1]; - foreach($info as $item){ - if($item[4] != '*'){ - $meta['date']['modified'] = $item[1]; - if($item[3]){ - $meta['contributor'][$item[3]] = $item[3]; - } - } - } - } - - $meta = p_render_metadata($ID, $meta); - io_saveFile($file, serialize($meta)); - - echo "metaUpdate(): finished".NL; - return true; + return idx_addPage($ID, true); } /** @@ -229,88 +147,10 @@ function metaUpdate(){ * @link https://www.google.com/webmasters/sitemaps/docs/en/about.html */ function runSitemapper(){ - global $conf; print "runSitemapper(): started".NL; - if(!$conf['sitemap']) return false; - - if($conf['compression'] == 'bz2' || $conf['compression'] == 'gz'){ - $sitemap = 'sitemap.xml.gz'; - }else{ - $sitemap = 'sitemap.xml'; - } - print "runSitemapper(): using $sitemap".NL; - - if(@file_exists(DOKU_INC.$sitemap)){ - if(!is_writable(DOKU_INC.$sitemap)) return false; - }else{ - if(!is_writable(DOKU_INC)) return false; - } - - if(@filesize(DOKU_INC.$sitemap) && - @filemtime(DOKU_INC.$sitemap) > (time()-($conf['sitemap']*60*60*24))){ - print 'runSitemapper(): Sitemap up to date'.NL; - return false; - } - - $pages = idx_getIndex('page', ''); - print 'runSitemapper(): creating sitemap using '.count($pages).' pages'.NL; - - // build the sitemap - ob_start(); - print '<?xml version="1.0" encoding="UTF-8"?>'.NL; - print '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'.NL; - foreach($pages as $id){ - $id = trim($id); - $file = wikiFN($id); - - //skip hidden, non existing and restricted files - if(isHiddenPage($id)) continue; - $date = @filemtime($file); - if(!$date) continue; - if(auth_aclcheck($id,'','') < AUTH_READ) continue; - - print ' <url>'.NL; - print ' <loc>'.wl($id,'',true).'</loc>'.NL; - print ' <lastmod>'.date_iso8601($date).'</lastmod>'.NL; - print ' </url>'.NL; - } - print '</urlset>'.NL; - $data = ob_get_contents(); - ob_end_clean(); - - //save the new sitemap - io_saveFile(DOKU_INC.$sitemap,$data); - - //ping search engines... - $http = new DokuHTTPClient(); - $http->timeout = 8; - - //ping google - print 'runSitemapper(): pinging google'.NL; - $url = 'http://www.google.com/webmasters/sitemaps/ping?sitemap='; - $url .= urlencode(DOKU_URL.$sitemap); - $resp = $http->get($url); - if($http->error) print 'runSitemapper(): '.$http->error.NL; - print 'runSitemapper(): '.preg_replace('/[\n\r]/',' ',strip_tags($resp)).NL; - - //ping yahoo - print 'runSitemapper(): pinging yahoo'.NL; - $url = 'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=dokuwiki&url='; - $url .= urlencode(DOKU_URL.$sitemap); - $resp = $http->get($url); - if($http->error) print 'runSitemapper(): '.$http->error.NL; - print 'runSitemapper(): '.preg_replace('/[\n\r]/',' ',strip_tags($resp)).NL; - - //ping microsoft - print 'runSitemapper(): pinging microsoft'.NL; - $url = 'http://www.bing.com/webmaster/ping.aspx?siteMap='; - $url .= urlencode(DOKU_URL.$sitemap); - $resp = $http->get($url); - if($http->error) print 'runSitemapper(): '.$http->error.NL; - print 'runSitemapper(): '.preg_replace('/[\n\r]/',' ',strip_tags($resp)).NL; - + $result = Sitemapper::generate() && Sitemapper::pingSearchEngines(); print 'runSitemapper(): finished'.NL; - return true; + return $result; } /** @@ -406,21 +246,6 @@ function sendDigest() { } /** - * Formats a timestamp as ISO 8601 date - * - * @author <ungu at terong dot com> - * @link http://www.php.net/manual/en/function.date.php#54072 - */ -function date_iso8601($int_date) { - //$int_date: current date in UNIX timestamp - $date_mod = date('Y-m-d\TH:i:s', $int_date); - $pre_timezone = date('O', $int_date); - $time_zone = substr($pre_timezone, 0, 3).":".substr($pre_timezone, 3, 2); - $date_mod .= $time_zone; - return $date_mod; -} - -/** * Just send a 1x1 pixel blank gif to the browser * * @author Andreas Gohr <andi@splitbrain.org> @@ -441,6 +266,6 @@ function sendGIF(){ // Thinks it's got the whole image } -//Setup VIM: ex: et ts=4 enc=utf-8 : +//Setup VIM: ex: et ts=4 : // No trailing PHP closing tag - no output please! // See Note at http://www.php.net/manual/en/language.basic-syntax.instruction-separation.php diff --git a/lib/exe/js.php b/lib/exe/js.php index f9682e1e9..5f376ee24 100644 --- a/lib/exe/js.php +++ b/lib/exe/js.php @@ -48,6 +48,7 @@ function js_out(){ DOKU_INC.'lib/scripts/textselection.js', DOKU_INC.'lib/scripts/toolbar.js', DOKU_INC.'lib/scripts/edit.js', + DOKU_INC.'lib/scripts/locktimer.js', DOKU_INC.'lib/scripts/linkwiz.js', DOKU_INC.'lib/scripts/media.js', DOKU_INC.'lib/scripts/subscriptions.js', @@ -112,7 +113,7 @@ function js_out(){ js_runonstart("initSizeCtl('size__ctl','wiki__text')"); js_runonstart("initToolbar('tool__bar','wiki__text',toolbar)"); if($conf['locktime'] != 0){ - js_runonstart("locktimer.init(".($conf['locktime'] - 60).",'".js_escape($lang['willexpire'])."',".$conf['usedraft'].")"); + js_runonstart("locktimer.init(".($conf['locktime'] - 60).",'".js_escape($lang['willexpire'])."',".$conf['usedraft'].", 'wiki__text')"); } js_runonstart('scrollToMarker()'); js_runonstart('focusMarker()'); @@ -396,4 +397,4 @@ function js_compress($s){ return trim($result); } -//Setup VIM: ex: et ts=4 enc=utf-8 : +//Setup VIM: ex: et ts=4 : diff --git a/lib/exe/mediamanager.php b/lib/exe/mediamanager.php index c79a25c08..02fde5a8d 100644 --- a/lib/exe/mediamanager.php +++ b/lib/exe/mediamanager.php @@ -82,18 +82,24 @@ // handle deletion if($DEL) { - $INUSE = media_inuse($DEL); - if(!$INUSE) { - if(media_delete($DEL,$AUTH)) { - msg(sprintf($lang['deletesucc'],noNS($DEL)),1); - } else { - msg(sprintf($lang['deletefail'],noNS($DEL)),-1); + $res = 0; + if(checkSecurityToken()) { + $res = media_delete($DEL,$AUTH); + } + if ($res & DOKU_MEDIA_DELETED) { + $msg = sprintf($lang['deletesucc'], noNS($DEL)); + if ($res & DOKU_MEDIA_EMPTY_NS) { + // current namespace was removed. redirecting to root ns passing msg along + send_redirect(DOKU_URL.'lib/exe/mediamanager.php?msg1='. + rawurlencode($msg).'&edid='.$_REQUEST['edid']); } - } else { + msg($msg,1); + } elseif ($res & DOKU_MEDIA_INUSE) { if(!$conf['refshow']) { - unset($INUSE); msg(sprintf($lang['mediainuse'],noNS($DEL)),0); } + } else { + msg(sprintf($lang['deletefail'],noNS($DEL)),-1); } } diff --git a/lib/exe/opensearch.php b/lib/exe/opensearch.php index f16b4f681..03a1632c4 100644 --- a/lib/exe/opensearch.php +++ b/lib/exe/opensearch.php @@ -35,4 +35,4 @@ echo ' <Url type="application/x-suggestions+json" template="'. DOKU_URL.'lib/exe/ajax.php?call=suggestions&q={searchTerms}" />'.NL; echo '</OpenSearchDescription>'.NL; -//Setup VIM: ex: et ts=4 enc=utf-8 : +//Setup VIM: ex: et ts=4 : diff --git a/lib/exe/xmlrpc.php b/lib/exe/xmlrpc.php index 53189d291..108dd8fd1 100644 --- a/lib/exe/xmlrpc.php +++ b/lib/exe/xmlrpc.php @@ -1,13 +1,13 @@ <?php if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); -// fix when '<?xml' isn't on the very first line +// fix when '< ?xml' isn't on the very first line if(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA); /** * Increased whenever the API is changed */ -define('DOKU_XMLRPC_API_VERSION',4); +define('DOKU_XMLRPC_API_VERSION',5); require_once(DOKU_INC.'inc/init.php'); session_write_close(); //close session @@ -143,6 +143,13 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { true ); + $this->addCallback( + 'dokuwiki.appendPage', + 'this:appendPage', + array('int', 'string', 'string', 'struct'), + 'Append text to a wiki page.' + ); + /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */ $this->addCallback( 'wiki.getRPCVersionSupported', @@ -357,9 +364,8 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { */ function listPages(){ $list = array(); - $pages = array_filter(array_filter(idx_getIndex('page', ''), - 'isVisiblePage'), - 'page_exists'); + $pages = idx_get_indexer()->getPages(); + $pages = array_filter(array_filter($pages,'isVisiblePage'),'page_exists'); foreach(array_keys($pages) as $idx) { $perm = auth_quickaclcheck($pages[$idx]); @@ -555,29 +561,20 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { unlock($id); // run the indexer if page wasn't indexed yet - if(!@file_exists(metaFN($id, '.indexed'))) { - // try to aquire a lock - $lock = $conf['lockdir'].'/_indexer.lock'; - while(!@mkdir($lock,$conf['dmode'])){ - usleep(50); - if(time()-@filemtime($lock) > 60*5){ - // looks like a stale lock - remove it - @rmdir($lock); - }else{ - return false; - } - } - if($conf['dperm']) chmod($lock, $conf['dperm']); + idx_addPage($id); - // do the work - idx_addPage($id); + return 0; + } - // we're finished - save and free lock - io_saveFile(metaFN($id,'.indexed'),INDEXER_VERSION); - @rmdir($lock); + /** + * Appends text to a wiki page. + */ + function appendPage($id, $text, $params) { + $currentpage = $this->rawPage($id); + if (!is_string($currentpage)) { + return $currentpage; } - - return 0; + return $this->putPage($id, $currentpage.$text, $params); } /** @@ -587,64 +584,26 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { */ function putAttachment($id, $file, $params) { $id = cleanID($id); - global $conf; - global $lang; - $auth = auth_quickaclcheck(getNS($id).':*'); - if($auth >= AUTH_UPLOAD) { - if(!isset($id)) { - return new IXR_ERROR(1, 'Filename not given.'); - } - $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP()); - - // save temporary file - @unlink($ftmp); - $buff = base64_decode($file); - io_saveFile($ftmp, $buff); + if(!isset($id)) { + return new IXR_ERROR(1, 'Filename not given.'); + } - // get filename - list($iext, $imime,$dl) = mimetype($id); - $id = cleanID($id); - $fn = mediaFN($id); - - // get filetype regexp - $types = array_keys(getMimeTypes()); - $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types); - $regex = join('|',$types); - - // because a temp file was created already - if(preg_match('/\.('.$regex.')$/i',$fn)) { - //check for overwrite - $overwrite = @file_exists($fn); - if($overwrite && (!$params['ow'] || $auth < AUTH_DELETE)) { - return new IXR_ERROR(1, $lang['uploadexist'].'1'); - } - // check for valid content - $ok = media_contentcheck($ftmp, $imime); - if($ok == -1) { - return new IXR_ERROR(1, sprintf($lang['uploadexist'].'2', ".$iext")); - } elseif($ok == -2) { - return new IXR_ERROR(1, $lang['uploadspam']); - } elseif($ok == -3) { - return new IXR_ERROR(1, $lang['uploadxss']); - } + global $conf; - // prepare event data - $data[0] = $ftmp; - $data[1] = $fn; - $data[2] = $id; - $data[3] = $imime; - $data[4] = $overwrite; + $ftmp = $conf['tmpdir'] . '/' . md5($id.clientIP()); - // trigger event - return trigger_event('MEDIA_UPLOAD_FINISH', $data, array($this, '_media_upload_action'), true); + // save temporary file + @unlink($ftmp); + $buff = base64_decode($file); + io_saveFile($ftmp, $buff); - } else { - return new IXR_ERROR(1, $lang['uploadwrong']); - } + $res = media_save(array('name' => $ftmp), $id, $params['ow'], $auth, 'rename'); + if (is_array($res)) { + return new IXR_ERROR(-$res[1], $res[0]); } else { - return new IXR_ERROR(1, "You don't have permissions to upload files."); + return $res; } } @@ -656,55 +615,15 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { function deleteAttachment($id){ $id = cleanID($id); $auth = auth_quickaclcheck(getNS($id).':*'); - if($auth < AUTH_DELETE) return new IXR_ERROR(1, "You don't have permissions to delete files."); - global $conf; - global $lang; - - // check for references if needed - $mediareferences = array(); - if($conf['refcheck']){ - $mediareferences = ft_mediause($id,$conf['refshow']); - } - - if(!count($mediareferences)){ - $file = mediaFN($id); - if(@unlink($file)){ - addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE); - io_sweepNS($id,'mediadir'); - return 0; - } - //something went wrong - return new IXR_ERROR(1, 'Could not delete file'); - } else { + $res = media_delete($id, $auth); + if ($res & DOKU_MEDIA_DELETED) { + return 0; + } elseif ($res & DOKU_MEDIA_NOT_AUTH) { + return new IXR_ERROR(1, "You don't have permissions to delete files."); + } elseif ($res & DOKU_MEDIA_INUSE) { return new IXR_ERROR(1, 'File is still referenced'); - } - } - - /** - * Moves the temporary file to its final destination. - * - * Michael Klier <chi@chimeric.de> - */ - function _media_upload_action($data) { - global $conf; - - if(is_array($data) && count($data)===5) { - io_createNamespace($data[2], 'media'); - if(rename($data[0], $data[1])) { - chmod($data[1], $conf['fmode']); - media_notify($data[2], $data[1], $data[3]); - // add a log entry to the media changelog - if ($data[4]) { - addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_EDIT); - } else { - addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_CREATE); - } - return $data[2]; - } else { - return new IXR_ERROR(1, 'Upload failed.'); - } } else { - return new IXR_ERROR(1, 'Upload failed.'); + return new IXR_ERROR(1, 'Could not delete file'); } } @@ -963,4 +882,4 @@ class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer { $server = new dokuwiki_xmlrpc_server(); -// vim:ts=4:sw=4:et:enc=utf-8: +// vim:ts=4:sw=4:et: |