blob: 613b50041f7ee7587f71ae363011bb6f4c1648a8 [file] [log] [blame]
<?php
/**
* File containing the ezcWebdavBasicPropertyStorage class.
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
* @package Webdav
* @version //autogen//
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
/**
* Container class for ezcWebdavProperty objects.
*
* An instance of this class is used to manage WebDAV properties, namely
* instances of {@link ezcWebdavProperty}. Properties are structured by their
* name and the namespace they reside in.
*
* @package Webdav
* @version //autogen//
*/
class ezcWebdavBasicPropertyStorage implements ezcWebdavPropertyStorage
{
/**
* Stores the WebDAV properties.
*
* The structure of this array is:
* <code>
* array(
* 'DAV:' => array(
* '<live property name>' => ezcWebdavLiveProperty,
* // ...
* ),
* '<another namespace URI>'array(
* '<dead property name>' => ezcWebdavDeadProperty,
* // ...
* ),
* // ...
* )
* </code>
*
* @var array
*/
protected $properties = array();
/**
* Stores a list of the assigned properties in the order they were
* assigned, to make this order accessible for the Iterator.
*
* @var array
*/
protected $propertyOrder = array();
/**
* Current position of the iterator in the ordered property list.
*
* @var int
*/
protected $propertyOrderPosition = 0;
/**
* Next ID for a element in the ordered property list, to generate valid
* IDs even when some contents has been removed.
*
* @var int
*/
protected $propertyOrderNextId = 0;
/**
* Attaches a property to the storage.
*
* Adds the given $property to the storage. The property can later be
* accessed by its name in combination with the namespace through the
* {@link get()} method. Live properties (and only these) reside in the
* namespace DAV:, which is the default for all accessor methods.
*
* If a property with the same namespace and name is already contained in
* the storage, it will be overwritten.
*
* @param ezcWebdavProperty $property
* @return void
*/
public function attach( ezcWebdavProperty $property )
{
$namespace = $property->namespace;
$name = $property->name;
// Update list of ordered properties
if ( !isset( $this->properties[$namespace] ) ||
!isset( $this->properties[$namespace][$name] ) )
{
$this->propertyOrder[$this->propertyOrderNextId++] = array( $namespace, $name );
}
// Add property
$this->properties[$namespace][$name] = $property;
}
/**
* Detaches a property from the storage.
*
* Removes the property with the given $name and $namespace from the
* storage. If the property does not exist in the storage, the call is
* silently ignored. If no $namespace is given, the default namespace for
* live properties ('DAV:') is used.
*
* @param string $name
* @param string $namespace
* @return void
*/
public function detach( $name, $namespace = 'DAV:' )
{
if ( isset( $this->properties[$namespace] ) &&
isset( $this->properties[$namespace][$name] ) )
{
unset( $this->properties[$namespace][$name] );
}
}
/**
* Returns if the given property exists in the storage.
*
* Returns if the property with the given $name and $namespace is contained
* in the storage. If the $namespace parameter is omited, the default live
* property namespace ('DAV:') is used.
*
* @param string $name
* @param string $namespace
* @return bool
*/
public function contains( $name, $namespace = 'DAV:' )
{
return isset( $this->properties[$namespace][$name] );
}
/**
* Returns a property from the storage.
*
* Returns the property with the given $name and $namespace. If the
* $namespace parameter is omitted, the default live property namespace
* ('DAV:') namespace is used. If the desired property is not contained in
* the storage, null is returned.
*
* @param string $name
* @param string $namespace
* @return ezcWebdavProperty|null
*/
public function get( $name, $namespace = 'DAV:' )
{
if ( isset( $this->properties[$namespace][$name] ) )
{
return $this->properties[$namespace][$name];
}
return null;
}
/**
* Returns all properties of a given namespace.
*
* The returned array is indexed by the property names. Live properties can
* be accessed by simply ommiting the $namespace parameter, since then the
* default namespace for live properties ('DAV:') is used.
*
* @param string $namespace
* @return array(string=>ezcWebdavProperty)
*/
public function getProperties( $namespace = 'DAV:' )
{
if ( !isset( $this->properties[$namespace] ) )
{
return array();
}
return $this->properties[$namespace];
}
/**
* Returns all properties contained in the storage.
*
* Returns the complete array stored in {@link $properties}.
*
* @return array(string=>array(string=>ezcWebdavProperty))
*/
public function getAllProperties()
{
return $this->properties;
}
/**
* Diff two property storages.
*
* Returns a property storage, which does only contain properties that are
* not present in the $properties parameter.
*
* @param ezcWebdavPropertyStorage $properties
* @return ezcWebdavBasicPropertyStorage
*/
public function diff( ezcWebdavPropertyStorage $properties )
{
$foreign = $properties->getAllProperties();
$diffedProperties = new ezcWebdavBasicPropertyStorage();
foreach ( $this->properties as $namespace => $properties )
{
foreach ( $properties as $name => $property )
{
if ( !isset( $foreign[$namespace][$name] ) )
{
// Only add properties to new property storage, which could
// not be found in the foreign property storage.
$diffedProperties->attach( $property );
}
}
}
return $diffedProperties;
}
/**
* Intersects between two property storages.
*
* Calculate and return an instance of {@link
* ezcWebdavBasicPropertyStorage} which contains the intersection of two
* property storages. This means a new property storage will be return
* which contains all values, which are present in the current and the
* given $properties property storage.
*
* @param ezcWebdavPropertyStorage $properties
* @return ezcWebdavBasicPropertyStorage
*/
public function intersect( ezcWebdavPropertyStorage $properties )
{
$foreign = $properties->getAllProperties();
$intersection = new ezcWebdavBasicPropertyStorage();
foreach ( $this->properties as $namespace => $properties )
{
foreach ( $properties as $name => $property )
{
if ( isset( $foreign[$namespace][$name] ) )
{
// Only add properties to new property storage, which could
// be found in both property storages.
$intersection->attach( $property );
}
}
}
return $intersection;
}
/*
* Methods required for Countable
*/
/**
* Return property count.
*
* Implementation required by interface Countable. Count the numbers of
* items contained by the instance. Will return the overall item count
* ignoring different namespaces.
*
* @return int
*/
public function count()
{
$count = 0;
foreach ( $this->properties as $properties )
{
$count += count( $properties );
}
return $count;
}
/**
* Methods required for Iterator
*/
/**
* Implements current() for Iterator.
*
* Returns the currently selected element during iteration with foreach.
*
* @return ezcWebdavProperty
*/
public function current()
{
list( $namespace, $name ) = $this->propertyOrder[$this->propertyOrderPosition];
// Skip detached properties
while ( !isset( $this->properties[$namespace][$name] ) )
{
if ( !isset( $this->propertyOrder[++$this->propertyOrderPosition] ) )
{
// We reached the end.
return false;
}
list( $namespace, $name ) = $this->propertyOrder[$this->propertyOrderPosition];
}
return $this->properties[$namespace][$name];
}
/**
* Implements key() for Iterator
*
* Returns the key of the currently selected element during iteration with
* foreach.
*
* @return int
*/
public function key()
{
return $this->propertyOrderPosition;
}
/**
* Implements next() for Iterator
*
* Advances the internal pointer to the next element during iteration with
* foreach.
*
* @return mixed
*/
public function next()
{
++$this->propertyOrderPosition;
}
/**
* Implements rewind() for Iterator
*
* Resets the internal pointer to the first element before iteration with
* foreach.
*
* @return void
*/
public function rewind()
{
$this->propertyOrderPosition = 0;
}
/**
* Implements valid() for Iterator
*
* Returns if the internal pointer still points to a valid element when
* iteration with foreach. If this method returns false, iteration ends.
*
* @return boolean
*/
public function valid()
{
do
{
if ( !isset( $this->propertyOrder[$this->propertyOrderPosition] ) )
{
// We reached the end.
return false;
}
list( $namespace, $name ) = $this->propertyOrder[$this->propertyOrderPosition];
if ( isset( $this->properties[$namespace][$name] ) )
{
// Found next valid property
return true;
}
++$this->propertyOrderPosition;
}
while ( !isset( $this->properties[$namespace][$name] ) );
return true;
}
/**
* Clones the property storage deeply.
*
* @return void
*/
public function __clone()
{
foreach ( $this->properties as $namespace => $props )
{
foreach ( $props as $name => $prop )
{
$this->properties[$namespace][$name] = clone $prop;
}
}
}
}
?>