Beispiel #1
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $result = ['name' => null, 'test' => 'anyof', 'is-not-defined' => false, 'param-filters' => [], 'text-matches' => []];
     $att = $reader->parseAttributes();
     $result['name'] = $att['name'];
     if (isset($att['test']) && $att['test'] === 'allof') {
         $result['test'] = 'allof';
     }
     $elems = $reader->parseInnerTree();
     if (is_array($elems)) {
         foreach ($elems as $elem) {
             switch ($elem['name']) {
                 case '{' . Plugin::NS_CARDDAV . '}param-filter':
                     $result['param-filters'][] = $elem['value'];
                     break;
                 case '{' . Plugin::NS_CARDDAV . '}is-not-defined':
                     $result['is-not-defined'] = true;
                     break;
                 case '{' . Plugin::NS_CARDDAV . '}text-match':
                     $matchType = isset($elem['attributes']['match-type']) ? $elem['attributes']['match-type'] : 'contains';
                     if (!in_array($matchType, ['contains', 'equals', 'starts-with', 'ends-with'])) {
                         throw new BadRequest('Unknown match-type: ' . $matchType);
                     }
                     $result['text-matches'][] = ['negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes', 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;unicode-casemap', 'value' => $elem['value'], 'match-type' => $matchType];
                     break;
             }
         }
     }
     return $result;
 }
Beispiel #2
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $result = ['name' => null, 'is-not-defined' => false, 'comp-filters' => [], 'prop-filters' => [], 'time-range' => false];
     $att = $reader->parseAttributes();
     $result['name'] = $att['name'];
     $elems = $reader->parseInnerTree();
     if (is_array($elems)) {
         foreach ($elems as $elem) {
             switch ($elem['name']) {
                 case '{' . Plugin::NS_CALDAV . '}comp-filter':
                     $result['comp-filters'][] = $elem['value'];
                     break;
                 case '{' . Plugin::NS_CALDAV . '}prop-filter':
                     $result['prop-filters'][] = $elem['value'];
                     break;
                 case '{' . Plugin::NS_CALDAV . '}is-not-defined':
                     $result['is-not-defined'] = true;
                     break;
                 case '{' . Plugin::NS_CALDAV . '}time-range':
                     if ($result['name'] === 'VCALENDAR') {
                         throw new BadRequest('You cannot add time-range filters on the VCALENDAR component');
                     }
                     $result['time-range'] = ['start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null];
                     if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) {
                         throw new BadRequest('The end-date must be larger than the start-date');
                     }
                     break;
             }
         }
     }
     return $result;
 }
Beispiel #3
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $result = ['name' => null, 'is-not-defined' => false, 'param-filters' => [], 'text-match' => null, 'time-range' => false];
     $att = $reader->parseAttributes();
     $result['name'] = $att['name'];
     $elems = $reader->parseInnerTree();
     if (is_array($elems)) {
         foreach ($elems as $elem) {
             switch ($elem['name']) {
                 case '{' . Plugin::NS_CALDAV . '}param-filter':
                     $result['param-filters'][] = $elem['value'];
                     break;
                 case '{' . Plugin::NS_CALDAV . '}is-not-defined':
                     $result['is-not-defined'] = true;
                     break;
                 case '{' . Plugin::NS_CALDAV . '}time-range':
                     $result['time-range'] = ['start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null];
                     if ($result['time-range']['start'] && $result['time-range']['end'] && $result['time-range']['end'] <= $result['time-range']['start']) {
                         throw new BadRequest('The end-date must be larger than the start-date');
                     }
                     break;
                 case '{' . Plugin::NS_CALDAV . '}text-match':
                     $result['text-match'] = ['negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes', 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap', 'value' => $elem['value']];
                     break;
             }
         }
     }
     return $result;
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $elems = $reader->parseInnerTree();
     $obj = new self();
     $obj->properties = self::traverse($elems);
     return $obj;
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $timeRange = '{' . Plugin::NS_CALDAV . '}time-range';
     $start = null;
     $end = null;
     foreach ((array) $reader->parseInnerTree([]) as $elem) {
         if ($elem['name'] !== $timeRange) {
             continue;
         }
         $start = empty($elem['attributes']['start']) ?: $elem['attributes']['start'];
         $end = empty($elem['attributes']['end']) ?: $elem['attributes']['end'];
     }
     if (!$start && !$end) {
         throw new BadRequest('The freebusy report must have a time-range element');
     }
     if ($start) {
         $start = DateTimeParser::parseDateTime($start);
     }
     if ($end) {
         $end = DateTimeParser::parseDateTime($end);
     }
     $result = new self();
     $result->start = $start;
     $result->end = $end;
     return $result;
 }
Beispiel #6
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $shareTypes = [];
     foreach ($reader->parseInnerTree() as $elem) {
         if ($elem['name'] === '{' . self::NS_OWNCLOUD . '}share-type') {
             $shareTypes[] = (int) $elem['value'];
         }
     }
     return new self($shareTypes);
 }
