123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- <?php
- namespace Sabre\VObject;
- class Component extends Node {
-
- public $name;
-
- public $children = array();
-
- public function __construct(Document $root, $name, array $children = array(), $defaults = true) {
- $this->name = strtoupper($name);
- $this->root = $root;
- if ($defaults) {
-
-
-
-
- $list = $this->getDefaults();
- $nodes = array();
- foreach($children as $key=>$value) {
- if ($value instanceof Node) {
- if (isset($list[$value->name])) {
- unset($list[$value->name]);
- }
- $nodes[] = $value;
- } else {
- $list[$key] = $value;
- }
- }
- foreach($list as $key=>$value) {
- $this->add($key, $value);
- }
- foreach($nodes as $node) {
- $this->add($node);
- }
- } else {
- foreach($children as $k=>$child) {
- if ($child instanceof Node) {
-
- $this->add($child);
- } else {
-
- $this->add($k, $child);
- }
- }
- }
- }
-
- public function add($a1, $a2 = null, $a3 = null) {
- if ($a1 instanceof Node) {
- if (!is_null($a2)) {
- throw new \InvalidArgumentException('The second argument must not be specified, when passing a VObject Node');
- }
- $a1->parent = $this;
- $this->children[] = $a1;
- return $a1;
- } elseif(is_string($a1)) {
- $item = $this->root->create($a1, $a2, $a3);
- $item->parent = $this;
- $this->children[] = $item;
- return $item;
- } else {
- throw new \InvalidArgumentException('The first argument must either be a \\Sabre\\VObject\\Node or a string');
- }
- }
-
- public function remove($item) {
- if (is_string($item)) {
- $children = $this->select($item);
- foreach($children as $k=>$child) {
- unset($this->children[$k]);
- }
- return $child;
- } else {
- foreach($this->children as $k => $child) {
- if ($child===$item) {
- unset($this->children[$k]);
- return $child;
- }
- }
- throw new \InvalidArgumentException('The item you passed to remove() was not a child of this component');
- }
- }
-
- public function children() {
- return $this->children;
- }
-
- public function getComponents() {
- $result = array();
- foreach($this->children as $child) {
- if ($child instanceof Component) {
- $result[] = $child;
- }
- }
- return $result;
- }
-
- public function select($name) {
- $group = null;
- $name = strtoupper($name);
- if (strpos($name,'.')!==false) {
- list($group,$name) = explode('.', $name, 2);
- }
- $result = array();
- foreach($this->children as $key=>$child) {
- if (
- (
- strtoupper($child->name) === $name
- && (is_null($group) || ( $child instanceof Property && strtoupper($child->group) === $group))
- )
- ||
- (
- $name === '' && $child instanceof Property && strtoupper($child->group) === $group
- )
- ) {
- $result[$key] = $child;
- }
- }
- reset($result);
- return $result;
- }
-
- public function serialize() {
- $str = "BEGIN:" . $this->name . "\r\n";
-
- $sortScore = function($key, $array) {
- if ($array[$key] instanceof Component) {
-
-
- if ($array[$key]->name === 'VTIMEZONE') {
- $score=300000000;
- return $score+$key;
- } else {
- $score=400000000;
- return $score+$key;
- }
- } else {
-
-
- if ($array[$key] instanceof Property) {
- if ($array[$key]->name === 'VERSION') {
- $score=100000000;
- return $score+$key;
- } else {
-
- $score=200000000;
- return $score+$key;
- }
- }
- }
- };
- $tmp = $this->children;
- uksort(
- $this->children,
- function($a, $b) use ($sortScore, $tmp) {
- $sA = $sortScore($a, $tmp);
- $sB = $sortScore($b, $tmp);
- return $sA - $sB;
- }
- );
- foreach($this->children as $child) $str.=$child->serialize();
- $str.= "END:" . $this->name . "\r\n";
- return $str;
- }
-
- public function jsonSerialize() {
- $components = array();
- $properties = array();
- foreach($this->children as $child) {
- if ($child instanceof Component) {
- $components[] = $child->jsonSerialize();
- } else {
- $properties[] = $child->jsonSerialize();
- }
- }
- return array(
- strtolower($this->name),
- $properties,
- $components
- );
- }
-
- protected function getDefaults() {
- return array();
- }
-
-
- public function __get($name) {
- $matches = $this->select($name);
- if (count($matches)===0) {
- return null;
- } else {
- $firstMatch = current($matches);
-
- $firstMatch->setIterator(new ElementList(array_values($matches)));
- return $firstMatch;
- }
- }
-
- public function __isset($name) {
- $matches = $this->select($name);
- return count($matches)>0;
- }
-
- public function __set($name, $value) {
- $matches = $this->select($name);
- $overWrite = count($matches)?key($matches):null;
- if ($value instanceof Component || $value instanceof Property) {
- $value->parent = $this;
- if (!is_null($overWrite)) {
- $this->children[$overWrite] = $value;
- } else {
- $this->children[] = $value;
- }
- } else {
- $property = $this->root->create($name,$value);
- $property->parent = $this;
- if (!is_null($overWrite)) {
- $this->children[$overWrite] = $property;
- } else {
- $this->children[] = $property;
- }
- }
- }
-
- public function __unset($name) {
- $matches = $this->select($name);
- foreach($matches as $k=>$child) {
- unset($this->children[$k]);
- $child->parent = null;
- }
- }
-
-
- public function __clone() {
- foreach($this->children as $key=>$child) {
- $this->children[$key] = clone $child;
- $this->children[$key]->parent = $this;
- }
- }
-
- public function getValidationRules() {
- return array();
- }
-
- public function validate($options = 0) {
- $rules = $this->getValidationRules();
- $defaults = $this->getDefaults();
- $propertyCounters = array();
- $messages = array();
- foreach($this->children as $child) {
- $name = strtoupper($child->name);
- if (!isset($propertyCounters[$name])) {
- $propertyCounters[$name] = 1;
- } else {
- $propertyCounters[$name]++;
- }
- $messages = array_merge($messages, $child->validate($options));
- }
- foreach($rules as $propName => $rule) {
- switch($rule) {
- case '0' :
- if (isset($propertyCounters[$propName])) {
- $messages[] = array(
- 'level' => 3,
- 'message' => $propName . ' MUST NOT appear in a ' . $this->name . ' component',
- 'node' => $this,
- );
- }
- break;
- case '1' :
- if (!isset($propertyCounters[$propName]) || $propertyCounters[$propName]!==1) {
- $repaired = false;
- if ($options & self::REPAIR && isset($defaults[$propName])) {
- $this->add($propName, $defaults[$propName]);
- }
- $messages[] = array(
- 'level' => $repaired?1:3,
- 'message' => $propName . ' MUST appear exactly once in a ' . $this->name . ' component',
- 'node' => $this,
- );
- }
- break;
- case '+' :
- if (!isset($propertyCounters[$propName]) || $propertyCounters[$propName] < 1) {
- $messages[] = array(
- 'level' => 3,
- 'message' => $propName . ' MUST appear at least once in a ' . $this->name . ' component',
- 'node' => $this,
- );
- }
- break;
- case '*' :
- break;
- case '?' :
- if (isset($propertyCounters[$propName]) && $propertyCounters[$propName] > 1) {
- $messages[] = array(
- 'level' => 3,
- 'message' => $propName . ' MUST NOT appear more than once in a ' . $this->name . ' component',
- 'node' => $this,
- );
- }
- break;
- }
- }
- return $messages;
- }
- }
|