Revision [20020]
This is an old revision of RESTHandler made by DomBonj on 2008-06-08 07:57:31.
REST Handler
NOT included in any Wikka versionThis is the development page for the REST handler.
Installation
- Save the first code block below as handlers/page/rest.php- Give it the same file permissions as the other php files in that directory
- Modify wikka.php as shown on the second code block below
- Modify libs/Wakka.class.php as shown on the third code block below
Code
1. New handlers/page/rest.php file
<?php
#
# Selects and returns the requested XML chunk(s) of the page
#
# @package Handlers
# @name REST
#
# @authors DomBonj
#
# @version 0.91
#
# @input Parameters in URL : [tag][/attr[/value]]
# if attr = index, value must be an integer
#
# @output returns a UTF-8 string (empty if no match)
#
# @uses Wakka::HasAccess()
#
function numeric_html_entities ($string)
{
$trans_tbl1 = get_html_translation_table(HTML_ENTITIES);
foreach ($trans_tbl1 as $ascii => $html_entity)
{
$trans_tbl2[$html_entity] = '&#'. ord($ascii) .';';
$trans_tbl3[$ascii] = '&#'. ord($ascii) .';';
}
// keep XML entities
unset($trans_tbl3['<']);
unset($trans_tbl3['>']);
unset($trans_tbl3['"']);
unset($trans_tbl3['\'']);
unset($trans_tbl3['&']);
$ret = strtr (strtr ($string, $trans_tbl2), $trans_tbl3);
// translate '&' character if not part of a numeric entity
$ret = preg_replace('/&(?!#[x]?[0-9a-f]+;)/i', '&', $ret);
return($ret);
}
function uri_suffix_to_xpath_request (array $params)
{ // empty return value means parameter error
$tag = isset($params[1]) ? $params[1] : '';
$attr = isset($params[3]) ? $params[3] : '';
$val = isset($params[5]) ? $params[5] : '';
$rank = isset($params[7]) ? $params[7] : '';
if ((($val != '') && ($attr == ''))
|| (!preg_match('/^[0-9]*$/', $rank))
|| (($tag == '') && ($attr == '') && ($rank !== '')) )
{ // semantically incorrect request
$xpath = '';
}
else
{ // correct request
$xpath = $tag ? ('//'. $tag) : ((!$attr && !$val) ? '/*' : '//*');
$xpath .= $attr ? ('[@'. $attr .($val ? '=\''.$val.'\'' : '') .']') : '';
}
return(array($xpath, $rank));
}
if ($this->HasAccess('read') && $this->page)
{
if (preg_match('/^([a-zA-Z_][A-Za-z0-9:_\-\.]*)?(\/([a-zA-Z_][A-Za-z0-9:_\-\.]*)?(\/([^\/]*))?(\/([^\/]*))?)?/', $this->RESTreq, $matches))
{ // well-formed request
list($xpath_req, $rank) = uri_suffix_to_xpath_request($matches);
}
else
{ // syntactically incorrect request
$xpath_req = '';
}
if ($xpath_req)
{ // build (x)html page. This code block is supposed to output the same html as the 'show' handler (bar transcoding)
$my_page = '<div class="page">'."\n";
$my_page .= $this->Format($this->page['body'], 'wakka');
$my_page .= '<div style="clear: both"></div>'."\n";
// Footnote action
if (function_exists('FNprint'))
{
$my_page .= (FNprint($this, 'list', '', $this->Href()));
}
$my_page .= '</div>'."\n";
$my_page = utf8_encode(numeric_html_entities($my_page));
$output = '';
try
{ // suppress WARNING messages
$xml = new SimpleXMLElement($my_page, LIBXML_NOERROR);
}
catch (Exception $e)
{ // $xml is NULL
}
if ($xml)
{
$cnt_obj = 1;
foreach ($xml->xpath($xpath_req) as $xml_obj)
{
if ($rank === '')
{ // false if $rank=0
$output .= $xml_obj->asXML() ."\n";
}
elseif ($cnt_obj++ == (int)$rank)
{ // only keep object #rank
$output = $xml_obj->asXML() ."\n";
}
}
}
}
else
{ // silent failure
$output = '';
}
echo ($output);
}
?>
#
# Selects and returns the requested XML chunk(s) of the page
#
# @package Handlers
# @name REST
#
# @authors DomBonj
#
# @version 0.91
#
# @input Parameters in URL : [tag][/attr[/value]]
# if attr = index, value must be an integer
#
# @output returns a UTF-8 string (empty if no match)
#
# @uses Wakka::HasAccess()
#
function numeric_html_entities ($string)
{
$trans_tbl1 = get_html_translation_table(HTML_ENTITIES);
foreach ($trans_tbl1 as $ascii => $html_entity)
{
$trans_tbl2[$html_entity] = '&#'. ord($ascii) .';';
$trans_tbl3[$ascii] = '&#'. ord($ascii) .';';
}
// keep XML entities
unset($trans_tbl3['<']);
unset($trans_tbl3['>']);
unset($trans_tbl3['"']);
unset($trans_tbl3['\'']);
unset($trans_tbl3['&']);
$ret = strtr (strtr ($string, $trans_tbl2), $trans_tbl3);
// translate '&' character if not part of a numeric entity
$ret = preg_replace('/&(?!#[x]?[0-9a-f]+;)/i', '&', $ret);
return($ret);
}
function uri_suffix_to_xpath_request (array $params)
{ // empty return value means parameter error
$tag = isset($params[1]) ? $params[1] : '';
$attr = isset($params[3]) ? $params[3] : '';
$val = isset($params[5]) ? $params[5] : '';
$rank = isset($params[7]) ? $params[7] : '';
if ((($val != '') && ($attr == ''))
|| (!preg_match('/^[0-9]*$/', $rank))
|| (($tag == '') && ($attr == '') && ($rank !== '')) )
{ // semantically incorrect request
$xpath = '';
}
else
{ // correct request
$xpath = $tag ? ('//'. $tag) : ((!$attr && !$val) ? '/*' : '//*');
$xpath .= $attr ? ('[@'. $attr .($val ? '=\''.$val.'\'' : '') .']') : '';
}
return(array($xpath, $rank));
}
if ($this->HasAccess('read') && $this->page)
{
if (preg_match('/^([a-zA-Z_][A-Za-z0-9:_\-\.]*)?(\/([a-zA-Z_][A-Za-z0-9:_\-\.]*)?(\/([^\/]*))?(\/([^\/]*))?)?/', $this->RESTreq, $matches))
{ // well-formed request
list($xpath_req, $rank) = uri_suffix_to_xpath_request($matches);
}
else
{ // syntactically incorrect request
$xpath_req = '';
}
if ($xpath_req)
{ // build (x)html page. This code block is supposed to output the same html as the 'show' handler (bar transcoding)
$my_page = '<div class="page">'."\n";
$my_page .= $this->Format($this->page['body'], 'wakka');
$my_page .= '<div style="clear: both"></div>'."\n";
// Footnote action
if (function_exists('FNprint'))
{
$my_page .= (FNprint($this, 'list', '', $this->Href()));
}
$my_page .= '</div>'."\n";
$my_page = utf8_encode(numeric_html_entities($my_page));
$output = '';
try
{ // suppress WARNING messages
$xml = new SimpleXMLElement($my_page, LIBXML_NOERROR);
}
catch (Exception $e)
{ // $xml is NULL
}
if ($xml)
{
$cnt_obj = 1;
foreach ($xml->xpath($xpath_req) as $xml_obj)
{
if ($rank === '')
{ // false if $rank=0
$output .= $xml_obj->asXML() ."\n";
}
elseif ($cnt_obj++ == (int)$rank)
{ // only keep object #rank
$output = $xml_obj->asXML() ."\n";
}
}
}
}
else
{ // silent failure
$output = '';
}
echo ($output);
}
?>
2. In wikka.php, go to line 378 and replace the following code block:
with the following code block:
if ((!preg_match("/(xml|raw|mm|grabcode)$/", $method)) && (!preg_match("/^rest(\W|$)/", $method)))
{
{
3. In libs/Wakka.class.php, go to line 1743 and replace the following code block:
// raw page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
// grabcode page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
// grabcode page handler
with the following code block:
// raw page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
// REST handler
elseif (preg_match('/^rest(\W|$)/', $this->method))
{
preg_match('/^rest(\/(.*))?/', $this->method, $matches);
header("Content-type: text/plain");
$this->RESTreq = $matches[2];
print($this->Method('rest'));
}
// grabcode page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
// REST handler
elseif (preg_match('/^rest(\W|$)/', $this->method))
{
preg_match('/^rest(\/(.*))?/', $this->method, $matches);
header("Content-type: text/plain");
$this->RESTreq = $matches[2];
print($this->Method('rest'));
}
// grabcode page handler