Beispiel #7
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $tags = [];
     foreach ($reader->parseInnerTree() as $elem) {
         if ($elem['name'] === '{' . self::NS_OWNCLOUD . '}tag') {
             $tags[] = $elem['value'];
         }
     }
     return new self($tags);
 }
Beispiel #8
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $elems = $reader->parseInnerTree(['{DAV:}sharee' => 'Sabre\\DAV\\Xml\\Element\\Sharee', '{DAV:}share-access' => 'Sabre\\DAV\\Xml\\Property\\ShareAccess', '{DAV:}prop' => 'Sabre\\Xml\\Deserializer\\keyValue']);
     $sharees = [];
     foreach ($elems as $elem) {
         if ($elem['name'] !== '{DAV:}sharee') {
             continue;
         }
         $sharees[] = $elem['value'];
     }
     return new self($sharees);
 }
Beispiel #9
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $self = new self();
     $elementMap = $reader->elementMap;
     $elementMap['{DAV:}prop'] = 'Sabre\\DAV\\Xml\\Element\\Prop';
     $elementMap['{DAV:}set'] = 'Sabre\\Xml\\Element\\KeyValue';
     $elems = $reader->parseInnerTree($elementMap);
     foreach ($elems as $elem) {
         if ($elem['name'] === '{DAV:}set') {
             $self->properties = array_merge($self->properties, $elem['value']['{DAV:}prop']);
         }
     }
     return $self;
 }
Beispiel #10
0
 /**
  *
  * Component loading and tree construction.
  *
  */
 public static function xmlDeserialize(Reader $reader)
 {
     $class_name = get_called_class();
     $component = new $class_name();
     /* First settings. */
     $component->_nodename = 'views';
     /* Iterate through children. */
     $children = $reader->parseInnerTree();
     if (!is_array($children)) {
         return $component;
     }
     foreach ($children as $child) {
         $component->_value[] = self::rec_xmlDeserialize($child, $component);
     }
     return $component;
 }
Beispiel #11
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $result = ['contentType' => $reader->getAttribute('content-type') ?: 'text/calendar', 'version' => $reader->getAttribute('version') ?: '2.0'];
     $elems = (array) $reader->parseInnerTree();
     foreach ($elems as $elem) {
         switch ($elem['name']) {
             case '{' . Plugin::NS_CALDAV . '}expand':
                 $result['expand'] = ['start' => isset($elem['attributes']['start']) ? DateTimeParser::parseDateTime($elem['attributes']['start']) : null, 'end' => isset($elem['attributes']['end']) ? DateTimeParser::parseDateTime($elem['attributes']['end']) : null];
                 if (!$result['expand']['start'] || !$result['expand']['end']) {
                     throw new BadRequest('The "start" and "end" attributes are required when expanding calendar-data');
                 }
                 if ($result['expand']['end'] <= $result['expand']['start']) {
                     throw new BadRequest('The end-date must be larger than the start-date when expanding calendar-data');
                 }
                 break;
         }
     }
     return $result;
 }
Beispiel #12
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * Important note 2: You are responsible for advancing the reader to the
  * next element. Not doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $result = ['name' => null, 'is-not-defined' => false, 'text-match' => null];
     $att = $reader->parseAttributes();
     $result['name'] = $att['name'];
     $elems = $reader->parseInnerTree();
     if (is_array($elems)) {
         foreach ($elems as $elem) {
             switch ($elem['name']) {
                 case '{' . Plugin::NS_CALDAV . '}is-not-defined':
                     $result['is-not-defined'] = true;
                     break;
                 case '{' . Plugin::NS_CALDAV . '}text-match':
                     $result['text-match'] = ['negate-condition' => isset($elem['attributes']['negate-condition']) && $elem['attributes']['negate-condition'] === 'yes', 'collation' => isset($elem['attributes']['collation']) ? $elem['attributes']['collation'] : 'i;ascii-casemap', 'value' => $elem['value']];
                     break;
             }
         }
     }
     return $result;
 }
