=====REST Handler=====
>>==See also:==
- Documentation: RESTHandlerInfo
==works with:==
- Wikka 1.1.6.4 & 1.1.6.5
>>//NOT included in any Wikka version//{{lastedit show="3"}}
This 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)%s
%s%s %s');
$REST_RETURN_CODES_ARRAY = array(
'MethodUnsupported' => array('Method not supported', 'HTTP/1.1 501 Not Implemented'),
'SyntaxError' => array('Could not parse request string', 'HTTP/1.1 400 Bad Request'),
'IllegalParameters' => array('Illegal parameter(s) value', 'HTTP/1.1 400 Bad Request'),
'XPathFailure' => array('Could not process query', 'HTTP/1.1 500 Server Error')
);
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]!='*' ? $params[1] : '') : '';
$attr = isset($params[3]) ? ($params[3]!='*' ? $params[3] : '') : '';
$val = isset($params[5]) ? ($params[5]!='*' ? $params[5] : '') : '';
$rank = isset($params[7]) ? $params[7] : '';
if ((($val != '') && ($attr == ''))
|| (!preg_match('/^([1-9][0-9]*)?$/', $rank))
|| (($tag == '') && ($attr == '') && ($rank !== '')) )
{ // semantically incorrect request
$xpath = '';
$error_code = REST_ERROR_BAD_PARAMETERS;
}
else
{ // correct request
$xpath = $tag ? ('//'. $tag) : ((!$attr && !$val) ? '/*' : '//*');
$xpath .= $attr ? (($val ? '[contains(concat(concat(" ", @'. $attr. '), " "), concat(concat(" ", \''. $val .'\'), " "))]' : '[@'. $attr .']')) : '';
$error_code = '';
}
return(array($xpath, $rank, $error_code));
}
if ($this->HasAccess('read') && $this->page)
{
if ($_SERVER['REQUEST_METHOD'] != 'GET')
{ // not supported
$xpath_req = '';
$error_code = REST_ERROR_NOT_SUPPORTED;
}
elseif (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, $error_code) = uri_suffix_to_xpath_request($matches);
}
else
{ // syntactically incorrect request
$xpath_req = '';
$error_code = REST_ERROR_SYNTAX;
}
if (!$error_code)
{ // build (x)html page. This code block is supposed to output the same html as the 'show' handler (bar transcoding)
$my_page = '
'. "\n";
$my_page .= $this->Format($this->page['body'], 'wakka');
$my_page .= '
'. "\n";
// Footnote action
if (function_exists('FNprint'))
{
$my_page .= (FNprint($this, 'list', '', $this->Href()));
}
$my_page .= '
'."\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
$error_code = REST_ERROR_XPATH_FAILURE;
}
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";
}
}
// if a '< ?xml version="1.0"? >' first line has been added, remove it
$output = preg_replace('/^\<\?xml[^\>]*?\>/i', '', $output);
}
}
if ($error_code)
{ // send 'Status' HTTP Header
header($REST_RETURN_CODES_ARRAY[$error_code][1]);
$output = sprintf(REST_FORMAT_ERROR_MSG, $error_code, $REST_RETURN_CODES_ARRAY[$error_code][0], $_SERVER['REQUEST_METHOD'], numeric_html_entities($this->RESTreq));
}
else
{
$output = '