2012-06-03 14:19:28 -04:00
< ? php
2012-08-11 04:07:19 -04:00
namespace Sabre\VObject ;
2012-06-03 14:19:28 -04:00
/**
* VObject Property
*
* A property in VObject is usually in the form PARAMNAME : paramValue .
* An example is : SUMMARY : Weekly meeting
*
* Properties can also have parameters :
* SUMMARY ; LANG = en : Weekly meeting .
*
* Parameters can be accessed using the ArrayAccess interface .
*
* @ copyright Copyright ( C ) 2007 - 2012 Rooftop Solutions . All rights reserved .
* @ author Evert Pot ( http :// www . rooftopsolutions . nl / )
* @ license http :// code . google . com / p / sabredav / wiki / License Modified BSD License
*/
2012-08-11 04:07:19 -04:00
class Property extends Element {
2012-06-03 14:19:28 -04:00
/**
* Propertyname
*
* @ var string
*/
public $name ;
/**
* Group name
*
* This may be something like 'HOME' for vcards .
*
* @ var string
*/
public $group ;
/**
* Property parameters
*
* @ var array
*/
public $parameters = array ();
/**
* Property value
*
* @ var string
*/
public $value ;
/**
* If properties are added to this map , they will be automatically mapped
* to their respective classes , if parsed by the reader or constructed with
* the 'create' method .
*
* @ var array
*/
static public $classMap = array (
2012-08-11 04:07:19 -04:00
'COMPLETED' => 'Sabre\\VObject\\Property\\DateTime' ,
'CREATED' => 'Sabre\\VObject\\Property\\DateTime' ,
'DTEND' => 'Sabre\\VObject\\Property\\DateTime' ,
'DTSTAMP' => 'Sabre\\VObject\\Property\\DateTime' ,
'DTSTART' => 'Sabre\\VObject\\Property\\DateTime' ,
'DUE' => 'Sabre\\VObject\\Property\\DateTime' ,
'EXDATE' => 'Sabre\\VObject\\Property\\MultiDateTime' ,
'LAST-MODIFIED' => 'Sabre\\VObject\\Property\\DateTime' ,
'RECURRENCE-ID' => 'Sabre\\VObject\\Property\\DateTime' ,
'TRIGGER' => 'Sabre\\VObject\\Property\\DateTime' ,
2012-06-03 14:19:28 -04:00
);
/**
* Creates the new property by name , but in addition will also see if
* there ' s a class mapped to the property name .
*
2012-08-11 04:07:19 -04:00
* Parameters can be specified with the optional third argument . Parameters
* must be a key -> value map of the parameter name , and value . If the value
* is specified as an array , it is assumed that multiple parameters with
* the same name should be added .
*
2012-06-03 14:19:28 -04:00
* @ param string $name
* @ param string $value
2012-08-11 04:07:19 -04:00
* @ param array $parameters
* @ return Property
2012-06-03 14:19:28 -04:00
*/
2012-08-11 04:07:19 -04:00
static public function create ( $name , $value = null , array $parameters = array ()) {
2012-06-03 14:19:28 -04:00
$name = strtoupper ( $name );
$shortName = $name ;
$group = null ;
if ( strpos ( $shortName , '.' ) !== false ) {
list ( $group , $shortName ) = explode ( '.' , $shortName );
}
if ( isset ( self :: $classMap [ $shortName ])) {
2012-08-11 04:07:19 -04:00
return new self :: $classMap [ $shortName ]( $name , $value , $parameters );
2012-06-03 14:19:28 -04:00
} else {
2012-08-11 04:07:19 -04:00
return new self ( $name , $value , $parameters );
2012-06-03 14:19:28 -04:00
}
}
/**
* Creates a new property object
*
2012-08-11 04:07:19 -04:00
* Parameters can be specified with the optional third argument . Parameters
* must be a key -> value map of the parameter name , and value . If the value
* is specified as an array , it is assumed that multiple parameters with
* the same name should be added .
2012-06-03 14:19:28 -04:00
*
* @ param string $name
* @ param string $value
2012-08-11 04:07:19 -04:00
* @ param array $parameters
2012-06-03 14:19:28 -04:00
*/
2012-08-11 04:07:19 -04:00
public function __construct ( $name , $value = null , array $parameters = array ()) {
2012-06-03 14:19:28 -04:00
$name = strtoupper ( $name );
$group = null ;
if ( strpos ( $name , '.' ) !== false ) {
list ( $group , $name ) = explode ( '.' , $name );
}
$this -> name = $name ;
$this -> group = $group ;
$this -> setValue ( $value );
2012-08-11 04:07:19 -04:00
foreach ( $parameters as $paramName => $paramValues ) {
2012-06-03 14:19:28 -04:00
2012-08-11 04:07:19 -04:00
if ( ! is_array ( $paramValues )) {
$paramValues = array ( $paramValues );
}
2012-06-03 14:19:28 -04:00
2012-08-11 04:07:19 -04:00
foreach ( $paramValues as $paramValue ) {
$this -> add ( $paramName , $paramValue );
}
}
}
2012-06-03 14:19:28 -04:00
/**
* Updates the internal value
*
* @ param string $value
* @ return void
*/
public function setValue ( $value ) {
$this -> value = $value ;
}
/**
* Turns the object back into a serialized blob .
*
* @ return string
*/
public function serialize () {
$str = $this -> name ;
if ( $this -> group ) $str = $this -> group . '.' . $this -> name ;
if ( count ( $this -> parameters )) {
foreach ( $this -> parameters as $param ) {
$str .= ';' . $param -> serialize ();
}
}
$src = array (
'\\' ,
" \n " ,
);
$out = array (
'\\\\' ,
'\n' ,
);
$str .= ':' . str_replace ( $src , $out , $this -> value );
$out = '' ;
while ( strlen ( $str ) > 0 ) {
if ( strlen ( $str ) > 75 ) {
$out .= mb_strcut ( $str , 0 , 75 , 'utf-8' ) . " \r \n " ;
$str = ' ' . mb_strcut ( $str , 75 , strlen ( $str ), 'utf-8' );
} else {
$out .= $str . " \r \n " ;
$str = '' ;
break ;
}
}
return $out ;
}
/**
* Adds a new componenten or element
*
* You can call this method with the following syntaxes :
*
2012-08-11 04:07:19 -04:00
* add ( Parameter $element )
2012-06-03 14:19:28 -04:00
* add ( string $name , $value )
*
* The first version adds an Parameter
* The second adds a property as a string .
*
* @ param mixed $item
* @ param mixed $itemValue
* @ return void
*/
public function add ( $item , $itemValue = null ) {
2012-08-11 04:07:19 -04:00
if ( $item instanceof Parameter ) {
2012-06-03 14:19:28 -04:00
if ( ! is_null ( $itemValue )) {
2012-08-11 04:07:19 -04:00
throw new \InvalidArgumentException ( 'The second argument must not be specified, when passing a VObject' );
2012-06-03 14:19:28 -04:00
}
$item -> parent = $this ;
$this -> parameters [] = $item ;
} elseif ( is_string ( $item )) {
if ( ! is_scalar ( $itemValue ) && ! is_null ( $itemValue )) {
2012-08-11 04:07:19 -04:00
throw new \InvalidArgumentException ( 'The second argument must be scalar' );
2012-06-03 14:19:28 -04:00
}
2012-08-11 04:07:19 -04:00
$parameter = new Parameter ( $item , $itemValue );
2012-06-03 14:19:28 -04:00
$parameter -> parent = $this ;
$this -> parameters [] = $parameter ;
} else {
2012-08-11 04:07:19 -04:00
throw new \InvalidArgumentException ( 'The first argument must either be a Element or a string' );
2012-06-03 14:19:28 -04:00
}
}
/* ArrayAccess interface {{{ */
/**
* Checks if an array element exists
*
* @ param mixed $name
* @ return bool
*/
public function offsetExists ( $name ) {
if ( is_int ( $name )) return parent :: offsetExists ( $name );
$name = strtoupper ( $name );
foreach ( $this -> parameters as $parameter ) {
if ( $parameter -> name == $name ) return true ;
}
return false ;
}
/**
* Returns a parameter , or parameter list .
*
* @ param string $name
2012-08-11 04:07:19 -04:00
* @ return Element
2012-06-03 14:19:28 -04:00
*/
public function offsetGet ( $name ) {
if ( is_int ( $name )) return parent :: offsetGet ( $name );
$name = strtoupper ( $name );
$result = array ();
foreach ( $this -> parameters as $parameter ) {
if ( $parameter -> name == $name )
$result [] = $parameter ;
}
if ( count ( $result ) === 0 ) {
return null ;
} elseif ( count ( $result ) === 1 ) {
return $result [ 0 ];
} else {
2012-08-11 04:07:19 -04:00
$result [ 0 ] -> setIterator ( new ElementList ( $result ));
2012-06-03 14:19:28 -04:00
return $result [ 0 ];
}
}
/**
* Creates a new parameter
*
* @ param string $name
* @ param mixed $value
* @ return void
*/
public function offsetSet ( $name , $value ) {
if ( is_int ( $name )) parent :: offsetSet ( $name , $value );
if ( is_scalar ( $value )) {
if ( ! is_string ( $name ))
2012-08-11 04:07:19 -04:00
throw new \InvalidArgumentException ( 'A parameter name must be specified. This means you cannot use the $array[]="string" to add parameters.' );
2012-06-03 14:19:28 -04:00
$this -> offsetUnset ( $name );
2012-08-11 04:07:19 -04:00
$parameter = new Parameter ( $name , $value );
2012-06-03 14:19:28 -04:00
$parameter -> parent = $this ;
$this -> parameters [] = $parameter ;
2012-08-11 04:07:19 -04:00
} elseif ( $value instanceof Parameter ) {
2012-06-03 14:19:28 -04:00
if ( ! is_null ( $name ))
2012-08-11 04:07:19 -04:00
throw new \InvalidArgumentException ( 'Don\'t specify a parameter name if you\'re passing a \\Sabre\\VObject\\Parameter. Add using $array[]=$parameterObject.' );
2012-06-03 14:19:28 -04:00
$value -> parent = $this ;
$this -> parameters [] = $value ;
} else {
2012-08-11 04:07:19 -04:00
throw new \InvalidArgumentException ( 'You can only add parameters to the property object' );
2012-06-03 14:19:28 -04:00
}
}
/**
* Removes one or more parameters with the specified name
*
* @ param string $name
* @ return void
*/
public function offsetUnset ( $name ) {
if ( is_int ( $name )) parent :: offsetUnset ( $name );
$name = strtoupper ( $name );
foreach ( $this -> parameters as $key => $parameter ) {
if ( $parameter -> name == $name ) {
$parameter -> parent = null ;
unset ( $this -> parameters [ $key ]);
}
}
}
/* }}} */
/**
* Called when this object is being cast to a string
*
* @ return string
*/
public function __toString () {
return ( string ) $this -> value ;
}
/**
* This method is automatically called when the object is cloned .
* Specifically , this will ensure all child elements are also cloned .
*
* @ return void
*/
public function __clone () {
foreach ( $this -> parameters as $key => $child ) {
$this -> parameters [ $key ] = clone $child ;
$this -> parameters [ $key ] -> parent = $this ;
}
}
}