Beispiel #13
0
 static function xmlDeserialize(Reader $reader)
 {
     $elements = $reader->parseInnerTree(['{' . Plugin::NS_OWNCLOUD . '}set' => 'Sabre\\Xml\\Element\\KeyValue', '{' . Plugin::NS_OWNCLOUD . '}remove' => 'Sabre\\Xml\\Element\\KeyValue']);
     $set = [];
     $remove = [];
     foreach ($elements as $elem) {
         switch ($elem['name']) {
             case '{' . Plugin::NS_OWNCLOUD . '}set':
                 $sharee = $elem['value'];
                 $sumElem = '{' . Plugin::NS_OWNCLOUD . '}summary';
                 $commonName = '{' . Plugin::NS_OWNCLOUD . '}common-name';
                 $set[] = ['href' => $sharee['{DAV:}href'], 'commonName' => isset($sharee[$commonName]) ? $sharee[$commonName] : null, 'summary' => isset($sharee[$sumElem]) ? $sharee[$sumElem] : null, 'readOnly' => !array_key_exists('{' . Plugin::NS_OWNCLOUD . '}read-write', $sharee)];
                 break;
             case '{' . Plugin::NS_OWNCLOUD . '}remove':
                 $remove[] = $elem['value']['{DAV:}href'];
                 break;
         }
     }
     return new self($set, $remove);
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $elems = $reader->parseInnerTree(['{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData', '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue']);
     $newProps = ['hrefs' => [], 'properties' => []];
     foreach ($elems as $elem) {
         switch ($elem['name']) {
             case '{DAV:}prop':
                 $newProps['properties'] = array_keys($elem['value']);
                 if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
                     $newProps += $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'];
                 }
                 break;
             case '{DAV:}href':
                 $newProps['hrefs'][] = Uri\resolve($reader->contextUri, $elem['value']);
                 break;
         }
     }
     $obj = new self();
     foreach ($newProps as $key => $value) {
         $obj->{$key} = $value;
     }
     return $obj;
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $self = new self();
     $foundSearchProp = false;
     $self->test = 'allof';
     if ($reader->getAttribute('test') === 'anyof') {
         $self->test = 'anyof';
     }
     $elemMap = ['{DAV:}property-search' => 'Sabre\\Xml\\Element\\KeyValue', '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue'];
     foreach ($reader->parseInnerTree($elemMap) as $elem) {
         switch ($elem['name']) {
             case '{DAV:}prop':
                 $self->properties = array_keys($elem['value']);
                 break;
             case '{DAV:}property-search':
                 $foundSearchProp = true;
                 // This property has two sub-elements:
                 //   {DAV:}prop - The property to be searched on. This may
                 //                also be more than one
                 //   {DAV:}match - The value to match with
                 if (!isset($elem['value']['{DAV:}prop']) || !isset($elem['value']['{DAV:}match'])) {
                     throw new BadRequest('The {DAV:}property-search element must contain one {DAV:}match and one {DAV:}prop element');
                 }
                 foreach ($elem['value']['{DAV:}prop'] as $propName => $discard) {
                     $self->searchProperties[$propName] = $elem['value']['{DAV:}match'];
                 }
                 break;
             case '{DAV:}apply-to-principal-collection-set':
                 $self->applyToPrincipalCollectionSet = true;
                 break;
         }
     }
     if (!$foundSearchProp) {
         throw new BadRequest('The {DAV:}principal-property-search report must contain at least 1 {DAV:}property-search element');
     }
     return $self;
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $elems = $reader->parseInnerTree(['{urn:ietf:params:xml:ns:caldav}comp-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\CompFilter', '{urn:ietf:params:xml:ns:caldav}prop-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\PropFilter', '{urn:ietf:params:xml:ns:caldav}param-filter' => 'Sabre\\CalDAV\\Xml\\Filter\\ParamFilter', '{urn:ietf:params:xml:ns:caldav}calendar-data' => 'Sabre\\CalDAV\\Xml\\Filter\\CalendarData', '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue']);
     $newProps = ['filters' => null, 'properties' => []];
     if (!is_array($elems)) {
         $elems = [];
     }
     foreach ($elems as $elem) {
         switch ($elem['name']) {
             case '{DAV:}prop':
                 $newProps['properties'] = array_keys($elem['value']);
                 if (isset($elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'])) {
                     $newProps += $elem['value']['{' . Plugin::NS_CALDAV . '}calendar-data'];
                 }
                 break;
             case '{' . Plugin::NS_CALDAV . '}filter':
                 foreach ($elem['value'] as $subElem) {
                     if ($subElem['name'] === '{' . Plugin::NS_CALDAV . '}comp-filter') {
                         if (!is_null($newProps['filters'])) {
                             throw new BadRequest('Only one top-level comp-filter may be defined');
                         }
                         $newProps['filters'] = $subElem['value'];
                     }
                 }
                 break;
         }
     }
     if (is_null($newProps['filters'])) {
         throw new BadRequest('The {' . Plugin::NS_CALDAV . '}filter element is required for this request');
     }
     $obj = new self();
     foreach ($newProps as $key => $value) {
         $obj->{$key} = $value;
     }
     return $obj;
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $elems = (array) $reader->parseInnerTree(['{urn:ietf:params:xml:ns:carddav}prop-filter' => 'Sabre\\CardDAV\\Xml\\Filter\\PropFilter', '{urn:ietf:params:xml:ns:carddav}param-filter' => 'Sabre\\CardDAV\\Xml\\Filter\\ParamFilter', '{urn:ietf:params:xml:ns:carddav}address-data' => 'Sabre\\CardDAV\\Xml\\Filter\\AddressData', '{DAV:}prop' => 'Sabre\\Xml\\Element\\KeyValue']);
     $newProps = ['filters' => null, 'properties' => [], 'test' => 'anyof', 'limit' => null];
     if (!is_array($elems)) {
         $elems = [];
     }
     foreach ($elems as $elem) {
         switch ($elem['name']) {
             case '{DAV:}prop':
                 $newProps['properties'] = array_keys($elem['value']);
                 if (isset($elem['value']['{' . Plugin::NS_CARDDAV . '}address-data'])) {
                     $newProps += $elem['value']['{' . Plugin::NS_CARDDAV . '}address-data'];
                 }
                 break;
             case '{' . Plugin::NS_CARDDAV . '}filter':
                 if (!is_null($newProps['filters'])) {
                     throw new BadRequest('You can only include 1 {' . Plugin::NS_CARDDAV . '}filter element');
                 }
                 if (isset($elem['attributes']['test'])) {
                     $newProps['test'] = $elem['attributes']['test'];
                     if ($newProps['test'] !== 'allof' && $newProps['test'] !== 'anyof') {
                         throw new BadRequest('The "test" attribute must be one of "allof" or "anyof"');
                     }
                 }
                 $newProps['filters'] = [];
                 foreach ((array) $elem['value'] as $subElem) {
                     if ($subElem['name'] === '{' . Plugin::NS_CARDDAV . '}prop-filter') {
                         $newProps['filters'][] = $subElem['value'];
                     }
                 }
                 break;
             case '{' . Plugin::NS_CARDDAV . '}limit':
                 foreach ($elem['value'] as $child) {
                     if ($child['name'] === '{' . Plugin::NS_CARDDAV . '}nresults') {
                         $newProps['limit'] = (int) $child['value'];
                     }
                 }
                 break;
         }
     }
     if (is_null($newProps['filters'])) {
         /*
          * We are supposed to throw this error, but KDE sometimes does not
          * include the filter element, and we need to treat it as if no
          * filters are supplied
          */
         //throw new BadRequest('The {' . Plugin::NS_CARDDAV . '}filter element is required for this request');
         $newProps['filters'] = [];
     }
     $obj = new self();
     foreach ($newProps as $key => $value) {
         $obj->{$key} = $value;
     }
     return $obj;
 }
