Fwd: smarty apps can automagically be webservices
[email protected] (Martin Sarsale) Mon, 28 Mar 2005 11:01:17 -0300
| Newsgroups | php.smarty.dev |
|---|---|
| Message-ID | <[email protected]> |
---------- Forwarded message ---------- From: Martin Sarsale <[email protected]> Date: Wed, 23 Mar 2005 14:04:30 -0300 Subject: smarty apps can automagically be webservices To: [email protected] Dear all: The other day I had an idea which Im not sure if it's something completely stupid or it rocks :) For the last years, I've been thinking that html interfaces for webapps suck (you're always reinventing the wheel, and it's a lot of work if you want to do something great as gmail). I understand that html is the best way to do "public" interfaces but for the backoffice I wanted to have something that felt better to the user (XUL, XWT, or just develop a client using webservices). I started thinking about it and I noticed that it would be very easy to have smarty apps to act as webservices by just adding some lines of code at the start of the original code. The idea is pretty simple: when the client asks for it, we send the variables set into the smarty object, encoded as XML-RPC. When the user makes a XML-RPC request, we'll translate it into HTTP parameters ($_GET, $_POST and $_REQUEST variables). This implementation just extends smarty class and when "display" method is called, we check if the user has asked for the xmlrpc version ("xmlrpc=1" on the GET string). Also at the beginning (I don't like how this is implemented very much) we check if the current is a XMLRPC request and if it is, we decode the parameters and set them as $_GET,$_POST and $_REQUEST variables. This has some security problems because the user can see all the variables on the template and it's common to have sensitive information assigned but not shown (think of a user listing where you assign the output from "select * from users" to the template and in the table users you have the password field. You won't print that field on the template, but it still available if you ask for the xmlrpc version). I've been playing with this code and tikiwiki and I found that when a lot of variables are assigned to the template, the answer gets pretty big, so the xmlrpc client can ask for specific variables ( http://url/x.php?xmlrpc=1&xmlrpcvars[]=varX&xmlrpcvars[]=varY ) Also, if the webapp developer wants to tight things a bit he can specify which variables he wants to provide to xmlrpc clients using the xmlrpcvars (array) attribute ($smarty->xmlrpcvars=array('varX');) I would like to hear some opinions about this, I know it's not a real webservices server but I think some people can find it usefull to instantly have its apps working as webservices. pd: you'll find the code attached -- Martin Sarsale - [email protected] -- Martin Sarsale - [email protected]
smarty_xmlrpc.php
(application/x-httpd-php, 1.5 KB)
<?
class Smarty_XMLRPC extends Smarty {
var $xmlrpcvars=array();
function display($resource_name, $cache_id = null, $compile_id = null){
if (!empty($_GET['xmlrpc'])){
if (empty($this->xmlrpcvars) && empty($_GET['xmlrpcvars'])){
$ret=$this->_tpl_vars;
}else{
$ret=array();
$vars=$this->xmlrpcvars;
if (empty($vars) && isset($_GET['xmlrpcvars']) && is_array($_GET['xmlrpcvars'])){
$vars=$vars+$_GET['xmlrpcvars'];
}
foreach($vars as $v){
$ret[$v]=$this->_tpl_vars[$v];
}
}
print xmlrpc_encode($ret);
}else{
if ($cache_id){
return parent::display($resource_name,$cache_id);
}elseif($compile_id){
return parent::display($resource_name,$cache_id,$compile_id);
}else{
return parent::display($resource_name);
}
}
}
}
if (!empty($_GET['xmlrpc'])){
$vars=(isset($HTTP_RAW_POST_DATA)) ? xmlrpc_decode($HTTP_RAW_POST_DATA) : array();
$method=(isset($HTTP_RAW_POST_DATA)) ? xmlrpc_parse_method_descriptions($HTTP_RAW_POST_DATA) : null;
if (!empty($method) && isset($method['methodname'])){
$_POST[$k]=$_REQUEST[$k]=$_GET[$k]=$method['methodname'];
}
if ($vars){
foreach($vars[0] as $k=>$v){
if (!is_numeric($k)){
$_POST[$k]=$k;
$_REQUEST[$k]=&$_POST[$k];
$_GET[$k]=&$_POST[$k];
}
}
}
// ob_start(); print_R($y); print_R($_POST); print_R($_GET); print_R($_REQUEST); $x=ob_get_contents(); ob_end_clean(); $f=fopen("/tmp/log",'a'); fputs($f,$x."\n-------------\n"); fclose($f);
}
?>