/** * 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; }
/** * 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; }
/** * 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; }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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; }
/** * * 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; }
/** * 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; }
/** * 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; }
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; }
/** * 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']); } }
/** * 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; }
/** * 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())); }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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); }
/** * 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); } }
/** * 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; }