Beispiel #18
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called staticly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * Important note 2: You are responsible for advancing the reader to the
  * next element. Not doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $tree = $reader->parseInnerTree()[0];
     switch ($tree['name']) {
         case '{DAV:}unauthenticated':
             return new self(self::UNAUTHENTICATED);
         case '{DAV:}authenticated':
             return new self(self::AUTHENTICATED);
         case '{DAV:}href':
             return new self(self::HREF, $tree['value']);
         case '{DAV:}all':
             return new self(self::ALL);
         default:
             throw new BadRequest('Unknown or unsupported principal type: ' . $tree['name']);
     }
 }
Beispiel #19
0
 /**
  * Convert XML Elements to IodefElement Objects
  * @param  SabreReader $reader [description]
  * @return IodefElement
  */
 public static function xmlDeserialize(SabreReader $reader)
 {
     $IodefElement = new static();
     $IodefElement->setAttributes($reader->parseAttributes());
     $innerData = $reader->parseInnerTree();
     // parseInnerTree will return an array or string.
     if (is_array($innerData)) {
         foreach ($innerData as $child) {
             // This should always and only by of type 'object'.
             if (gettype($child['value']) == 'object') {
                 $className = $child['value']->getShortName();
                 if (substr($IodefElement->elements[$className], -6) == '_MULTI') {
                     $IodefElement->{$className}[] = $child['value'];
                 } else {
                     $IodefElement->{$className} = $child['value'];
                 }
             }
         }
     } else {
         if (!empty($innerData)) {
             $IodefElement->value = $innerData;
         }
     }
     return $IodefElement;
 }
