/** * Returns a list of properties for a given path * * The path that should be supplied should have the baseUrl stripped out * The list of properties should be supplied in Clark notation. If the list is empty * 'allprops' is assumed. * * If a depth of 1 is requested child elements will also be returned. * * @param string $path * @param array $propertyNames * @param int $depth * @return array */ public function getPropertiesForPath($path, $propertyNames = array(), $depth = 0) { if ($depth != 0) { $depth = 1; } $returnPropertyList = array(); $parentNode = $this->tree->getNodeForPath($path); $nodes = array($path => $parentNode); if ($depth == 1 && $parentNode instanceof Sabre_DAV_ICollection) { foreach ($this->tree->getChildren($path) as $childNode) { $nodes[$path . '/' . $childNode->getName()] = $childNode; } } // If the propertyNames array is empty, it means all properties are requested. // We shouldn't actually return everything we know though, and only return a // sensible list. $allProperties = count($propertyNames) == 0; foreach ($nodes as $myPath => $node) { $currentPropertyNames = $propertyNames; $newProperties = array('200' => array(), '404' => array()); if ($allProperties) { // Default list of propertyNames, when all properties were requested. $currentPropertyNames = array('{DAV:}getlastmodified', '{DAV:}getcontentlength', '{DAV:}resourcetype', '{DAV:}quota-used-bytes', '{DAV:}quota-available-bytes', '{DAV:}getetag', '{DAV:}getcontenttype'); } // If the resourceType was not part of the list, we manually add it // and mark it for removal. We need to know the resourcetype in order // to make certain decisions about the entry. // WebDAV dictates we should add a / and the end of href's for collections $removeRT = false; if (!in_array('{DAV:}resourcetype', $currentPropertyNames)) { $currentPropertyNames[] = '{DAV:}resourcetype'; $removeRT = true; } $result = $this->broadcastEvent('beforeGetProperties', array($myPath, $node, &$currentPropertyNames, &$newProperties)); // If this method explicitly returned false, we must ignore this // node as it is inaccessible. if ($result === false) { continue; } if (count($currentPropertyNames) > 0) { if ($node instanceof Sabre_DAV_IProperties) { $newProperties['200'] = $newProperties[200] + $node->getProperties($currentPropertyNames); } } foreach ($currentPropertyNames as $prop) { if (isset($newProperties[200][$prop])) { continue; } switch ($prop) { case '{DAV:}getlastmodified': if ($node->getLastModified()) { $newProperties[200][$prop] = new Sabre_DAV_Property_GetLastModified($node->getLastModified()); } break; case '{DAV:}getcontentlength': if ($node instanceof Sabre_DAV_IFile) { $size = $node->getSize(); if (!is_null($size)) { $newProperties[200][$prop] = (int) $node->getSize(); } } break; case '{DAV:}quota-used-bytes': if ($node instanceof Sabre_DAV_IQuota) { $quotaInfo = $node->getQuotaInfo(); $newProperties[200][$prop] = $quotaInfo[0]; } break; case '{DAV:}quota-available-bytes': if ($node instanceof Sabre_DAV_IQuota) { $quotaInfo = $node->getQuotaInfo(); $newProperties[200][$prop] = $quotaInfo[1]; } break; case '{DAV:}getetag': if ($node instanceof Sabre_DAV_IFile && ($etag = $node->getETag())) { $newProperties[200][$prop] = $etag; } break; case '{DAV:}getcontenttype': if ($node instanceof Sabre_DAV_IFile && ($ct = $node->getContentType())) { $newProperties[200][$prop] = $ct; } break; case '{DAV:}supported-report-set': $reports = array(); foreach ($this->plugins as $plugin) { $reports = array_merge($reports, $plugin->getSupportedReportSet($myPath)); } $newProperties[200][$prop] = new Sabre_DAV_Property_SupportedReportSet($reports); break; case '{DAV:}resourcetype': $newProperties[200]['{DAV:}resourcetype'] = new Sabre_DAV_Property_ResourceType(); foreach ($this->resourceTypeMapping as $className => $resourceType) { if ($node instanceof $className) { $newProperties[200]['{DAV:}resourcetype']->add($resourceType); } } break; } // If we were unable to find the property, we will list it as 404. if (!$allProperties && !isset($newProperties[200][$prop])) { $newProperties[404][$prop] = null; } } $this->broadcastEvent('afterGetProperties', array(trim($myPath, '/'), &$newProperties)); $newProperties['href'] = trim($myPath, '/'); // Its is a WebDAV recommendation to add a trailing slash to collectionnames. // Apple's iCal also requires a trailing slash for principals (rfc 3744). // Therefore we add a trailing / for any non-file. This might need adjustments // if we find there are other edge cases. if ($myPath != '' && isset($newProperties[200]['{DAV:}resourcetype']) && count($newProperties[200]['{DAV:}resourcetype']->getValue()) > 0) { $newProperties['href'] .= '/'; } // If the resourcetype property was manually added to the requested property list, // we will remove it again. if ($removeRT) { unset($newProperties[200]['{DAV:}resourcetype']); } $returnPropertyList[] = $newProperties; } return $returnPropertyList; }