function getItem(\DOMNode $itemDomNode) { $item = new \stdClass(); $item->title = $itemDomNode->getElementsByTagName('title')->item(0)->firstChild->data; $item->link = $itemDomNode->getElementsByTagName('link')->item(0)->firstChild->data; $item->description = $itemDomNode->getElementsByTagName('description')->item(0)->firstChild->data; $authorText = $itemDomNode->getElementsByTagName('author')->item(0)->firstChild->data; $arr = explode(' ', trim($authorText)); $item->authorEmail = trim($arr[0]); $item->guid = $itemDomNode->getElementsByTagName('guid')->item(0)->firstChild->data; $item->pubDate = $itemDomNode->getElementsByTagName('pubDate')->item(0)->firstChild->data; $item->viaUrl = $itemDomNode->getElementsByTagNameNS('http://www.editoreye.com/rss/via', 'link')->item(0)->getAttribute('url'); $item->via = $itemDomNode->getElementsByTagNameNS('http://www.editoreye.com/rss/via', 'link')->item(0)->getAttribute('name'); $item->authorName = $itemDomNode->getElementsByTagNameNS('http://purl.org/dc/elements/1.1/', 'creator')->item(0)->firstChild->data; $item->content = $itemDomNode->getElementsByTagName('content')->item(0)->firstChild->data; return $item; }
/** * Get array of declared font names * * @return array */ private function getFonts() { $nodes = $this->fonts->getElementsByTagNameNS(self::NS_STYLE, 'font-face'); $fonts = array(); foreach ($nodes as $node) { $fonts[] = $node->getAttributeNS(self::NS_STYLE, 'name'); } return $fonts; }
/** * Return array of descendant DOMNode of $node with tagName equals to $name * * @param DOMNode $node to starts with * @param string $name of descendant * * @return array of descendant DOMNode with tagName equals to $name */ public static function getNodesName($node, $name) { if (strpos($name, ':') !== false) { list(, $localname) = explode(':', $name); $nodes = $node->getElementsByTagNameNS('*', $localname); } else { $nodes = $node->getElementsByTagName($name); } return self::filterNodeListByName($nodes, $name); }
/** * This function handles the calendar-multiget REPORT. * * prefetch events into calendar container class, to avoid single lookup of events * * @param \DOMNode $dom * @return void */ public function calendarMultiGetReport($dom) { $properties = array_keys(\Sabre\DAV\XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV', 'href'); $filters = array('name' => 'VCALENDAR', 'comp-filters' => array(array('name' => 'VEVENT', 'prop-filters' => array()))); foreach ($hrefElems as $elem) { list($dirName, $baseName) = \Sabre\DAV\URLUtil::splitPath($elem->nodeValue); $filters['comp-filters'][0]['prop-filters'][] = array('name' => 'UID', 'text-match' => array('value' => $baseName)); } $node = $this->server->tree->getNodeForPath($this->server->getRequestUri()); $node->calendarQuery($filters); }
/** * This function handles the addressbook-multiget REPORT. * * This report is used by the client to fetch the content of a series * of urls. Effectively avoiding a lot of redundant requests. * * @param DOMNode $dom * @return void */ public function addressbookMultiGetReport($dom) { $properties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV', 'href'); $propertyList = array(); foreach ($hrefElems as $elem) { $uri = $this->server->calculateUri($elem->nodeValue); list($propertyList[]) = $this->server->getPropertiesForPath($uri, $properties); } $this->server->httpResponse->sendStatus(207); $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList)); }
/** * This function handles the addressbook-multiget REPORT. * * This report is used by the client to fetch the content of a series * of urls. Effectively avoiding a lot of redundant requests. * * @param \DOMNode $dom * @return void */ function addressbookMultiGetReport($dom) { $properties = array_keys(DAV\XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV', 'href'); $propertyList = []; $uris = []; foreach ($hrefElems as $elem) { $uris[] = $this->server->calculateUri($elem->nodeValue); } $xpath = new \DOMXPath($dom); $xpath->registerNameSpace('card', Plugin::NS_CARDDAV); $xpath->registerNameSpace('dav', 'urn:DAV'); $contentType = $xpath->evaluate("string(/card:addressbook-multiget/dav:prop/card:address-data/@content-type)"); $version = $xpath->evaluate("string(/card:addressbook-multiget/dav:prop/card:address-data/@version)"); if ($version) { $contentType .= '; version=' . $version; } $vcardType = $this->negotiateVCard($contentType); $propertyList = []; foreach ($this->server->getPropertiesForMultiplePaths($uris, $properties) as $props) { if (isset($props['200']['{' . self::NS_CARDDAV . '}address-data'])) { $props['200']['{' . self::NS_CARDDAV . '}address-data'] = $this->convertVCard($props[200]['{' . self::NS_CARDDAV . '}address-data'], $vcardType); } $propertyList[] = $props; } $prefer = $this->server->getHTTPPRefer(); $this->server->httpResponse->setStatus(207); $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); $this->server->httpResponse->setBody($this->server->generateMultiStatus($propertyList, $prefer['return-minimal'])); }
/** * This function handles the calendar-multiget REPORT. * * This report is used by the client to fetch the content of a series * of urls. Effectively avoiding a lot of redundant requests. * * @param \DOMNode $dom * @return void */ public function calendarMultiGetReport($dom) { $properties = array_keys(DAV\XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV', 'href'); $xpath = new \DOMXPath($dom); $xpath->registerNameSpace('cal', Plugin::NS_CALDAV); $xpath->registerNameSpace('dav', 'urn:DAV'); $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand'); if ($expand->length > 0) { $expandElem = $expand->item(0); $start = $expandElem->getAttribute('start'); $end = $expandElem->getAttribute('end'); if (!$start || !$end) { throw new DAV\Exception\BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element'); } $start = VObject\DateTimeParser::parseDateTime($start); $end = VObject\DateTimeParser::parseDateTime($end); if ($end <= $start) { throw new DAV\Exception\BadRequest('The end-date must be larger than the start-date in the expand element.'); } $expand = true; } else { $expand = false; } foreach ($hrefElems as $elem) { $uri = $this->server->calculateUri($elem->nodeValue); list($objProps) = $this->server->getPropertiesForPath($uri, $properties); if ($expand && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) { $vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']); $vObject->expand($start, $end); $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize(); } $propertyList[] = $objProps; } $prefer = $this->server->getHTTPPRefer(); $this->server->httpResponse->sendStatus(207); $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); $this->server->httpResponse->sendBody($this->server->generateMultiStatus($propertyList, $prefer['return-minimal'])); }
/** * This function handles the calendar-query REPORT * * This report is used by clients to request calendar objects based on * complex conditions. * * @param DOMNode $dom * @return void */ public function calendarQueryReport($dom) { $requestedProperties = array_keys(Sabre_DAV_XMLUtil::parseProperties($dom->firstChild)); $filterNode = $dom->getElementsByTagNameNS('urn:ietf:params:xml:ns:caldav', 'filter'); if ($filterNode->length !== 1) { throw new Sabre_DAV_Exception_BadRequest('The calendar-query report must have a filter element'); } $filters = Sabre_CalDAV_XMLUtil::parseCalendarQueryFilters($filterNode->item(0)); $requestedCalendarData = true; if (!in_array('{urn:ietf:params:xml:ns:caldav}calendar-data', $requestedProperties)) { // We always retrieve calendar-data, as we need it for filtering. $requestedProperties[] = '{urn:ietf:params:xml:ns:caldav}calendar-data'; // If calendar-data wasn't explicitly requested, we need to remove // it after processing. $requestedCalendarData = false; } // These are the list of nodes that potentially match the requirement $candidateNodes = $this->server->getPropertiesForPath($this->server->getRequestUri(), $requestedProperties, $this->server->getHTTPDepth(0)); $verifiedNodes = array(); foreach ($candidateNodes as $node) { // If the node didn't have a calendar-data property, it must not be a calendar object if (!isset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'])) { continue; } if ($this->validateFilters($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data'], $filters)) { if (!$requestedCalendarData) { unset($node[200]['{urn:ietf:params:xml:ns:caldav}calendar-data']); } $verifiedNodes[] = $node; } } $this->server->httpResponse->sendStatus(207); $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); $this->server->httpResponse->sendBody($this->server->generateMultiStatus($verifiedNodes)); }
/** * Read the node value, decode it if needed * * @param \DOMNode $node The node to read * @param TagInterface $tag The tag associated * @return ValueInterface The value extracted */ protected function readNodeValue(\DOMNode $node, TagInterface $tag = null) { $nodeName = $this->normalize($node->nodeName); if (is_null($tag) && TagFactory::hasFromRDFTagname($nodeName)) { $tag = TagFactory::getFromRDFTagname($nodeName); } if ($node->getElementsByTagNameNS(self::RDF_NAMESPACE, 'Bag')->length > 0) { $ret = array(); foreach ($node->getElementsByTagNameNS(self::RDF_NAMESPACE, 'li') as $nodeElement) { $ret[] = $nodeElement->nodeValue; } if (is_null($tag) || $tag->isMulti()) { return new Multi($ret); } else { return new Mono(implode(' ', $ret)); } } elseif ($node->getAttribute('rdf:datatype') === 'http://www.w3.org/2001/XMLSchema#base64Binary') { if (is_null($tag) || $tag->isBinary()) { return Binary::loadFromBase64(trim($node->nodeValue)); } else { return new Mono(base64_decode(trim($node->nodeValue))); } } else { if (!is_null($tag) && $tag->isMulti()) { return new Multi($node->nodeValue); } else { return new Mono($node->nodeValue); } } }
/** * This function handles the calendar-multiget REPORT. * * This report is used by the client to fetch the content of a series * of urls. Effectively avoiding a lot of redundant requests. * * @param \DOMNode $dom * @return void */ function calendarMultiGetReport($dom) { $properties = array_keys(DAV\XMLUtil::parseProperties($dom->firstChild)); $hrefElems = $dom->getElementsByTagNameNS('urn:DAV', 'href'); $xpath = new \DOMXPath($dom); $xpath->registerNameSpace('cal', Plugin::NS_CALDAV); $xpath->registerNameSpace('dav', 'urn:DAV'); $expand = $xpath->query('/cal:calendar-multiget/dav:prop/cal:calendar-data/cal:expand'); if ($expand->length > 0) { $expandElem = $expand->item(0); $start = $expandElem->getAttribute('start'); $end = $expandElem->getAttribute('end'); if (!$start || !$end) { throw new DAV\Exception\BadRequest('The "start" and "end" attributes are required for the CALDAV:expand element'); } $start = VObject\DateTimeParser::parseDateTime($start); $end = VObject\DateTimeParser::parseDateTime($end); if ($end <= $start) { throw new DAV\Exception\BadRequest('The end-date must be larger than the start-date in the expand element.'); } $expand = true; } else { $expand = false; } $needsJson = $xpath->evaluate("boolean(/cal:calendar-multiget/dav:prop/cal:calendar-data[@content-type='application/calendar+json'])"); $uris = []; foreach ($hrefElems as $elem) { $uris[] = $this->server->calculateUri($elem->nodeValue); } $tz = null; $timeZones = []; foreach ($this->server->getPropertiesForMultiplePaths($uris, $properties) as $uri => $objProps) { if (($needsJson || $expand) && isset($objProps[200]['{' . self::NS_CALDAV . '}calendar-data'])) { $vObject = VObject\Reader::read($objProps[200]['{' . self::NS_CALDAV . '}calendar-data']); if ($expand) { // We're expanding, and for that we need to figure out the // calendar's timezone. list($calendarPath) = URLUtil::splitPath($uri); if (!isset($timeZones[$calendarPath])) { // Checking the calendar-timezone property. $tzProp = '{' . self::NS_CALDAV . '}calendar-timezone'; $tzResult = $this->server->getProperties($calendarPath, [$tzProp]); if (isset($tzResult[$tzProp])) { // This property contains a VCALENDAR with a single // VTIMEZONE. $vtimezoneObj = VObject\Reader::read($tzResult[$tzProp]); $timeZone = $vtimezoneObj->VTIMEZONE->getTimeZone(); } else { // Defaulting to UTC. $timeZone = new DateTimeZone('UTC'); } $timeZones[$calendarPath] = $timeZone; } $vObject->expand($start, $end, $timeZones[$calendarPath]); } if ($needsJson) { $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = json_encode($vObject->jsonSerialize()); } else { $objProps[200]['{' . self::NS_CALDAV . '}calendar-data'] = $vObject->serialize(); } } $propertyList[] = $objProps; } $prefer = $this->server->getHTTPPRefer(); $this->server->httpResponse->setStatus(207); $this->server->httpResponse->setHeader('Content-Type', 'application/xml; charset=utf-8'); $this->server->httpResponse->setHeader('Vary', 'Brief,Prefer'); $this->server->httpResponse->setBody($this->server->generateMultiStatus($propertyList, $prefer['return-minimal'])); }
/** * Retrieve a child DOM element from a DOM element. * If the element is not found and $errorMessage is set, then a RepositoryException is thrown. * If the element is not found and $errorMessage is empty, then false is returned. * * @throws \PHPCR\RepositoryException When the element is not found and an $errorMessage is set * * @param \DOMNode $dom The DOM element which content should be searched * @param string $namespace The namespace of the searched element * @param string $element The name of the searched element * @param string $errorMessage The error message in case the element is not found * @return bool|\DOMNode */ protected function getRequiredDomElementByTagNameNS($dom, $namespace, $element, $errorMessage = '') { $list = $dom->getElementsByTagNameNS($namespace, $element); if (!$list->length) { if ($errorMessage) { throw new RepositoryException($errorMessage); } return false; } return $list->item(0); }
/** * * @param DOMNode $article * @param array $aProperty * @return mixed */ protected function getValue($article, $aProperty) { if (is_array($aProperty) === false) { return ''; } $value = null; $tagName = $aProperty['tagName']; $attribute = array_key_exists('attribute', $aProperty) ? $aProperty['attribute'] : false; $namespace = array_key_exists('namespace', $aProperty) ? $aProperty['namespace'] : false; $hasAttribute = array_key_exists('hasAttribute', $aProperty) ? $aProperty['hasAttribute'] : false; if ($namespace) { $tag = $article->getElementsByTagNameNS($tagName, $namespace); } else { $tag = $article->getElementsByTagName($tagName); } if ($tag->length == 0) { $tagName = strtolower($tagName); if ($namespace) { $tag = $article->getElementsByTagNameNS($tagName, $namespace); } else { $tag = $article->getElementsByTagName($tagName); } } if ($tag->length) { $valueTag = null; if ($hasAttribute) { foreach ($tag as $auxTag) { /* @var $auxTag DOMNode */ if ($auxTag->attributes->length > 0) { $node = $auxTag->attributes->getNamedItem($hasAttribute['name']); if ($node && (!array_key_exists('value', $hasAttribute) || $node->nodeValue == $hasAttribute['value'])) { $valueTag = $auxTag; break; } } } } else { $valueTag = $tag[0]; } if ($valueTag) { if ($attribute) { $value = $valueTag->getAttribute($attribute); } else { $value = $valueTag->nodeValue; } } } return $value; }