Beispiel #20
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * Important note 2: You are responsible for advancing the reader to the
  * next element. Not doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     return new self(new DateTime($reader->parseInnerTree()));
 }
Beispiel #21
0
 /**
  * Parse the curriculum definition file.
  *
  * By passing the official curriculum definition file (XML), this method
  * will parse it and return a curriculum definition it can understand and
  * treat. It mainly needs a "dictionary" of term types.
  *
  * @param string $curriculumXml
  *    The curriculum definition file, in XML.
  * @param string $variant
  *    (optional) The variant of the curriculum to parse. Defaults to 'V_EF'.
  *
  * @return array
  *    An object with 2 properties:
  *    - curriculum: A parsed and prepared curriculum tree. It uses
  *      Educa\DSB\Client\Curriculum\Term\LP21Term elements to define
  *      the curriculum tree.
  *    - dictionary: A dictionary of term identifiers, with name and type
  *      information for each one of them.
  *
  * @see \Educa\DSB\Client\Curriculum\LP21Curriculum::setCurriculumDictionary()
  */
 public static function parseCurriculumXml($curriculumXml, $variant = 'V_EF')
 {
     $reader = new Reader();
     // Prepare custom handlers for reading an XML node. See the Sabre\Xml
     // documentation for more information.
     $baseHandler = function ($reader) use($variant) {
         $node = new \stdClass();
         // Fetch the attributes. We want the UUID attribute.
         $attributes = $reader->parseAttributes();
         $node->uuid = trim($attributes['uuid']);
         // We derive the type from the node name.
         $node->type = strtolower(str_replace('{}', '', trim($reader->getClark())));
         // Give a default description.
         $node->description = (object) array('de' => '');
         // Fetch the descendants.
         $children = $reader->parseInnerTree();
         if (!empty($children)) {
             $node->children = array();
             foreach ($children as $child) {
                 // Look for child types that are relevant for us. Some must
                 // be parsed as child types of their own, others should be
                 // treated as being part of the current node.
                 if (in_array($child['name'], array('{}fach', '{}kompetenzbereich', '{}handlungs-themenaspekt', '{}kompetenz', '{}kompetenzstufe'))) {
                     $node->children[] = $child;
                 } elseif ($child['name'] == '{}bezeichnung') {
                     $node->description = (object) array_reduce($child['value'], function ($carry, $item) {
                         $langcode = strtolower(str_replace('{}', '', $item['name']));
                         $carry[$langcode] = $item['value'];
                         return $carry;
                     }, array());
                 } elseif ($child['name'] == '{}kantone') {
                     $node->cantons = array_map('trim', explode(',', $child['value']));
                 }
             }
         }
         if (!empty($node->cantons) && !in_array($variant, $node->cantons)) {
             return null;
         }
         return $node;
     };
     $kompetenzstufeHandler = function ($reader) use($variant) {
         $nodes = array();
         $cycle = $url = $version = $code = null;
         // Fetch the descendants.
         $children = $reader->parseInnerTree();
         if (!empty($children)) {
             foreach ($children as $child) {
                 if ($child['name'] == '{}absaetze') {
                     $nodes = $child['value'];
                 } elseif ($child['name'] == '{}zyklus') {
                     $cycle = trim($child['value']);
                 } elseif ($child['name'] == '{}lehrplanversion') {
                     $version = trim($child['value']);
                 } elseif ($child['name'] == '{}kanton' && $child['attributes']['id'] == $variant) {
                     foreach ($child['value'] as $grandChild) {
                         if ($grandChild['name'] == '{}code') {
                             $code = trim($grandChild['value']);
                         } elseif ($grandChild['name'] == '{}url') {
                             $url = trim($grandChild['value']);
                         }
                     }
                 }
             }
         }
         // Map all the Kompetenzstufe properties to the child Absaetzen.
         return array_map(function ($node) use($cycle, $url, $version, $code) {
             if (isset($cycle)) {
                 $node->cycle = $cycle;
             }
             if (isset($url)) {
                 $node->url = $url;
             }
             if (isset($version)) {
                 $node->version = $version;
             }
             if (isset($code)) {
                 $node->code = $code;
             }
             return $node;
         }, $nodes);
     };
     $absaetzeHandler = function ($reader) {
         $nodes = array();
         // Fetch the descendants.
         $children = $reader->parseInnerTree();
         if (!empty($children)) {
             foreach ($children as $child) {
                 if ($child['name'] == '{}bezeichnung') {
                     $node = new \stdClass();
                     // We treat it as a "Kompetenzstufe".
                     $node->type = 'kompetenzstufe';
                     $node->description = (object) array_reduce($child['value'], function ($carry, $item) {
                         $langcode = strtolower(str_replace('{}', '', $item['name']));
                         $carry[$langcode] = $item['value'];
                         return $carry;
                     }, array());
                     // The UUID is on the child Bezeichnung element, not our
                     // own node.
                     $node->uuid = $child['attributes']['uuid'];
                     $nodes[] = $node;
                 }
             }
         }
         return $nodes;
     };
     // Register our handler for the following node types. All others will be
     // treated with the default one provided by Sabre\Xml, but we don't
     // really care.
     $reader->elementMap = ['{}fachbereich' => $baseHandler, '{}fach' => $baseHandler, '{}kompetenzbereich' => $baseHandler, '{}handlungs-themenaspekt' => $baseHandler, '{}kompetenz' => $baseHandler, '{}kompetenzstufe' => $kompetenzstufeHandler, '{}absaetze' => $absaetzeHandler];
     // Parse the data.
     $reader->xml($curriculumXml);
     $data = $reader->parse();
     // Prepare the dictionary.
     $dictionary = array();
     // Prepare our root element.
     $root = new LP21Term('root', 'root');
     // Now, recursively parse the tree, transforming it into a tree of
     // LP21Term instances.
     $recurse = function ($tree, $parent) use(&$recurse, &$dictionary) {
         foreach ($tree as $item) {
             // Fetch our nodes.
             $nodes = $item['value'];
             if (!is_array($nodes)) {
                 $nodes = [$nodes];
             }
             // Double check the format. Is this one of our nodes?
             foreach ($nodes as $node) {
                 if (isset($node->uuid) && isset($node->type) && isset($node->description)) {
                     $term = new LP21Term($node->type, $node->uuid, $node->description);
                     $parent->addChild($term);
                     // Add it to our dictionary.
                     $dictionary[$node->uuid] = (object) array('name' => $node->description, 'type' => $node->type);
                     // Do we have an objective code?
                     if (!empty($node->code)) {
                         $term->setCode($node->code);
                         $dictionary[$node->uuid]->code = $node->code;
                     }
                     // Do we have any cantons information?
                     if (!empty($node->cantons)) {
                         $term->setCantons($node->cantons);
                         $dictionary[$node->uuid]->cantons = $node->cantons;
                     }
                     // Do we have curriculum version information?
                     if (!empty($node->version)) {
                         $term->setVersion($node->version);
                         $dictionary[$node->uuid]->version = $node->version;
                     }
                     // Do we have URL information?
                     if (!empty($node->url)) {
                         $term->setUrl($node->url);
                         $dictionary[$node->uuid]->url = $node->url;
                     }
                     // Do we have cycle information?
                     if (!empty($node->cycle)) {
                         $cycles = str_split($node->cycle);
                         $term->setCycles($cycles);
                         $dictionary[$node->uuid]->cycles = $cycles;
                     }
                     if (!empty($node->children)) {
                         $recurse($node->children, $term);
                     }
                 }
             }
         }
     };
     $recurse($data['value'], $root);
     // Return the parsed data.
     return (object) array('curriculum' => $root, 'dictionary' => $dictionary);
 }
