source: branches/2.0/include/ws_protocols/rest_encoder.php @ 16498

Last change on this file since 16498 was 4426, checked in by plg, 15 years ago

bug 1211 fixed: with PHP 5.3, the get_class function requires the input
parameter to be an object, or else throws a E_WARNING message. In webservices
files, I have replaced all "get_class" calls by "@get_class".

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