source: trunk/include/ws_protocols/rest_encoder.php @ 2126

Last change on this file since 2126 was 2126, checked in by rvelices, 17 years ago
  • some code refactoring before upgrade to utf (only cosmetic at this point...)
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 7.2 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | PhpWebGallery - a PHP based picture gallery                           |
4// | Copyright (C) 2003-2007 PhpWebGallery Team - http://phpwebgallery.net |
5// +-----------------------------------------------------------------------+
6// | file          : $Id: rest_encoder.php 2126 2007-10-08 23:46:09Z rvelices $
7// | last update   : $Date: 2007-10-08 23:46:09 +0000 (Mon, 08 Oct 2007) $
8// | last modifier : $Author: rvelices $
9// | revision      : $Revision: 2126 $
10// +-----------------------------------------------------------------------+
11// | This program is free software; you can redistribute it and/or modify  |
12// | it under the terms of the GNU General Public License as published by  |
13// | the Free Software Foundation                                          |
14// |                                                                       |
15// | This program is distributed in the hope that it will be useful, but   |
16// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
17// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
18// | General Public License for more details.                              |
19// |                                                                       |
20// | You should have received a copy of the GNU General Public License     |
21// | along with this program; if not, write to the Free Software           |
22// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
23// | USA.                                                                  |
24// +-----------------------------------------------------------------------+
25
26
27class PwgXmlWriter
28{
29  var $_indent;
30  var $_indentStr;
31
32  var $_elementStack;
33  var $_lastTagOpen;
34  var $_indentLevel;
35
36  var $_encodedXml;
37
38  function PwgXmlWriter()
39  {
40    $this->_elementStack = array();
41    $this->_lastTagOpen = false;
42    $this->_indentLevel = 0;
43
44    $this->_encodedXml = '';
45    $this->_indent = true;
46    $this->_indentStr = "\t";
47  }
48
49  function &getOutput()
50  {
51    return $this->_encodedXml;
52  }
53
54
55  function start_element($name)
56  {
57    $this->_end_prev(false);
58    if (!empty($this->_elementStack))
59    {
60      $this->_eol_indent();
61    }
62    $this->_indentLevel++;
63    $this->_indent();
64    $this->_output( '<'.$name );
65    $this->_lastTagOpen = true;
66    array_push( $this->_elementStack, $name);
67  }
68
69  function end_element($x)
70  {
71    $close_tag = $this->_end_prev(true);
72    $name = array_pop( $this->_elementStack );
73    if ($close_tag)
74    {
75      $this->_indentLevel--;
76      $this->_indent();
77//      $this->_eol_indent();
78      $this->_output('</'.$name.">");
79    }
80  }
81
82  function write_content($value)
83  {
84    $this->_end_prev(false);
85    $value = (string)$value;
86    $this->_output( htmlspecialchars( $value ) );
87  }
88
89  function write_cdata($value)
90  {
91    $this->_end_prev(false);
92    $value = (string)$value;
93    $this->_output(
94      '<![CDATA['
95      . str_replace(']]>', ']]&gt;', $value)
96      . ']]>' );
97  }
98
99  function write_attribute($name, $value)
100  {
101    $this->_output(' '.$name.'="'.$this->encode_attribute($value).'"');
102  }
103
104  function encode_attribute($value)
105  {
106    return htmlspecialchars( (string)$value);
107  }
108
109  function _end_prev($done)
110  {
111    $ret = true;
112    if ($this->_lastTagOpen)
113    {
114      if ($done)
115      {
116        $this->_indentLevel--;
117        $this->_output( ' />' );
118        //$this->_eol_indent();
119        $ret = false;
120      }
121      else
122      {
123        $this->_output( '>' );
124      }
125      $this->_lastTagOpen = false;
126    }
127    return $ret;
128  }
129
130  function _eol_indent()
131  {
132    if ($this->_indent)
133      $this->_output("\n");
134  }
135
136  function _indent()
137  {
138    if ($this->_indent and
139        $this->_indentLevel > count($this->_elementStack) )
140    {
141      $this->_output(
142        str_repeat( $this->_indentStr, count($this->_elementStack) )
143       );
144    }
145  }
146
147  function _output($raw_content)
148  {
149    $this->_encodedXml .= $raw_content;
150  }
151}
152
153class PwgRestEncoder extends PwgResponseEncoder
154{
155  function encodeResponse($response)
156  {
157    global $lang_info;
158    $respClass = strtolower( get_class($response) );
159    if ($respClass=='pwgerror')
160    {
161      $ret = '<?xml version="1.0"?>
162<rsp stat="fail">
163        <err code="'.$response->code().'" msg="'.htmlspecialchars($response->message()).'" />
164</rsp>';
165      return $ret;
166    }
167
168    $this->_writer = new PwgXmlWriter();
169    $this->encode($response);
170    $ret = $this->_writer->getOutput();
171    $ret = '<?xml version="1.0" encoding="'.get_pwg_charset().'" ?>
172<rsp stat="ok">
173'.$ret.'
174</rsp>';
175
176    return $ret;
177  }
178
179  function getContentType()
180  {
181    return 'text/xml';
182  }
183
184  function encode_array($data, $itemName, $xml_attributes=array())
185  {
186    foreach ($data as $item)
187    {
188      $this->_writer->start_element( $itemName );
189      $this->encode($item, $xml_attributes);
190      $this->_writer->end_element( $itemName );
191    }
192  }
193
194  function encode_struct($data, $skip_underscore, $xml_attributes=array())
195  {
196    foreach ($data as $name => $value)
197    {
198      if (is_numeric($name))
199        continue;
200      if ($skip_underscore and $name[0]=='_')
201        continue;
202      if ( is_null($value) )
203        continue; // null means we dont put it
204      if ( $name==WS_XML_ATTRIBUTES)
205      {
206        foreach ($value as $attr_name => $attr_value)
207        {
208          $this->_writer->write_attribute($attr_name, $attr_value);
209        }
210        unset($data[$name]);
211      }
212      else if ( isset($xml_attributes[$name]) )
213      {
214        $this->_writer->write_attribute($name, $value);
215        unset($data[$name]);
216      }
217    }
218
219    foreach ($data as $name => $value)
220    {
221      if (is_numeric($name))
222        continue;
223      if ($skip_underscore and $name[0]=='_')
224        continue;
225      if ( is_null($value) )
226        continue; // null means we dont put it
227      if ($name!=WS_XML_CONTENT)
228        $this->_writer->start_element($name);
229      $this->encode($value);
230      if ($name!=WS_XML_CONTENT)
231        $this->_writer->end_element($name);
232    }
233  }
234
235  function encode($data, $xml_attributes=array() )
236  {
237    switch (gettype($data))
238    {
239      case 'null':
240      case 'NULL':
241        $this->_writer->write_content('');
242        break;
243      case 'boolean':
244        $this->_writer->write_content($data ? '1' : '0');
245        break;
246      case 'integer':
247      case 'double':
248        $this->_writer->write_content($data);
249        break;
250      case 'string':
251        $this->_writer->write_content($data);
252        break;
253      case 'array':
254        $is_array = range(0, count($data) - 1) === array_keys($data);
255        if ($is_array)
256        {
257          $this->encode_array($data, 'item' );
258        }
259        else
260        {
261          $this->encode_struct($data, false, $xml_attributes);
262        }
263        break;
264      case 'object':
265        switch ( strtolower(get_class($data)) )
266        {
267          case 'pwgnamedarray':
268            $this->encode_array($data->_content, $data->_itemName, $data->_xmlAttributes);
269            break;
270          case 'pwgnamedstruct':
271            $this->encode_array( array($data->_content), $data->_name, $data->_xmlAttributes);
272            break;
273          default:
274            $this->encode_struct(get_object_vars($data), true);
275            break;
276        }
277        break;
278      default:
279        trigger_error("Invalid type ". gettype($data)." ".get_class($data), E_USER_WARNING );
280    }
281  }
282}
283
284?>
Note: See TracBrowser for help on using the repository browser.