Beispiel #22
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $cs = '{' . Plugin::NS_CALENDARSERVER . '}';
     $users = [];
     foreach ($reader->parseInnerTree() as $elem) {
         if ($elem['name'] !== $cs . 'user') {
             continue;
         }
         $user = ['href' => null, 'commonName' => null, 'readOnly' => null, 'summary' => null, 'status' => null];
         foreach ($elem['value'] as $userElem) {
             switch ($userElem['name']) {
                 case $cs . 'invite-accepted':
                     $user['status'] = SharingPlugin::STATUS_ACCEPTED;
                     break;
                 case $cs . 'invite-declined':
                     $user['status'] = SharingPlugin::STATUS_DECLINED;
                     break;
                 case $cs . 'invite-noresponse':
                     $user['status'] = SharingPlugin::STATUS_NORESPONSE;
                     break;
                 case $cs . 'invite-invalid':
                     $user['status'] = SharingPlugin::STATUS_INVALID;
                     break;
                 case '{DAV:}href':
                     $user['href'] = $userElem['value'];
                     break;
                 case $cs . 'common-name':
                     $user['commonName'] = $userElem['value'];
                     break;
                 case $cs . 'access':
                     foreach ($userElem['value'] as $accessHref) {
                         if ($accessHref['name'] === $cs . 'read') {
                             $user['readOnly'] = true;
                         }
                     }
                     break;
                 case $cs . 'summary':
                     $user['summary'] = $userElem['value'];
                     break;
             }
         }
         if (!$user['status']) {
             throw new \InvalidArgumentException('Every user must have one of cs:invite-accepted, cs:invite-declined, cs:invite-noresponse or cs:invite-invalid');
         }
         $users[] = $user;
     }
     return new self($users);
 }
    /**
     * The deserialize method is called during xml parsing.
     *
     * This method is called statictly, this is because in theory this method
     * may be used as a type of constructor, or factory method.
     *
     * Often you want to return an instance of the current class, but you are
     * free to return other data as well.
     *
     * You are responsible for advancing the reader to the next element. Not
     * doing anything will result in a never-ending loop.
     *
     * If you just want to skip parsing for this element altogether, you can
     * just call $reader->next();
     *
     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
     * the next element.
     *
     * @param Reader $reader
     * @return mixed
     */
    static function xmlDeserialize(Reader $reader) {

        $elems = $reader->parseInnerTree();

        $components = [];

        foreach ($elems as $elem) {
            if ($elem['name'] === '{' . Plugin::NS_CALDAV . '}comp') {
                $components[] = $elem['attributes']['name'];
            }
        }

        return new self($components);

    }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $result = [];
     $tree = $reader->parseInnerTree(['{DAV:}privilege' => 'Sabre\\Xml\\Element\\Elements']);
     foreach ($tree as $element) {
         if ($element['name'] !== '{DAV:}privilege') {
             continue;
         }
         $result[] = $element['value'][0];
     }
     return new self($result);
 }
