7 class Value implements \Countable, \IteratorAggregate, \ArrayAccess
9 public static $xmlrpcI4 =
"i4";
10 public static $xmlrpcInt =
"int";
11 public static $xmlrpcBoolean =
"boolean";
12 public static $xmlrpcDouble =
"double";
13 public static $xmlrpcString =
"string";
14 public static $xmlrpcDateTime =
"dateTime.iso8601";
15 public static $xmlrpcBase64 =
"base64";
16 public static $xmlrpcArray =
"array";
17 public static $xmlrpcStruct =
"struct";
18 public static $xmlrpcValue =
"undefined";
19 public static $xmlrpcNull =
"null";
21 public static $xmlrpcTypes = array(
27 "dateTime.iso8601" => 1,
37 public $_php_class =
null;
50 if ($val !== -1 || $type !=
'') {
54 $this->me[
'string'] = $val;
61 case 'dateTime.iso8601':
65 $this->me[$type] = $val;
69 $this->me[
'array'] = $val;
73 $this->me[
'struct'] = $val;
76 error_log(
"XML-RPC: " . __METHOD__ .
": not a known type ($type)");
92 if (isset(static::$xmlrpcTypes[$type])) {
93 $typeOf = static::$xmlrpcTypes[$type];
97 error_log(
"XML-RPC: " . __METHOD__ .
": not a scalar type ($type)");
104 if ($type == static::$xmlrpcBoolean) {
105 if (strcasecmp($val,
'true') == 0 || $val == 1 || ($val ==
true && strcasecmp($val,
'false'))) {
112 switch ($this->mytype) {
114 error_log(
'XML-RPC: ' . __METHOD__ .
': scalar xmlrpc value can have only one value');
117 error_log(
'XML-RPC: ' . __METHOD__ .
': cannot add anonymous scalar to struct xmlrpc value');
121 $this->me[
'array'][] =
new Value($val, $type);
126 $this->me[$type] = $val;
127 $this->mytype = $typeOf;
144 if ($this->mytype == 0) {
145 $this->mytype = static::$xmlrpcTypes[
'array'];
146 $this->me[
'array'] = $values;
149 } elseif ($this->mytype == 2) {
151 $this->me[
'array'] = array_merge($this->me[
'array'], $values);
155 error_log(
'XML-RPC: ' . __METHOD__ .
': already initialized as a [' . $this->kindOf() .
']');
171 if ($this->mytype == 0) {
172 $this->mytype = static::$xmlrpcTypes[
'struct'];
173 $this->me[
'struct'] = $values;
176 } elseif ($this->mytype == 3) {
178 $this->me[
'struct'] = array_merge($this->me[
'struct'], $values);
182 error_log(
'XML-RPC: ' . __METHOD__ .
': already initialized as a [' . $this->kindOf() .
']');
194 switch ($this->mytype) {
213 if (!isset(static::$xmlrpcTypes[$typ])) {
217 switch (static::$xmlrpcTypes[$typ]) {
220 case static::$xmlrpcBase64:
221 $rs .=
"<${typ}>" . base64_encode($val) .
"</${typ}>";
223 case static::$xmlrpcBoolean:
224 $rs .=
"<${typ}>" . ($val ?
'1' :
'0') .
"</${typ}>";
226 case static::$xmlrpcString:
229 $rs .=
"<${typ}>" . Charset::instance()->encodeEntities($val, PhpXmlRpc::$xmlrpc_internalencoding, $charsetEncoding) .
"</${typ}>";
231 case static::$xmlrpcInt:
232 case static::$xmlrpcI4:
233 $rs .=
"<${typ}>" . (int)$val .
"</${typ}>";
235 case static::$xmlrpcDouble:
241 $rs .=
"<${typ}>" . preg_replace(
'/\\.?0+$/',
'', number_format((
double)$val, 128,
'.',
'')) .
"</${typ}>";
243 case static::$xmlrpcDateTime:
244 if (is_string($val)) {
245 $rs .=
"<${typ}>${val}</${typ}>";
246 } elseif (is_a($val,
'DateTime')) {
247 $rs .=
"<${typ}>" . $val->format(
'Ymd\TH:i:s') .
"</${typ}>";
248 } elseif (is_int($val)) {
249 $rs .=
"<${typ}>" . strftime(
"%Y%m%dT%H:%M:%S", $val) .
"</${typ}>";
252 $rs .=
"<${typ}>${val}</${typ}>";
255 case static::$xmlrpcNull:
256 if (PhpXmlRpc::$xmlrpc_null_apache_encoding) {
265 $rs .=
"<${typ}>${val}</${typ}>";
270 if ($this->_php_class) {
271 $rs .=
'<struct php_class="' . $this->_php_class .
"\">\n";
275 $charsetEncoder = Charset::instance();
276 foreach ($val as $key2 => $val2) {
277 $rs .=
'<member><name>' . $charsetEncoder->encodeEntities($key2, PhpXmlRpc::$xmlrpc_internalencoding, $charsetEncoding) .
"</name>\n";
279 $rs .= $val2->serialize($charsetEncoding);
280 $rs .=
"</member>\n";
286 $rs .=
"<array>\n<data>\n";
287 foreach ($val as $element) {
289 $rs .= $element->serialize($charsetEncoding);
291 $rs .=
"</data>\n</array>";
313 list($typ, $val) = each($this->me);
315 return '<value>' . $this->serializedata($typ, $val, $charsetEncoding) .
"</value>\n";
331 return array_key_exists($key, $this->me[
'struct']);
346 return $this->me[
'struct'][$key];
355 reset($this->me[
'struct']);
367 return each($this->me[
'struct']);
378 list(, $b) = each($this->me);
392 list($a,) = each($this->me);
393 if ($a == static::$xmlrpcI4) {
394 $a = static::$xmlrpcInt;
411 return $this->me[
'array'][$key];
423 return count($this->me[
'array']);
435 return count($this->me[
'struct']);
448 switch ($this->mytype) {
450 return count($this->me[
'struct']);
452 return count($this->me[
'array']);
466 switch ($this->mytype) {
468 return new \ArrayIterator($this->me[
'struct']);
470 return new \ArrayIterator($this->me[
'array']);
472 return new \ArrayIterator($this->me);
474 return new \ArrayIterator();
476 return new \ArrayIterator();
482 switch ($this->mytype) {
485 throw new \Exception(
'It is only possible to add Value objects to an XML-RPC Struct');
487 if (is_null($offset)) {
489 throw new \Exception(
'It is not possible to add anonymous members to an XML-RPC Struct');
491 $this->me[
'struct'][$offset] = $value;
496 throw new \Exception(
'It is only possible to add Value objects to an XML-RPC Array');
498 if (is_null($offset)) {
499 $this->me[
'array'][] = $value;
502 $this->me[
'array'][$offset] = $value;
508 list($type,) = each($this->me);
509 if ($type != $offset) {
510 throw new \Exception(
'');
512 $this->me[$type] = $value;
516 throw new \Exception(
"XML-RPC Value is of type 'undef' and its value can not be set using array index");
521 switch ($this->mytype) {
523 return isset($this->me[
'struct'][$offset]);
525 return isset($this->me[
'array'][$offset]);
528 return $offset == $this->scalartyp();
535 switch ($this->mytype) {
537 unset($this->me[
'struct'][$offset]);
540 unset($this->me[
'array'][$offset]);
544 throw new \Exception(
"XML-RPC Value is of type 'scalar' and its value can not be unset using array index");
546 throw new \Exception(
"XML-RPC Value is of type 'undef' and its value can not be unset using array index");
551 switch ($this->mytype) {
553 return isset($this->me[
'struct'][$offset]) ? $this->me[
'struct'][$offset] :
null;
555 return isset($this->me[
'array'][$offset]) ? $this->me[
'array'][$offset] :
null;
559 list($type, $value) = each($this->me);
560 return $type == $offset ? $value :
null;
563 throw new \Exception(
"XML-RPC Value is of type 'undef' and can not be accessed using array index");