setInput($input); } if (is_null($this->input)) { throw new EofException('End of input stream, or no input supplied'); } if (!is_null($options)) { $this->options = $options; } switch($this->input[0]) { case 'vcalendar' : $this->root = new VCalendar(array(), false); break; case 'vcard' : $this->root = new VCard(array(), false); break; default : throw new ParseException('The root component must either be a vcalendar, or a vcard'); } foreach($this->input[1] as $prop) { $this->root->add($this->parseProperty($prop)); } if (isset($this->input[2])) foreach($this->input[2] as $comp) { $this->root->add($this->parseComponent($comp)); } // Resetting the input so we can throw an feof exception the next time. $this->input = null; return $this->root; } /** * Parses a component * * @param array $jComp * @return \Sabre\VObject\Component */ public function parseComponent(array $jComp) { // We can remove $self from PHP 5.4 onward. $self = $this; $properties = array_map( function($jProp) use ($self) { return $self->parseProperty($jProp); }, $jComp[1] ); if (isset($jComp[2])) { $components = array_map( function($jComp) use ($self) { return $self->parseComponent($jComp); }, $jComp[2] ); } else $components = array(); return $this->root->createComponent( $jComp[0], array_merge($properties, $components), $defaults = false ); } /** * Parses properties. * * @param array $jProp * @return \Sabre\VObject\Property */ public function parseProperty(array $jProp) { list( $propertyName, $parameters, $valueType ) = $jProp; $propertyName = strtoupper($propertyName); // This is the default class we would be using if we didn't know the // value type. We're using this value later in this function. $defaultPropertyClass = $this->root->getClassNameForPropertyName($propertyName); $parameters = (array)$parameters; $value = array_slice($jProp, 3); $valueType = strtoupper($valueType); if (isset($parameters['group'])) { $propertyName = $parameters['group'] . '.' . $propertyName; unset($parameters['group']); } $prop = $this->root->createProperty($propertyName, null, $parameters, $valueType); $prop->setJsonValue($value); // We have to do something awkward here. FlatText as well as Text // represents TEXT values. We have to normalize these here. In the // future we can get rid of FlatText once we're allowed to break BC // again. if ($defaultPropertyClass === 'Sabre\VObject\Property\FlatText') { $defaultPropertyClass = 'Sabre\VObject\Property\Text'; } // If the value type we received (e.g.: TEXT) was not the default value // type for the given property (e.g.: BDAY), we need to add a VALUE= // parameter. if ($defaultPropertyClass !== get_class($prop)) { $prop["VALUE"] = $valueType; } return $prop; } /** * Sets the input data * * @param resource|string|array $input * @return void */ public function setInput($input) { if (is_resource($input)) { $input = stream_get_contents($input); } if (is_string($input)) { $input = json_decode($input); } $this->input = $input; } }