From c4e0e4a153fee5f985668670a91b2cd94a17dd75 Mon Sep 17 00:00:00 2001 From: Andreas Gohr <andi@splitbrain.org> Date: Fri, 14 Apr 2006 17:03:58 +0200 Subject: [PATCH] relative upper links Now allows links like [[..:..:page]] darcs-hash:20060414150358-7ad00-88394caabc6ee2ce7137694e2a0c0c98e7534ea5.gz --- _test/cases/inc/pageutils_resolve_id.test.php | 45 ++++++++++ inc/pageutils.php | 84 ++++++++++++------- 2 files changed, 99 insertions(+), 30 deletions(-) create mode 100644 _test/cases/inc/pageutils_resolve_id.test.php diff --git a/_test/cases/inc/pageutils_resolve_id.test.php b/_test/cases/inc/pageutils_resolve_id.test.php new file mode 100644 index 000000000..64b4033cd --- /dev/null +++ b/_test/cases/inc/pageutils_resolve_id.test.php @@ -0,0 +1,45 @@ +<?php +require_once DOKU_INC.'inc/utf8.php'; +require_once DOKU_INC.'inc/pageutils.php'; + +class init_resolve_id_test extends UnitTestCase { + + + function test1(){ + // we test multiple cases here + // format: $ns, $page, $output + $tests = array(); + + // relative current in root + $tests[] = array('','page','page'); + $tests[] = array('','.page','page'); + $tests[] = array('','.:page','page'); + + // relative current in namespace + $tests[] = array('lev1:lev2','page','lev1:lev2:page'); + $tests[] = array('lev1:lev2','.page','lev1:lev2:page'); + $tests[] = array('lev1:lev2','.:page','lev1:lev2:page'); + + // relative upper in root + $tests[] = array('','..page','page'); + $tests[] = array('','..:page','page'); + + // relative upper in namespace + $tests[] = array('lev1:lev2','..page','lev1:page'); + $tests[] = array('lev1:lev2','..:page','lev1:page'); + $tests[] = array('lev1:lev2','..:..:page','page'); + $tests[] = array('lev1:lev2','..:..:..:page','page'); + + // strange and broken ones + $tests[] = array('lev1:lev2','....:....:page','lev1:lev2:page'); + $tests[] = array('lev1:lev2','..:..:lev3:page','lev3:page'); + $tests[] = array('lev1:lev2','..:..:lev3:..:page','page'); + $tests[] = array('lev1:lev2','..:..:lev3:..:page:....:...','page'); + + foreach($tests as $test){ + $this->assertEqual(resolve_id($test[0],$test[1]),$test[2]); + } + } + +} +//Setup VIM: ex: et ts=4 enc=utf-8 : diff --git a/inc/pageutils.php b/inc/pageutils.php index 0689ff6fe..6adeb85b2 100644 --- a/inc/pageutils.php +++ b/inc/pageutils.php @@ -111,10 +111,11 @@ function cleanID($id,$ascii=false){ * @author Andreas Gohr <andi@splitbrain.org> */ function getNS($id){ - if(strpos($id,':')!==false){ - return substr($id,0,strrpos($id,':')); - } - return false; + $pos = strrpos($id,':'); + if($pos!==false){ + return substr($id,0,$pos); + } + return false; } /** @@ -218,24 +219,57 @@ function localeFN($id){ } /** - * Returns a full media id + * Resolve relative paths in IDs * - * @author Andreas Gohr <andi@splitbrain.org> + * Do not call directly use resolve_mediaid or resolve_pageid + * instead + * + * Partyly based on a cleanPath function found at + * http://www.php.net/manual/en/function.realpath.php#57016 + * + * @author <bart at mediawave dot nl> */ -function resolve_mediaid($ns,&$page,&$exists){ - global $conf; - - //if links starts with . add current namespace - if($page{0} == '.'){ - $page = $ns.':'.substr($page,1); +function resolve_id($ns,$id){ + // if the id starts with a dot we need to handle the + // relative stuff + if($id{0} == '.'){ + // normalize initial dots without a colon + $id = preg_replace('/^(\.+)(?=[^:\.])/','\1:',$id); + // prepend the current namespace + $id = $ns.':'.$id; + + // cleanup relatives + $result = array(); + $pathA = explode(':', $id); + if (!$pathA[0]) $result[] = ''; + foreach ($pathA AS $key => $dir) { + if ($dir == '..') { + if (end($result) == '..') { + $result[] = '..'; + } elseif (!array_pop($result)) { + $result[] = '..'; + } + } elseif ($dir && $dir != '.') { + $result[] = $dir; + } + } + if (!end($pathA)) $result[] = ''; + $id = implode(':', $result); + }elseif($ns !== false && strpos($id,':') === false){ + //if link contains no namespace. add current namespace (if any) + $id = $ns.':'.$id; } - //if link contains no namespace. add current namespace (if any) - if($ns !== false && strpos($page,':') === false){ - $page = $ns.':'.$page; - } + return cleanID($id); +} - $page = cleanID($page); +/** + * Returns a full media id + * + * @author Andreas Gohr <andi@splitbrain.org> + */ +function resolve_mediaid($ns,&$page,&$exists){ + $page = resolve_id($ns,$page); $file = mediaFN($page); $exists = @file_exists($file); } @@ -249,19 +283,9 @@ function resolve_pageid($ns,&$page,&$exists){ global $conf; $exists = false; - //if links starts with . add current namespace - if($page{0} == '.'){ - $page = $ns.':'.substr($page,1); - } - - //if link contains no namespace. add current namespace (if any) - if($ns !== false && strpos($page,':') === false){ - $page = $ns.':'.$page; - } - //keep hashlink if exists then clean both parts list($page,$hash) = split('#',$page,2); - $page = cleanID($page); + $page = resolve_id($ns,$page); $hash = cleanID($hash); $file = wikiFN($page); @@ -337,7 +361,7 @@ function isVisiblePage($id){ * @link http://simon.incutio.com/archive/2003/04/23/conditionalGet */ function http_conditionalRequest($timestamp){ - // A PHP implementation of conditional get, see + // A PHP implementation of conditional get, see // http://fishbowl.pastiche.org/archives/001132.html $last_modified = substr(date('r', $timestamp), 0, -5).'GMT'; $etag = '"'.md5($last_modified).'"'; @@ -349,7 +373,7 @@ function http_conditionalRequest($timestamp){ stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false; $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? - stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : + stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : false; if (!$if_modified_since && !$if_none_match) { return; -- GitLab