Beispiel #25
0
    /**
     * The deserialize method is called during xml parsing.
     *
     * This method is called statictly, this is because in theory this method
     * may be used as a type of constructor, or factory method.
     *
     * Often you want to return an instance of the current class, but you are
     * free to return other data as well.
     *
     * Important note 2: You are responsible for advancing the reader to the
     * next element. Not doing anything will result in a never-ending loop.
     *
     * If you just want to skip parsing for this element altogether, you can
     * just call $reader->next();
     *
     * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
     * the next element.
     *
     * @param Reader $reader
     * @return mixed
     */
    static function xmlDeserialize(Reader $reader) {

        $elementMap = [
            '{DAV:}ace'       => 'Sabre\Xml\Element\KeyValue',
            '{DAV:}privilege' => 'Sabre\Xml\Element\Elements',
            '{DAV:}principal' => 'Sabre\DAVACL\Xml\Property\Principal',
        ];

        $privileges = [];

        foreach ((array)$reader->parseInnerTree($elementMap) as $element) {

            if ($element['name'] !== '{DAV:}ace') {
                continue;
            }
            $ace = $element['value'];

            if (empty($ace['{DAV:}principal'])) {
                throw new DAV\Exception\BadRequest('Each {DAV:}ace element must have one {DAV:}principal element');
            }
            $principal = $ace['{DAV:}principal'];

            switch ($principal->getType()) {
                case Principal::HREF :
                    $principal = $principal->getHref();
                    break;
                case Principal::AUTHENTICATED :
                    $principal = '{DAV:}authenticated';
                    break;
                case Principal::UNAUTHENTICATED :
                    $principal = '{DAV:}unauthenticated';
                    break;
                case Principal::ALL :
                    $principal = '{DAV:}all';
                    break;

            }

            $protected = array_key_exists('{DAV:}protected', $ace);

            if (!isset($ace['{DAV:}grant'])) {
                throw new DAV\Exception\NotImplemented('Every {DAV:}ace element must have a {DAV:}grant element. {DAV:}deny is not yet supported');
            }
            foreach ($ace['{DAV:}grant'] as $elem) {
                if ($elem['name'] !== '{DAV:}privilege') {
                    continue;
                }

                foreach ($elem['value'] as $priv) {
                    $privileges[] = [
                        'principal' => $principal,
                        'protected' => $protected,
                        'privilege' => $priv,
                    ];
                }

            }

        }

        return new self($privileges);

    }
