Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117877216
kolab_format.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
11 KB
Referenced Files
None
Subscribers
None
kolab_format.php
View Options
<?php
/**
* Kolab format model class
*
* Abstract base class for different Kolab groupware objects read from/written
* to the Kolab 2 format using Horde_Kolab_Format classes.
*
* @version @package_version@
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
abstract
class
kolab_format
{
public
static
$timezone
;
public
/*abstract*/
$CTYPE
;
protected
/*abstract*/
$xmltype
;
protected
/*abstract*/
$subtype
;
protected
$handler
;
protected
$data
;
protected
$xmldata
;
protected
$kolab_object
;
protected
$loaded
=
false
;
protected
$version
=
2.0
;
const
KTYPE_PREFIX
=
'application/x-vnd.kolab.'
;
const
PRODUCT_ID
=
'Roundcube-libkolab-horde-0.9'
;
/**
* Factory method to instantiate a kolab_format object of the given type and version
*
* @param string Object type to instantiate
* @param float Format version
* @param string Cached xml data to initialize with
* @return object kolab_format
*/
public
static
function
factory
(
$type
,
$version
=
2.0
,
$xmldata
=
null
)
{
if
(!
isset
(
self
::
$timezone
))
self
::
$timezone
=
new
DateTimeZone
(
'UTC'
);
if
(!
self
::
supports
(
$version
))
return
PEAR
::
raiseError
(
"No support for Kolab format version "
.
$version
);
list
(
$xmltype
,
$subtype
)
=
explode
(
'.'
,
$type
);
$type
=
preg_replace
(
'/configuration
\.
[a-z.]+$/'
,
'configuration'
,
$type
);
$suffix
=
preg_replace
(
'/[^a-z]+/'
,
''
,
$xmltype
);
$classname
=
'kolab_format_'
.
$suffix
;
if
(
class_exists
(
$classname
))
return
new
$classname
(
$xmldata
,
$subtype
);
return
PEAR
::
raiseError
(
"Failed to load Kolab Format wrapper for type "
.
$type
);
}
/**
* Determine support for the given format version
*
* @param float Format version to check
* @return boolean True if supported, False otherwise
*/
public
static
function
supports
(
$version
)
{
if
(
$version
==
2.0
)
return
class_exists
(
'Horde_Kolab_Format_Xml'
);
return
false
;
}
/**
* Convert the given date/time value into a structure for Horde_Kolab_Format_Xml_Type_DateTime
*
* @param mixed Date/Time value either as unix timestamp, date string or PHP DateTime object
* @param DateTimeZone The timezone the date/time is in. Use global default if Null, local time if False
* @param boolean True of the given date has no time component
* @return array Hash array with date
*/
public
static
function
horde_datetime
(
$datetime
,
$tz
=
null
,
$dateonly
=
false
)
{
// use timezone information from datetime of global setting
if
(!
$tz
&&
$tz
!==
false
)
{
$tz
=
self
::
$timezone
;
}
$result
=
null
;
// got a unix timestamp (in UTC)
if
(
is_numeric
(
$datetime
))
{
$datetime
=
new
DateTime
(
'@'
.
$datetime
,
new
DateTimeZone
(
'UTC'
));
if
(
$tz
)
$datetime
->
setTimezone
(
$tz
);
}
else
if
(
is_string
(
$datetime
)
&&
strlen
(
$datetime
))
{
try
{
$datetime
=
new
DateTime
(
$datetime
,
$tz
?:
null
);
}
catch
(
Exception
$e
)
{
}
}
if
(
$datetime
instanceof
DateTime
)
{
// always save dates in UTC for compatibility reasons
if
(!
$dateonly
&&
!
$datetime
->
_dateonly
&&
$tz
!==
false
)
$datetime
->
setTimezone
(
new
DateTimeZone
(
'UTC'
));
$result
=
array
(
'date'
=>
$datetime
,
'date-only'
=>
$dateonly
||
$datetime
->
_dateonly
);
}
return
$result
;
}
/**
* Convert the given Horde_Kolab_Format_Xml_Type_DateTime structure into a simple PHP DateTime object
*
* @param arrry Hash array with datetime properties
* @return object DateTime PHP datetime instance
*/
public
static
function
php_datetime
(
$data
)
{
if
(
is_array
(
$data
))
{
$d
=
$data
[
'date'
];
if
(
is_a
(
$d
,
'DateTime'
))
{
if
(
$data
[
'date-only'
])
$d
->
_dateonly
=
$data
[
'date-only'
];
return
$d
;
}
}
else
if
(
is_object
(
$data
)
&&
is_a
(
$data
,
'DateTime'
))
return
$data
;
return
null
;
}
/**
* Parse the X-Kolab-Type header from MIME messages and return the object type in short form
*
* @param string X-Kolab-Type header value
* @return string Kolab object type (contact,event,task,note,etc.)
*/
public
static
function
mime2object_type
(
$x_kolab_type
)
{
return
preg_replace
(
'/dictionary.[a-z.]+$/'
,
'dictionary'
,
substr
(
$x_kolab_type
,
strlen
(
self
::
KTYPE_PREFIX
)));
}
/**
* Convert alarm time into internal ical-based format
*
* @param int Alarm value as saved in Kolab 2 format
* @return string iCal-style alarm value for internal use
*/
public
static
function
from_kolab2_alarm
(
$alarm_value
)
{
if
(!
$alarm_value
)
return
null
;
$alarm_unit
=
'M'
;
if
(
$alarm_value
%
1440
==
0
)
{
$alarm_value
/=
1440
;
$alarm_unit
=
'D'
;
}
else
if
(
$alarm_value
%
60
==
0
)
{
$alarm_value
/=
60
;
$alarm_unit
=
'H'
;
}
$alarm_value
*=
-
1
;
return
$alarm_value
.
$alarm_unit
;
}
/**
* Utility function to convert from Roundcube's internal alarms format
* to an alarm offset in minutes used by the Kolab 2 format.
*
* @param string iCal-style alarm string
* @return int Alarm offset in minutes
*/
public
static
function
to_kolab2_alarm
(
$alarms
)
{
$ret
=
null
;
if
(!
$alarms
)
return
$ret
;
$alarmbase
=
explode
(
":"
,
$alarms
);
$avalue
=
intval
(
preg_replace
(
'/[^0-9]/'
,
''
,
$alarmbase
[
0
]));
if
(
preg_match
(
"/^@/"
,
$alarmbase
[
0
]))
{
$ret
=
null
;
}
else
if
(
preg_match
(
"/H/"
,
$alarmbase
[
0
]))
{
$ret
=
$avalue
*
60
;
}
else
if
(
preg_match
(
"/D/"
,
$alarmbase
[
0
]))
{
$ret
=
$avalue
*
24
*
60
;
}
else
{
$ret
=
$avalue
;
}
return
$ret
;
}
/**
* Default constructor of all kolab_format_* objects
*/
public
function
__construct
(
$xmldata
=
null
,
$subtype
=
null
)
{
$this
->
subtype
=
$subtype
;
try
{
$factory
=
new
Horde_Kolab_Format_Factory
();
$handler
=
$factory
->
create
(
'Xml'
,
$this
->
xmltype
,
array
(
'subtype'
=>
$this
->
subtype
));
if
(
is_object
(
$handler
)
&&
!
is_a
(
$handler
,
'PEAR_Error'
))
{
$this
->
handler
=
$handler
;
$this
->
xmldata
=
$xmldata
;
}
}
catch
(
Exception
$e
)
{
rcube
::
raise_error
(
$e
,
true
);
}
}
/**
* Check for format errors after calling kolabformat::write*()
*
* @return boolean True if there were errors, False if OK
*/
protected
function
format_errors
(
$p
)
{
$ret
=
false
;
if
(
is_object
(
$p
)
&&
is_a
(
$p
,
'PEAR_Error'
))
{
rcube
::
raise_error
(
array
(
'code'
=>
660
,
'type'
=>
'php'
,
'file'
=>
__FILE__
,
'line'
=>
__LINE__
,
'message'
=>
"Horde_Kolab_Format error: "
.
$p
->
getMessage
(),
),
true
);
$ret
=
true
;
}
return
$ret
;
}
/**
* Generate a unique identifier for a Kolab object
*/
protected
function
generate_uid
()
{
$rc
=
rcube
::
get_instance
();
return
md5
(
time
()
.
uniqid
(
rand
()))
.
'-'
.
substr
(
md5
(
$rc
->
user
?
$rc
->
user
->
get_username
()
:
rand
()),
0
,
16
);
}
/**
* Initialize libkolabxml object with cached xml data
*/
protected
function
init
()
{
if
(!
$this
->
loaded
)
{
if
(
$this
->
xmldata
)
{
$this
->
load
(
$this
->
xmldata
);
$this
->
xmldata
=
null
;
}
$this
->
loaded
=
true
;
}
}
/**
* Direct getter for object properties
*/
public
function
__get
(
$var
)
{
return
$this
->
data
[
$var
];
}
/**
* Load Kolab object data from the given XML block
*
* @param string XML data
* @return boolean True on success, False on failure
*/
public
function
load
(
$xml
)
{
$this
->
loaded
=
false
;
// XML-to-array
try
{
$object
=
$this
->
handler
->
load
(
$xml
,
array
(
'relaxed'
=>
true
));
$this
->
kolab_object
=
$object
;
$this
->
fromkolab2
(
$object
);
$this
->
loaded
=
true
;
}
catch
(
Exception
$e
)
{
rcube
::
raise_error
(
$e
,
true
);
console
(
$xml
);
}
}
/**
* Write object data to XML format
*
* @param float Format version to write
* @return string XML data
*/
public
function
write
(
$version
=
null
)
{
$this
->
init
();
if
(
$version
&&
!
self
::
supports
(
$version
))
return
false
;
// generate UID if not set
if
(!
$this
->
kolab_object
[
'uid'
])
{
$this
->
kolab_object
[
'uid'
]
=
$this
->
generate_uid
();
}
try
{
$xml
=
$this
->
handler
->
save
(
$this
->
kolab_object
);
if
(
strlen
(
$xml
))
{
$this
->
xmldata
=
$xml
;
$this
->
data
[
'uid'
]
=
$this
->
kolab_object
[
'uid'
];
}
}
catch
(
Exception
$e
)
{
rcube
::
raise_error
(
$e
,
true
);
$this
->
xmldata
=
null
;
}
return
$this
->
xmldata
;
}
/**
* Set properties to the kolabformat object
*
* @param array Object data as hash array
*/
abstract
public
function
set
(&
$object
);
/**
*
*/
abstract
public
function
is_valid
();
/**
* Getter for the parsed object data
*
* @return array Kolab object data as hash array
*/
public
function
to_array
()
{
// load from XML if not done yet
if
(
empty
(
$this
->
data
))
$this
->
init
();
return
$this
->
data
;
}
/**
* Load object data from Kolab2 format
*
* @param array Hash array with object properties (produced by Horde Kolab_Format classes)
*/
abstract
public
function
fromkolab2
(
$object
);
/**
* Callback for kolab_storage_cache to get object specific tags to cache
*
* @return array List of tags to save in cache
*/
public
function
get_tags
()
{
return
array
();
}
/**
* Callback for kolab_storage_cache to get words to index for fulltext search
*
* @return array List of words to save in cache
*/
public
function
get_words
()
{
return
array
();
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sun, Apr 5, 9:26 PM (3 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18831231
Default Alt Text
kolab_format.php (11 KB)
Attached To
Mode
rRPK roundcubemail-plugins-kolab
Attached
Detach File
Event Timeline