示例#1
0
    /**
     * Small helper to support PROPFIND with DEPTH_INFINITY.
     */
    private function addPathNodesRecursively(&$propFindRequests, PropFind $propFind) {

        $newDepth = $propFind->getDepth();
        $path = $propFind->getPath();

        if ($newDepth !== self::DEPTH_INFINITY) {
            $newDepth--;
        }

        foreach ($this->tree->getChildren($path) as $childNode) {
            $subPropFind = clone $propFind;
            $subPropFind->setDepth($newDepth);
            $subPath = $path ? $path . '/' . $childNode->getName() : $childNode->getName();
            $subPropFind->setPath($subPath);

            $propFindRequests[] = [
                $subPropFind,
                $childNode
            ];

            if (($newDepth === self::DEPTH_INFINITY || $newDepth >= 1) && $childNode instanceof ICollection) {
                $this->addPathNodesRecursively($propFindRequests, $subPropFind);
            }

        }
    }
示例#2
0
 /**
  * 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;
     }
     $path = rtrim($path, '/');
     // This event allows people to intercept these requests early on in the
     // process.
     //
     // We're not doing anything with the result, but this can be helpful to
     // pre-fetch certain expensive live properties.
     $this->broadCastEvent('beforeGetPropertiesForPath', array($path, $propertyNames, $depth));
     $returnPropertyList = array();
     $parentNode = $this->tree->getNodeForPath($path);
     $nodes = array($path => $parentNode);
     if ($depth == 1 && $parentNode instanceof 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 IProperties) {
                 $nodeProperties = $node->getProperties($currentPropertyNames);
                 // The getProperties method may give us too much,
                 // properties, in case the implementor was lazy.
                 //
                 // So as we loop through this list, we will only take the
                 // properties that were actually requested and discard the
                 // rest.
                 foreach ($currentPropertyNames as $k => $currentPropertyName) {
                     if (isset($nodeProperties[$currentPropertyName])) {
                         unset($currentPropertyNames[$k]);
                         $newProperties[200][$currentPropertyName] = $nodeProperties[$currentPropertyName];
                     }
                 }
             }
         }
         foreach ($currentPropertyNames as $prop) {
             if (isset($newProperties[200][$prop])) {
                 continue;
             }
             switch ($prop) {
                 case '{DAV:}getlastmodified':
                     if ($node->getLastModified()) {
                         $newProperties[200][$prop] = new Property\GetLastModified($node->getLastModified());
                     }
                     break;
                 case '{DAV:}getcontentlength':
                     if ($node instanceof IFile) {
                         $size = $node->getSize();
                         if (!is_null($size)) {
                             $newProperties[200][$prop] = (int) $node->getSize();
                         }
                     }
                     break;
                 case '{DAV:}quota-used-bytes':
                     if ($node instanceof IQuota) {
                         $quotaInfo = $node->getQuotaInfo();
                         $newProperties[200][$prop] = $quotaInfo[0];
                     }
                     break;
                 case '{DAV:}quota-available-bytes':
                     if ($node instanceof IQuota) {
                         $quotaInfo = $node->getQuotaInfo();
                         $newProperties[200][$prop] = $quotaInfo[1];
                     }
                     break;
                 case '{DAV:}getetag':
                     if ($node instanceof IFile && ($etag = $node->getETag())) {
                         $newProperties[200][$prop] = $etag;
                     }
                     break;
                 case '{DAV:}getcontenttype':
                     if ($node instanceof 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 Property\SupportedReportSet($reports);
                     break;
                 case '{DAV:}resourcetype':
                     $newProperties[200]['{DAV:}resourcetype'] = new 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, $node));
         $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), though this is non-standard.
         if ($myPath != '' && isset($newProperties[200]['{DAV:}resourcetype'])) {
             $rt = $newProperties[200]['{DAV:}resourcetype'];
             if ($rt->is('{DAV:}collection') || $rt->is('{DAV:}principal')) {
                 $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;
 }