Beispiel #26
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * Important note 2: You are responsible for advancing the reader to the
  * next element. Not doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param XML\Reader $reader
  * @return mixed
  */
 public static function deserializeXml(XML\Reader $reader)
 {
     $subTree = $reader->parseInnerTree();
     return $subTree;
 }
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $elems = $reader->parseInnerTree();
     $components = [];
     foreach ((array) $elems as $elem) {
         if ($elem['name'] === '{' . Plugin::NS_CALDAV . '}comp') {
             $components[] = $elem['attributes']['name'];
         }
     }
     if (!$components) {
         throw new ParseException('supported-calendar-component-set must have at least one CALDAV:comp element');
     }
     return new self($components);
 }
Beispiel #28
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $reader->pushContext();
     $reader->elementMap['{DAV:}propstat'] = 'Sabre\\Xml\\Element\\KeyValue';
     // We are overriding the parser for {DAV:}prop. This deserializer is
     // almost identical to the one for Sabre\Xml\Element\KeyValue.
     //
     // The difference is that if there are any child-elements inside of
     // {DAV:}prop, that have no value, normally any deserializers are
     // called. But we don't want this, because a singular element without
     // child-elements implies 'no value' in {DAV:}prop, so we want to skip
     // deserializers and just set null for those.
     $reader->elementMap['{DAV:}prop'] = function (Reader $reader) {
         if ($reader->isEmptyElement) {
             $reader->next();
             return [];
         }
         $values = [];
         $reader->read();
         do {
             if ($reader->nodeType === Reader::ELEMENT) {
                 $clark = $reader->getClark();
                 if ($reader->isEmptyElement) {
                     $values[$clark] = null;
                     $reader->next();
                 } else {
                     $values[$clark] = $reader->parseCurrentElement()['value'];
                 }
             } else {
                 $reader->read();
             }
         } while ($reader->nodeType !== Reader::END_ELEMENT);
         $reader->read();
         return $values;
     };
     $elems = $reader->parseInnerTree();
     $reader->popContext();
     $href = null;
     $propertyLists = [];
     $statusCode = null;
     foreach ($elems as $elem) {
         switch ($elem['name']) {
             case '{DAV:}href':
                 $href = $elem['value'];
                 break;
             case '{DAV:}propstat':
                 $status = $elem['value']['{DAV:}status'];
                 list(, $status, ) = explode(' ', $status, 3);
                 $properties = isset($elem['value']['{DAV:}prop']) ? $elem['value']['{DAV:}prop'] : [];
                 $propertyLists[$status] = $properties;
                 break;
             case '{DAV:}status':
                 list(, $statusCode, ) = explode(' ', $elem['value'], 3);
                 break;
         }
     }
     return new self($href, $propertyLists, $statusCode);
 }
Beispiel #29
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * You are responsible for advancing the reader to the next element. Not
  * doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Reader $reader)
 {
     $hrefs = [];
     foreach ((array) $reader->parseInnerTree() as $elem) {
         if ($elem['name'] !== '{DAV:}href') {
             continue;
         }
         $hrefs[] = $elem['value'];
     }
     if ($hrefs) {
         return new self($hrefs, false);
     }
 }
Beispiel #30
0
 /**
  * The deserialize method is called during xml parsing.
  *
  * This method is called statictly, this is because in theory this method
  * may be used as a type of constructor, or factory method.
  *
  * Often you want to return an instance of the current class, but you are
  * free to return other data as well.
  *
  * Important note 2: You are responsible for advancing the reader to the
  * next element. Not doing anything will result in a never-ending loop.
  *
  * If you just want to skip parsing for this element altogether, you can
  * just call $reader->next();
  *
  * $reader->parseInnerTree() will parse the entire sub-tree, and advance to
  * the next element.
  *
  * @param Xml\Reader $reader
  * @return mixed
  */
 static function xmlDeserialize(Xml\Reader $reader)
 {
     $subTree = $reader->parseInnerTree();
     return $subTree;
 }