mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-15 20:44:28 +01:00
initial import of egwical module
contributed by Jan v. Lieshout
This commit is contained in:
parent
84c8db4e8b
commit
fc41cacfd9
95
egwical/doc/EgwIcal-BUGS-and-TODOS.txt
Normal file
95
egwical/doc/EgwIcal-BUGS-and-TODOS.txt
Normal file
@ -0,0 +1,95 @@
|
||||
/*! \page pageegwicalbugandtodo BUGS and TODOS
|
||||
|
||||
<PRE>
|
||||
Know BUGS and things todo
|
||||
---------------------------
|
||||
TODO means: should be done/would be nice in a newer release
|
||||
BUG means: known problem needs to be fixed
|
||||
FAIl means: known failure to provide (not easily to be done/fixed
|
||||
|
||||
(note: this list is probably not quite up todate)
|
||||
|
||||
|
||||
release: VERSION 0.9.0 NEED TO UPDATE THIS!!
|
||||
|
||||
new in V0.7.78 versus v0.7.70:
|
||||
|
||||
bovevents:
|
||||
|
||||
+ whole day events import/export seems to work nice
|
||||
+ continue on erroneous overwrites (errors only visible in errorlog)
|
||||
+ no error messages for forbidden overwrite events of non owned events
|
||||
+ errormessages (when activated) only shows problematic events
|
||||
++ basic (multiple) VALARM import and export, working! (without action select)
|
||||
+ allow for vevents with either DTEND or DURATION
|
||||
+ provided (horde iCalendar) patch to prevent segfaults on some bad iCal inputs
|
||||
|
||||
1) EgwIcal package general (V0.9)
|
||||
----------------
|
||||
|
||||
|
||||
[ ]1.2 TODO get it nicely into egw cvs
|
||||
[+/-]1.7 TODO/WISH allow for import of ATTENDEEs not in Egw yet (create new addressbook entry?)
|
||||
[+](ad hoc solution: add CN and mailto to description)
|
||||
[+/-]1.4 TODO check and generate source code documentation(phpdoc or doxygen)
|
||||
|
||||
[ ]1.5 TODO test these routines in use for syncml import/export
|
||||
|
||||
1.6 TODO/WISH: nothing done yet for vfreebusy, vjournal, notes, components
|
||||
only vevents and vtodos are supported.
|
||||
|
||||
|
||||
3) egwical.egwical (V0.9.01)
|
||||
--------------------
|
||||
|
||||
[+?]3.1 TODO check/implement correct timezone handling (seems ok)
|
||||
[ ]3.9 TEST with syncml
|
||||
[ ]3.2 TODO/WISH handle location (GEO), link(?), url, delegation, ()CONTACT?
|
||||
[ ]3.3 TODO write more documentation (continue mainpage)
|
||||
[ ]3.4 TODO add accumulting buffer system to egwical
|
||||
|
||||
4) egwical.bocalupdate_vevents (V0.9.02)
|
||||
------------------------------
|
||||
|
||||
[+?]4.1 TODO check/implement correct timezone handling (related 3.1)
|
||||
[ ]4.2a TODO/WISH handle URL, GEO etc. fields. (needs extra fields handling in bocalupdate!)
|
||||
[ ]4.2b FAIL rrule-COUNT import not implemented in egw?
|
||||
[+]4.2 BUG!!!! rrule-BYDAY import goes wrong. FIXED (v0.7.76)
|
||||
[+]4.3 TODO check and improve ORGANIZER,ATTENDEE<-> participants mapping
|
||||
ATTENDEE s import and export (appears to work oke >= V0.7.71)
|
||||
[+]4.4 TODO handle import and export of ALARMS
|
||||
[ ]4.7 TODO (ad hoc) add non egw known attendees to description on import
|
||||
[ ]4.8 TODO move compatibility code to compat classes.
|
||||
|
||||
|
||||
4.9 see 3.2
|
||||
|
||||
|
||||
5) egwical.boinfolog_vtodos (V0.9.02)
|
||||
----------------------------
|
||||
5.1 TODO check/implement correct timezone handling (related 3.1)
|
||||
5.3 FAIL import/export more than 1 category per task (egw doesnot allow)
|
||||
5.3 TODO check and improve ORGANIZER,ATTENDEE<-> info_responsible etc mapping
|
||||
5.4 TODO handle import and export of ALARMS
|
||||
5.5 TODO rewrite code into supportedFields structure (for next version)
|
||||
[ ]5.9 TODO rewrite into skeleton structure analog to egwical.bocalupdate_vevents
|
||||
|
||||
|
||||
|
||||
10.) in used routines from others:
|
||||
|
||||
10.1 BUG Horde_iCalendar(1.2rc6): EXDATE bug
|
||||
-[+]fixed by patch 'exdate ....'
|
||||
10.2 BUG Horde_iCalendar(1.2rc6): standard.php Warning
|
||||
-[+]fixed by patch '...??..'
|
||||
|
||||
10.3 BUG infolog(1.2rc6): datetime is 1 hour wrong for untimed due field in tasks
|
||||
|
||||
11) detected errors/flaws in other programs
|
||||
|
||||
11.1 Korganizer 3.5: recurrence endondate display is interpreted different from egw and
|
||||
mozilla (and probable also rfc 2445)
|
||||
|
||||
|
||||
</PRE>
|
||||
*/
|
183
egwical/doc/EgwIcal-Timezone-handling.txt
Normal file
183
egwical/doc/EgwIcal-Timezone-handling.txt
Normal file
@ -0,0 +1,183 @@
|
||||
/*! \page pageegwicaltzh EgwIcal Timezone Handling
|
||||
|
||||
Short description on the timezone handling in EgwIcal
|
||||
|
||||
@date 20060216
|
||||
@version 0.9.04
|
||||
@author JVL
|
||||
@note Document needs further editing and annotations!!
|
||||
|
||||
|
||||
|
||||
In EgwIcal the timed data of Egroupware like events and tasks get
|
||||
converted to elements for an iCalendar. In the Egroupware server we
|
||||
are dealing with socalled "egw server" time, in applications that a
|
||||
user of egw runs, the user can set a "locale" and thereby defining a
|
||||
"local timezone". And finally when events and task get exported to an
|
||||
iCalendar that is sent to a client or uploaded from it, they may also
|
||||
have their timesettings defined according to some "timezone".
|
||||
|
||||
How is this all handled in EgwIcal?
|
||||
|
||||
|
||||
|
||||
@section secegwicalgentzh EgwIcal general Timezone handling
|
||||
|
||||
In general EgwIcal distinguishes between two different types of time
|
||||
descriptions for an event. An event can either be a:
|
||||
<ul>
|
||||
<li>
|
||||
DATETIME (DT) (described) event.
|
||||
|
||||
In this case the occurence of the event is described as taking place
|
||||
on a certain day and within that day on a certain time. E.g. <code>
|
||||
mon 12 june 2006 at 12:33 GMT+001 </code> Examples are: <i>the
|
||||
opening of the Olympic games</i>.
|
||||
|
||||
DT events are thus absolute (in global world time) anchored in time:
|
||||
everyone watching live TV, anywhere in the world can see it happen
|
||||
at that same moment described by DT.
|
||||
|
||||
Result is that a DT described event will occur at different hours or
|
||||
even days in different timezones. (Some people have to watch the
|
||||
Olympic game openings at night..)
|
||||
|
||||
|
||||
<li>DATE (D) (described) events
|
||||
|
||||
These events donot happen at an absolute global time but are only
|
||||
well defined relative to a timezone.
|
||||
A good example is "your birthday" or "new years day".
|
||||
|
||||
In principle this could be either <i>whole day</i> events (like
|
||||
birthdays) or events timed within days (like the "easter sunday
|
||||
service at 12:00").
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
For handling DT events it can be profitable to use a globally unified standard
|
||||
for describing the timingly definitions, like e.g. UTC.
|
||||
And indeed:
|
||||
<ul>
|
||||
<li>RE.0, REI.0 <b> Egw and EgwIcal try to handle DATE-TIME events in UTC.</b>
|
||||
|
||||
Or of course, equivalently, some (time + UTC offset)-pair description.
|
||||
</ul>
|
||||
|
||||
|
||||
For handling D events you can best give a (timezone/geo) relative
|
||||
description together with the GEO location. Then someone who wants to
|
||||
visit such a event can checkout the location and see what timezone
|
||||
they have there at moment of the event, calculate it back to UTC and
|
||||
then she knows when to get there.
|
||||
Egw and EgwIcal are no very sophisticated in handling these:
|
||||
|
||||
- <b> RE.1 (I am not 100% sure:) Egw tries to handle DATE events relative to
|
||||
the UserInterface its timezone: the so called USER-TIME.</b>
|
||||
|
||||
and for EgwIcal:
|
||||
|
||||
- <b> REI.1 EgwIcal tries to handle DATE events relative to
|
||||
the UserInterface timezone (USER-TIME) of the IcalSrv proces of the
|
||||
logged in user.</b>
|
||||
|
||||
and keep in mind:
|
||||
|
||||
- <b> REI.2 EgwIcal currently will only import or export DATE events
|
||||
for <i>whole day</i> events or for <i>occurence settings of recurrent
|
||||
events</i> </b>
|
||||
|
||||
In the following sections I will explain a bit more what this means
|
||||
for import of Ical data from clients and export to it.
|
||||
|
||||
|
||||
|
||||
|
||||
@section secegwicalimptzh EgwIcal Timezone handling for icaldata import from a client.
|
||||
|
||||
.....
|
||||
|
||||
@subsection subsecvtmz VTIMEZONE import handling.
|
||||
|
||||
No VTIMEZONE ical elements are parsed or used
|
||||
This has a consequence:
|
||||
|
||||
- no basic import timezone setting via this supported
|
||||
|
||||
- no imported timezones with identifiers that can be referenced by
|
||||
VEVENTS or VTODOS are supported
|
||||
|
||||
@subsection subsecdtimp DATETIME formatted data import handling.
|
||||
|
||||
DATETIME formatted data is inspected for its timezone. If the
|
||||
timezone is UTC ('Z') then it is converted (i.e. copied) to UTC
|
||||
before processing further. If the timezone is not given of is
|
||||
referenced with a key to a VTIMEZONE component in the Icalendar
|
||||
file, this timezone info is discarded and <b> a "timezoned" DATETIME
|
||||
is just interpreted as relative to the USERTIME of the IcalSrv
|
||||
process: any timezone info is neglected</b>.
|
||||
|
||||
Clearly this can be wrong in many occasions: thus this should be
|
||||
considered a BUG!
|
||||
|
||||
@subsection subsecdimp DATE formatted data import handling.
|
||||
|
||||
<b>DATE formatted data is ust interpreted as relative to the USERTIME of the IcalSrv
|
||||
process: any timezone info is neglected</b>.
|
||||
|
||||
|
||||
@subsection subsecrruleimp Importing Recurrence Elements
|
||||
|
||||
|
||||
|
||||
Doing recurrence calculation in UTC is notably not a good thing to
|
||||
do because DayTime Savings changes during the runtime of the
|
||||
recurring event can cause troubles. The best thing to do is to
|
||||
calculate the recurrence in the geo/time-zone of the definer. See
|
||||
@url ... of the CAlConnect Group for this. But as clients often dont
|
||||
export their timezones, (and we dont do any processing of it anyhow)
|
||||
we do the following:
|
||||
|
||||
<ol>
|
||||
<li> first the START and (if there UNTIL) dates are converted to UTC
|
||||
dates. Then these are converted to the IcalSrv locale setting.
|
||||
|
||||
<li> Then the recurrence rules are evaluated, and converted to the info
|
||||
Egw needs. Note: Egw cannot use the COUNT field, so EgwIcal has to
|
||||
rewrite it to a UNTIL value.
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
@section secegwicalexptzh EgwIcal Timezone handling for icaldata export to a client.
|
||||
|
||||
On export ....
|
||||
|
||||
- all Egw DATETIME info is exported in UTC time.
|
||||
|
||||
- all Egw DATE info is exported without any timezone info,
|
||||
and thus should best be considered in the USERTIME of the IcalSrv
|
||||
process.
|
||||
|
||||
|
||||
@subsection subsecrruleexp Exporting Recurrence Elements
|
||||
|
||||
On export Recurrence Rules are interpreted as follows:
|
||||
|
||||
<ul>
|
||||
<li> the START date, if in DATE-TIME format is converted to UTC.
|
||||
If it is in DATE format exported right away, thus being in the
|
||||
IcalSrv local timezone: <b>this may be wrong, but best possible!</b>.
|
||||
|
||||
<li> If there, an UNTIL date this is exported as UTC
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
Hope this explains things a bit.
|
||||
|
||||
Jan
|
||||
|
||||
*/
|
182
egwical/doc/EgwIcal-intro.txt
Normal file
182
egwical/doc/EgwIcal-intro.txt
Normal file
@ -0,0 +1,182 @@
|
||||
/*! @mainpage EgwIcal package for Egroupware
|
||||
|
||||
@NOTE this text is not up to date
|
||||
@version 0.9.01
|
||||
@author jvl
|
||||
|
||||
The EgwIcal package provides routines for converting between iCalendar RFC
|
||||
2445 conformant dataelements (like VEVENTS, VTODOS, VALARMS etc.) and
|
||||
corresponding Egroupware database entries (like calendar events,
|
||||
infolog tasks etc.). EgwIcal also provides routines to do import to
|
||||
and export from the Egroupware system for these iCalendar elements,
|
||||
thereby doing the conversion on the fly. Finally, EgwIcal provides a
|
||||
buffering feature where mixed sets of these elements can be accumulated and
|
||||
then be imported or exported all at once.
|
||||
|
||||
@section secinstall SHORT experimental Install How-To:
|
||||
|
||||
- Install the EgwIcal package by either checking out the egwical module from cvs
|
||||
or untarring some tarball egwical-vx.y.x.tgz of the package (when available).
|
||||
|
||||
|
||||
@section secusage Usage of the EgwIcal system
|
||||
|
||||
The EgwIcal system allows four(or 3?) characteristic ways to help you
|
||||
with manipulating iCalendar data in a Egw context:.....
|
||||
|
||||
@section secusageiecnv Converting iCalendar elements to Egw elements
|
||||
|
||||
To convert a iCalendar datacomponent e.g. of type "VEVENT" into a
|
||||
corresponding egw component of e.g. "calendar event" you can use the
|
||||
following in your code:
|
||||
|
||||
<code> ......
|
||||
</code>
|
||||
|
||||
@section secusageeicnv Converting Egw elements to iCalendar elements.
|
||||
|
||||
To convert a egw component of e.g. "calendar event" into a
|
||||
corresponding iCalendar datacomponent of e.g. type "VEVENT"you can use the
|
||||
following in your code:
|
||||
|
||||
<code> ......
|
||||
</code>
|
||||
|
||||
@section secusageimport Importing iCalendar elements into Egw
|
||||
applications storage.
|
||||
|
||||
To import a iCalendar datacomponentof e.g. type "VEVENT" as a
|
||||
corresponding egw component of type "calendar event" into your
|
||||
calendar application (its database) you can use the
|
||||
following in your code:
|
||||
|
||||
<code> ......
|
||||
</code>
|
||||
|
||||
@section secusageexport Exporting Egw application elements as iCalendar elements.
|
||||
|
||||
To export as a egw datacomponent of e.g. type "calendar event" from your
|
||||
calendar application (its database) as a iCalendar datacomponentof e.g. type "VEVENT",
|
||||
you can use the following in your code:
|
||||
|
||||
<code> ......
|
||||
</code>
|
||||
|
||||
@section secusageexpimpbuffer Exporting (mixed) collections of iCalendar elements.
|
||||
|
||||
Beside directly exporting single elements or sets of
|
||||
iCalendar data generated generated from a egw application like
|
||||
calendar, you can also use the "buffer" system of EgwIcal, to collect
|
||||
various sets of such dataelements, even from different Egw
|
||||
applications (like calendar and infolog), and then later on export
|
||||
these all together as one big iCalendar.
|
||||
|
||||
To do collection followed by export you can use code like below:
|
||||
<code> ......
|
||||
</code>
|
||||
|
||||
|
||||
@section secimplementation How is EgwIcal implemented?
|
||||
|
||||
To use or extend EgwIcal best, as a developer, it may be good know a bit about
|
||||
its implementation.
|
||||
EgwIcal is built according to the Workers Union Representatives
|
||||
Hierarchy (WURH) pattern. Quite a mouthfull, and probably there are
|
||||
somewhere better names for this pattern (see ...). In @ref pageegwicalwurh
|
||||
you can read more on this.
|
||||
|
||||
Basically it means that there is one super "worker" class
|
||||
@ref egwical that uses for specific work like e.g. conversion
|
||||
between VEVENTS and calendar tasks, a specific subclass
|
||||
like e.g. bocalupdate_vevents that is connected to the
|
||||
egwical object via a socalled "representative" member in the registry $reg_rscs
|
||||
(attribute).
|
||||
|
||||
Currently EgwIcal has the following subclasses:
|
||||
|
||||
- <code>bocalupdate_vevents</code> for manipulating calendar events as
|
||||
VEVENTS.
|
||||
|
||||
- <code>boinfolog_vtodos</code> for manipulating infolog tasks as VTODOS.
|
||||
|
||||
Future subclasses might be:
|
||||
|
||||
- <code>???_vjournals</code> for manipulating .... as VJOURNALS.
|
||||
|
||||
- <code>bocal_vfreebusies</code> for manipulating calendar data as
|
||||
VFREEBUSY elements.
|
||||
|
||||
- <code>addressbook_vcard</code> for manipulating addressdata data as
|
||||
VCARDS.
|
||||
|
||||
- <code>???_vnotes</code> for manipulating .... as VNOTES.
|
||||
|
||||
|
||||
|
||||
@section secdeletioncheatcode Cheatcode for Deleting Calendars, events or todos
|
||||
|
||||
Egwical provides a special "hackish" feature specifically meant for
|
||||
use with the crippeld ical-over-http (aka webcal) implementation that
|
||||
the package IcalSrv provides for Egroupware.
|
||||
|
||||
This IcalSrv implementation does not support deletion of egw calendar
|
||||
or infolog elements directly (see the IcalSrv package). As a help out
|
||||
the "cheat" is implemented that: you can though delete an item by
|
||||
simply giving the VEVENT or VTODO 'SUMMARY' field a value
|
||||
<code>X-DELETE</code> or <code>_DELETED_</code> and then importing it
|
||||
through the Egwical system. I you do so the the corresponding egw
|
||||
element from calendar or infolog will get deleted.
|
||||
|
||||
|
||||
@section secpatches Patches
|
||||
|
||||
|
||||
You may need to apply some of the patches found in PATCHES.
|
||||
Currently there a two patches to fix a warning and a bug (related to EXDATE
|
||||
fields handling) in the horde routines.
|
||||
Note these may be already committed in the CVS version.
|
||||
|
||||
|
||||
|
||||
@section sectest Extra testing
|
||||
|
||||
The package contains two "compatibility" classes (@ref boical and @ref vcalinfolog) with
|
||||
which you can replace
|
||||
the current <code>infolog/inc/class.vcalinfolog.inc.php</code> resp.
|
||||
<code>calendar/inc/class.boical.inc.php</code>
|
||||
files.
|
||||
|
||||
When done so, the egw syncml, ical import/export and infolog import/export in egw
|
||||
will all use the new code. This way you can discover more bugs and failure in the code :)
|
||||
|
||||
But, when not renamed, these programs will use the old code (and thus are not broken or
|
||||
improved by the new one..)
|
||||
|
||||
|
||||
@section secdocumentation Documentation
|
||||
|
||||
There is (somewhere) complete doxygen generated documentation for the
|
||||
EgwIcal package. Otherwise you can generate it yourself by using
|
||||
doxygen on the source filetree. Maybe phpdocumenter can give you also
|
||||
something usefull. And maybe you are just reading it now this very moment...
|
||||
|
||||
|
||||
|
||||
@section secbugandtodo BuG and todo list
|
||||
|
||||
@todo notably timezone handling in EgwIcal should be documented and
|
||||
possible features to allow import/export and use of iCalendar
|
||||
VTIMEZONE components should be provided.
|
||||
|
||||
-see BUGs and TODOs in @ref pageegwicalbugandtodo
|
||||
|
||||
|
||||
|
||||
|
||||
have fun
|
||||
|
||||
|
||||
JVL
|
||||
|
||||
|
||||
*/
|
BIN
egwical/doc/egwical-doxydoc.tgz
Normal file
BIN
egwical/doc/egwical-doxydoc.tgz
Normal file
Binary file not shown.
205
egwical/doc/egwical-wurh-pattern.txt
Normal file
205
egwical/doc/egwical-wurh-pattern.txt
Normal file
@ -0,0 +1,205 @@
|
||||
/*!
|
||||
\page pageegwicalwurh EgwIcal Workers Union Representatives Hierarchy Pattern
|
||||
implementation.
|
||||
|
||||
@author JVL
|
||||
@date 20060214
|
||||
@version v0.9.02
|
||||
|
||||
The current Egw Ical package provides routines for exporting iCalendar
|
||||
data like vevents, vtodos, vcards etc. from the various corresponding
|
||||
Egroupware packages (the "backends"). And vice versa importing these to the datastores
|
||||
of these packages. On the other hand there can also be a variety of
|
||||
interface components that transport e.g these exported vevents to
|
||||
further applications (the "clients"). Think e.g on the "icalsrv"
|
||||
service to transport whole sets of vevents in one go over http to a
|
||||
client, or the "syncml" service that transports them to syncml
|
||||
speaking device, or simple routine that let you save or upload a
|
||||
calendar file from within the webgui.
|
||||
|
||||
An iCalendar data object can hold a set of these various kinds of
|
||||
data-elements as parts of itself. And these data-elements itself can
|
||||
also be composed of sub-elements (like e.g. VALARM and VTIMEZONE
|
||||
components).
|
||||
|
||||
|
||||
So in this situation we have Wholes (like an iCalendar object) with
|
||||
Parts (like groups of Vevents and groups of Vtodos) on the one hand.
|
||||
And on the other hand we have dedicated subappliations that may handle
|
||||
these groups of Part data. To implement this we can make use of a
|
||||
smart combination of two implementation primitives "compounds" and
|
||||
"classes and subclasses".
|
||||
|
||||
In the WURH pattern the combination of these two is very rather
|
||||
outspoken and quite entangled and even a bit tricky: each specific
|
||||
type of Part is "represented" by specific subclass of the class of
|
||||
Whole compound. The data in the parts can now be manipulated in two
|
||||
ways:
|
||||
|
||||
1) all together as whole, via methods of the compound, or
|
||||
2) all in the group of a part, by the methods of the (associated)
|
||||
subclass its representative.
|
||||
|
||||
@note I forgot the official (GOF) name of the pattern (if there is
|
||||
any..)
|
||||
|
||||
|
||||
|
||||
\section secwurhexample Example WURH pattern implementation: Meal preparation
|
||||
|
||||
As simple example should explain this: Meal preparation URH pattern
|
||||
implementation
|
||||
|
||||
think of the preparation of meal, that consist of soup and meat.
|
||||
To "cook" the meal, the soup has to be boiled and the meat has to be
|
||||
baked.
|
||||
|
||||
in OO notation: <code><>- </code> or <code>.</code> . means member of,
|
||||
<code><- </code> means subclass of
|
||||
|
||||
Classes:
|
||||
<PRE>
|
||||
MealCooker <- SoupCooker; MealCooker <- MeatCooker;
|
||||
MealCooker <>- SoupCooker; MealCooker <>- MeatCooker;
|
||||
</PRE>
|
||||
Methods:
|
||||
<PRE>
|
||||
MealCooker->cook(); SoupCooker->boil(); MeatCooker->bake();
|
||||
</PRE>
|
||||
and possibly the cook() method may even, for easy of use in the Soup and
|
||||
Meat classes by implemented (overridden) by the boil() resp. bake() method.
|
||||
|
||||
Now the code to prepare to have $mymealck prepare a meail with $mysoupck and $mymeatck (without
|
||||
subclass overrriding):
|
||||
<PRE>
|
||||
$mymealck = New MealCooker;
|
||||
$mymeatck = New MeatCooker;
|
||||
$mysoupck = New SoupCooker;
|
||||
|
||||
$meat_in_mealck = $mymealck->addMeatHandler($mymeatck);
|
||||
$soup_in mealck = $mymealck->addSoupHandler($mysoupck);
|
||||
|
||||
// these are in class MealCooker implemented as
|
||||
// $this.m = meatcooker_config($mymeatck); resp. $this.s = soupcooker_config($mysoupck);
|
||||
</PRE>
|
||||
|
||||
Now cooking the meal is done by, cooking the soup in its appropiate
|
||||
way (namely "boiling()" )via its union representative ($soup_in_mealck). Note that it is
|
||||
called "union" representative because multiple SoupCookers parts may have been
|
||||
added already to use. And also cooking the meat in its appropiate way
|
||||
("baking()") likewise. Thus
|
||||
<PRE>
|
||||
$mymealck->cook([$apiec_of_meat,$avolum_of_soup]) can be done by calling:
|
||||
|
||||
$meat_in_mealck->bake($apiece_of_meat);
|
||||
$soup_in_mealck->boil($avolume_of_soup);
|
||||
</PRE>
|
||||
and then you can serve boths parts in one go with:
|
||||
<PRE>
|
||||
$mymealck->serve();
|
||||
</PRE>
|
||||
|
||||
If we implemented the specific ways of cooking as overriding subclass
|
||||
methods for Meal->cook() then in simple cases we dont even need to use
|
||||
the representatives to call the preparation as we implement to main
|
||||
cook() method to call all itself on all its parts:
|
||||
<PRE>
|
||||
$mymealck = New MealCooker;
|
||||
$mymeatck = New MeatCooker;
|
||||
$mysoupck = New SoupCooker;
|
||||
|
||||
$mymealck->addMeatHandler($mymeatck);
|
||||
$mymealck->addSoupHandler($mysoupck);
|
||||
</PRE>
|
||||
|
||||
And <code> $mymealck->cook([$apiec_of_meat,$avolum_of_soup]) </code> can then done by
|
||||
just calling:
|
||||
|
||||
<PRE>
|
||||
$meat_in_mealck->bake($apiece_of_meat);
|
||||
$soup_in_mealck->boil($avolume_of_soup);
|
||||
|
||||
// which effects in $mymealck.m->cook($apiece_o_fmeat);
|
||||
// and $mymealck.s ->cook($avolume_of_soup);
|
||||
// that effects again in $mymealck.m->bake($apiece_o_fmeat);
|
||||
// and $mymealck.s->boil($avolume_of_soup);
|
||||
|
||||
</PRE>
|
||||
|
||||
So this allows for using of manipulation methods of the whole (in case
|
||||
of simple generic actions reimplemented in the subclasses of the
|
||||
parts) together with using more specific methods for specific
|
||||
parts. (e.g. $soup_in_mealck->set_boil_time(10) etc.)
|
||||
|
||||
|
||||
|
||||
\section securhinei WURH pattern usage in Egwical.
|
||||
|
||||
The Egwical class manages an complete iCalendar component with
|
||||
VEVENTS, VTODOS etc. as parts. The handling of these part(unions)s is
|
||||
done by specific subclasses of Egwical, like e.g. infolog_bovtodo and
|
||||
calendar_bovevents.
|
||||
The system can be used in two different modes of operation:
|
||||
|
||||
- 1) for conversion of egw tasks, events, etc. to their iCal
|
||||
counterparts. (the cnv_ methods).
|
||||
|
||||
- 2) for filling the (internal) egwical object with al lot of vtodos and
|
||||
vevents, either coming from import or from conversion of egw
|
||||
counterparts. When the compound is filled it can (as a whole) be
|
||||
exported or imported.
|
||||
|
||||
|
||||
add 1) So e.g. exporting a group of events refered to by $event_ids as
|
||||
VEVENTS goes as follows:
|
||||
<PRE>
|
||||
$cal = New Bocal; // build calendar
|
||||
$event_ids = $cal->search("filt_def'); // get group of egw event ids to export.
|
||||
|
||||
$ei = New Egwical; // build Compound iCalendar processor
|
||||
$bve = $ei->addRsc($cal); // add calendar part and get representive
|
||||
$vcalstr = $bve->cnv2VEVENTS($event_ids); // export some events
|
||||
|
||||
</PRE>
|
||||
|
||||
if we also want to export some VTODOs this goes as follows:
|
||||
|
||||
<PRE>
|
||||
$binf = New Infolog // build infolog app. object
|
||||
$task_ids = $binf->search("filt_def'); // get group of egw task ids to export.
|
||||
|
||||
$bvt = $ei->addRsc($binf); // add infolog part and get representive
|
||||
$vcalstr = $bvt->cnv2VTODOS($task_ids);
|
||||
|
||||
</PRE>
|
||||
add 2) the same egw elements from 1) are now first collected in
|
||||
egwical and then as a whole exported.
|
||||
|
||||
<PRE>
|
||||
$cal = New Bocal; // build calendar
|
||||
$event_ids = $cal->search("filt_def'); // get group of egw event ids to export.
|
||||
|
||||
$ei = New Egwical; // build Compound iCalendar processor
|
||||
$bve = $ei->addRsc($cal); // add calendar sys part and get representive
|
||||
$bve->clear(); // empty the list of Vevents in bve
|
||||
$bve->addEventsOntoVEVENTS($event_ids); // add the converted events to vevents in $ei
|
||||
|
||||
</PRE>
|
||||
if we also want to add some VTODOs this goes as follows:
|
||||
<PRE>
|
||||
$binf = New Infolog // build infolog app. object
|
||||
$task_ids = $binf->search("filt_def'); // get group of egw task ids to export.
|
||||
|
||||
$bvt = $ei->addRsc($binf); // add infolog sys part and get representive
|
||||
$bvt->clear(); // empty the list of Vtodos in bvt
|
||||
$bvt>addTasksOntoVTODOS($task_ids); // add the converted tasks to vtodos in $ei
|
||||
|
||||
</PRE>
|
||||
and finally export the whole iCalendar
|
||||
<PRE>
|
||||
$ei->export()
|
||||
</PRE>
|
||||
|
||||
----------
|
||||
|
||||
*/
|
1075
egwical/inc/class.bocalupdate_vevents.inc.php
Normal file
1075
egwical/inc/class.bocalupdate_vevents.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
69
egwical/inc/class.boical.inc.compat.php
Normal file
69
egwical/inc/class.boical.inc.compat.php
Normal file
@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* eGroupWare - compatibility replacement for file calendar/inc/class.boical.inc.php
|
||||
* to start using the new egwical routines.
|
||||
*
|
||||
* http://www.egroupware.org *
|
||||
* @author Jan van Lieshout *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License. *
|
||||
* @version 0.9.00
|
||||
\**************************************************************************/
|
||||
|
||||
/* THIS CLASS IS JUST HERE FOR BACKWARD COMPATIBILITY */
|
||||
/* in future you should rewrite ical handling using the egwical class */
|
||||
|
||||
// require_once EGW_SERVER_ROOT.'/egwicalsrv/inc/calendar/class.bovevents.inc.php';
|
||||
|
||||
|
||||
class boical extends bocalupdate
|
||||
{
|
||||
// introduce auxilliary egwical object
|
||||
var $ei;
|
||||
|
||||
// introduce a worker obj (also accessible via $ei but this is shorter..)
|
||||
var $wkobj;
|
||||
|
||||
function boical()
|
||||
{
|
||||
bocalupdate::bocalupdate(); // call superclass constructor
|
||||
error_log("warning class: calendar.boical call DEPRECATED," .
|
||||
"\nplease rewrite your code to use egwical class" .
|
||||
"\n now temporary code fix used ");
|
||||
// The longer road, using egwicals cleverness:
|
||||
$this->ei =& CreateObject('egwical.egwical');
|
||||
$this->wkobj =& $this->ei->addRsc($this);
|
||||
// alternatively the fast, shortcut, road for knowingly experts only:
|
||||
//$this->wkobj =& CreateObject('egwical.bocalupdate_vevents');
|
||||
//$this->wkobj->setRsc($this);
|
||||
|
||||
if ($this->wkobj == false){
|
||||
error_log('boical constructor: couldnot add boical resource to egwical: FATAL');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now implement the compatibility methods, that are all moved to egwical!
|
||||
|
||||
function &exportVCal($events,$version='1.0',$method='PUBLISH')
|
||||
{
|
||||
return $this->wkobj->exportVCal($events,$version,$method);
|
||||
}
|
||||
|
||||
function importVCal($_vcalData, $cal_id=-1)
|
||||
{
|
||||
return $this->wkobj->importVCal($_vcalData, $cal_id);
|
||||
}
|
||||
|
||||
|
||||
function setSupportedFields($_productManufacturer='file', $_productName='')
|
||||
{
|
||||
return $this->wkobj->setSupportedFields($_productManufacturer, $_productName);
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
561
egwical/inc/class.boinfolog_vtodos.inc.php
Normal file
561
egwical/inc/class.boinfolog_vtodos.inc.php
Normal file
@ -0,0 +1,561 @@
|
||||
<?php
|
||||
/**
|
||||
*@file
|
||||
* eGroupWare - iCalendar VTODOS conversion, import and export for egw infolog
|
||||
* application.
|
||||
*
|
||||
* http://www.egroupware.org *
|
||||
* @author Jan van Lieshout *
|
||||
* based on class.boical.inc.php and on class.vcalinfolog.inc.php
|
||||
* originals written by Lars Kneschke <lkneschke@egroupware.org> *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License. *
|
||||
**************************************************************************/
|
||||
|
||||
/* JVL Todo V0.7:
|
||||
* - add structure and API terminology from class.bovevents.inc.php:DONE
|
||||
* - rewrite all vevent to vtodo strings: DONE..
|
||||
* - Maybe add a supportFields system as done in calendar.bovevents, to allow for
|
||||
* handling vtodos for various devices
|
||||
* - if done document the supportFields method and show how it can be used
|
||||
* - find out how to do deletion based on imported VTODOS ? Can that be done?
|
||||
* - check the usage and conversions of user time and server times
|
||||
* - add compatibility API for the class infolog.vcalinfolog: DONE but UNTESTED
|
||||
* - add ORGANIZER export: DONE (V0.51) removed (dont know map field)
|
||||
* - add ORGANIZER import: ... maybe map t info_responsible
|
||||
* - add CATEGORIES export: DONE (V0.52)
|
||||
* - add CATEGORIE import: DONE (V0.7.01)
|
||||
* - add "subtask" export: DONE (v0.52)
|
||||
* - add "subtask" import: PARTLY
|
||||
* - rewrite PRIORITY export: DONE (V0.52)
|
||||
* - rewrite PRIORITY import:DONE (V0.7.01)
|
||||
* - repair datecreated: DONT know map field
|
||||
* - repair date modified export: PARTLY done
|
||||
* - repair startdate or enddate without time details: DONE (V0.7.02)
|
||||
*/
|
||||
|
||||
|
||||
// require_once EGW_SERVER_ROOT.'/infolog/inc/class.boinfolog.inc.php';
|
||||
require_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/Horde/iCalendar.php';
|
||||
// require_once EGW_SERVER_ROOT.'/icalsrv/inc/class.egwical.inc.php';
|
||||
|
||||
/**
|
||||
*
|
||||
* iCal vtodos import and export via Horde iCalendar classes
|
||||
* @note the routines in this package should be used OO only so that de constructor
|
||||
* can initialize the data common to the import and export routines
|
||||
* @note this package provides compatibilty routines for class infolog.vcalinfolog
|
||||
* this can e.g. be used by making infolog.vcalinfolog a simple extension of
|
||||
* infolog.bovtodos
|
||||
*
|
||||
* @todo move the compatibility functions for vcalinfolog completely to the compat class.
|
||||
* There is no need to have them here anymore.
|
||||
* @todo rewrite bovtodos to use a ical2egw and supportedFields system
|
||||
* @todo <b>IMPORTANT</b> rewrite bovtodos to handle uid_matching analogous to bovevents
|
||||
*
|
||||
* @package egwical
|
||||
* @author Jan van Lieshout <jvl (at)xs4all.nl> This version.
|
||||
* @author Lars Kneschke <lkneschke@egroupware.org> (parts of reused code)
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de> (parts of reused code)
|
||||
* @version 0.9.02 First for use with new WURH egwical class
|
||||
* @license http://opensource.org/licenses/gpl-license.php GPL -
|
||||
* GNU General Public License
|
||||
*/
|
||||
|
||||
class boinfolog_vtodos extends egwical
|
||||
{
|
||||
|
||||
/**
|
||||
* @var object
|
||||
* The egw infolog object that will be used to transport events from and to
|
||||
* This is set by setRsc()
|
||||
*/
|
||||
var $myinf = null;
|
||||
|
||||
|
||||
/**
|
||||
* Describe the provided work capabilities of the class.
|
||||
* @return string The description as entries for the @ref $reg_workers registry
|
||||
* table.
|
||||
*/
|
||||
function provides_work()
|
||||
{
|
||||
return
|
||||
array('boinfolog' => array('workerclass' => 'boinfolog_vtodos',
|
||||
'workerobj' => $null,
|
||||
'icalsup' => array('VTODO')),
|
||||
'vcalinfolog' => array('workerclass' => 'boinfolog_vtodos',
|
||||
'workerobj' => $null,
|
||||
'icalsup' => array('VTODO'))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Our Constructor, fills the basic class members
|
||||
* and set the description of our worker capabilities.
|
||||
*/
|
||||
function bovtodos() {
|
||||
|
||||
// call superclass constructor by hand
|
||||
boinfolog::boinfolog();
|
||||
|
||||
$this->TASKMAGIC = $GLOBALS['egw_info']['server']['install_id']
|
||||
? $GLOBALS['egw_info']['server']['install_id']
|
||||
: 'local';
|
||||
|
||||
// $this->setSupportedFields(); //not implemented yet
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the egw resource that this worker will handle.
|
||||
* This worker is only capable of handling boinfolog objects, so it should
|
||||
* be of that class. This method is mostly called indirectly from a egwical compound
|
||||
* addRsc() call. But you can call it also directly (if you know what your doing ..)
|
||||
* @return boolean false on error, true else
|
||||
*/
|
||||
function setRsc($egw_rsc)
|
||||
{
|
||||
if(!is_a($egw_rsc,'boinfolog'))
|
||||
return false;
|
||||
$this->myinf = $egw_rsc;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// --- conversion and import code --
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @var $TASKMAGIC
|
||||
* Magic unique number used for de/encoding our uids.
|
||||
*
|
||||
* This string that contains global unique magic number that is
|
||||
* unique for our current database installed etc. It is used to recognize
|
||||
* earlier exported VTODO or VEVENT UID fields as referring to their eGW counterparts.
|
||||
*/
|
||||
var $TASKMAGIC='dummy';
|
||||
|
||||
|
||||
|
||||
|
||||
// Some helper functions first
|
||||
|
||||
|
||||
/**
|
||||
* generate a unique id, with the todo id encoded into it, which can be
|
||||
* used for later synchronisation.
|
||||
*
|
||||
* @param $todo_id string|int eGW id of the content
|
||||
* @use $TASKMAGIC string that holds our unique ID
|
||||
* @return false|string on error: false
|
||||
* on success the global unique id
|
||||
*/
|
||||
function _id2guid($todo_id)
|
||||
{
|
||||
if (empty($todo_id))
|
||||
return false;
|
||||
|
||||
return 'infolog_task'.'-'.$todo_id.'-'. $this->TASKMAGIC;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* get the local content id from a global UID
|
||||
*
|
||||
* @param string $globalUid the global UID
|
||||
* @return false|int on error: false
|
||||
* on success: local egw todo id
|
||||
*/
|
||||
function _guid2id($VTodoUID)
|
||||
{
|
||||
// error_log('_guid2id: trying to recover id from' . $VTodoUID);
|
||||
if (!preg_match('/^infolog_task-(\d+)-' .
|
||||
$this->TASKMAGIC . '$/',$VTodoUID,$matches))
|
||||
return false;
|
||||
|
||||
// error_log("_guid2id: found (" . $matches[1] . ")");
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* export the eGW todos in $todos to iCalendar VTODOS and add these to
|
||||
* the Horde_iCalendar object &$hIcal
|
||||
* Note: that because eGW does not store uid fields for tasks in its db we
|
||||
* are in general not able to recoginize VTODOS by their uid-field.
|
||||
* Because of this it is only possible to have a VTODO overwrite an internal
|
||||
* eGW todo (task) when this VTODO was in an earlier fase build as export of an
|
||||
* internal eGW todo. In other words to later on change your imported VTODO,
|
||||
* you first have export it and in the client make your changes on this exemplar.
|
||||
*
|
||||
* @param &$hIcal Horde_iCalendar object to wich the produced VTodos are added
|
||||
* @param $todos array with either id s (tids) for a eGW todoData structs
|
||||
* or an array of such todoData structs, that will be exported
|
||||
* @param boolean $euid_export if true export the uid field (Note: Currently not available!)
|
||||
* else generate a uid from with the task id encoded (Default setting)
|
||||
* @return $ok/$vcnt boolean/int on error: false / on success: nof vtodos exported
|
||||
* @use members supportedFields(), _id2guid()
|
||||
*/
|
||||
function exportTodosOntoIcal(&$hIcal, $todos, $euid_export=false)
|
||||
{
|
||||
//NOTE: $euid_export has currently no effect
|
||||
# error_log("ical_export_add_Todos here, for " . count($todos) . "todos");
|
||||
|
||||
$todo = array(); // container for each todo to be exported
|
||||
$tid = null; // id of the todo to be exported
|
||||
$vexpcnt =0; // number of vtodos exported
|
||||
# $options = array('CHARSET' => 'UTF-8','ENCODING' => 'QUOTED-PRINTABLE');
|
||||
|
||||
|
||||
if (!is_array($todos)) $todos = array($todos);
|
||||
|
||||
foreach($todos as $todo) {
|
||||
// some hocuspocus to handle the polymorphy of the $todos arg
|
||||
if (!is_array($todo)
|
||||
&& !($todo = $this->myinf->read($todo))){
|
||||
|
||||
return false; // no permission to read $tid
|
||||
}
|
||||
$tid = $todo['info_id'];
|
||||
// oke, now sure $todo is a todoData array and $tid its info_id field..
|
||||
//_debug_array($todo);
|
||||
|
||||
$todo = $GLOBALS['egw']->translation->
|
||||
convert($todo,$GLOBALS['egw']->translation->charset(),'UTF-8');
|
||||
|
||||
# error_log('todo to export=' . print_r($todo,true));
|
||||
|
||||
//someday: $this->newComponent() ???
|
||||
$vtodo = Horde_iCalendar::newComponent('VTODO',$hIcal);
|
||||
|
||||
$vGUID = $this->_id2guid($tid);
|
||||
|
||||
// if (!$euid_export)
|
||||
// append Non Recoverable so _guid2id() wont recognize it later
|
||||
// $vGUID .= 'NR';
|
||||
$vtodo->setAttribute('UID',$vGUID);
|
||||
// for subtasks set the parent
|
||||
// egw2vtodo: info_id_parent => pid -> RELATED-TO:parent_uid
|
||||
if ($parid = $todo['info_id_parent'])
|
||||
$vtodo->setAttribute('RELATED-TO', $this->_id2guid($parid));
|
||||
|
||||
$vtodo->setAttribute('SUMMARY', $todo['info_subject']);
|
||||
$vtodo->setParameter('SUMMARY', $options);
|
||||
$vtodo->setAttribute('DESCRIPTION', $todo['info_des']);
|
||||
$vtodo->setParameter('DESCRIPTION', $options);
|
||||
if($todo['info_startdate'])
|
||||
$vtodo->setAttribute('DTSTART', $todo['info_startdate']);
|
||||
if($todo['info_enddate'])
|
||||
$vtodo->setAttribute('DUE', $todo['info_enddate']);
|
||||
$vtodo->setAttribute('DTSTAMP',time());
|
||||
|
||||
$lastmodDate = $todo['info_datemodified'];
|
||||
$vtodo->setAttribute('LAST-MODIFIED', $lastmodDate );
|
||||
|
||||
if ($createDate = $this->get_TSdbAdd($tid,'infolog')){
|
||||
$vtodo->setAttribute( 'CREATED', $createDate);
|
||||
} else {
|
||||
$vtodo->setAttribute( 'CREATED', $lastmodDate);
|
||||
}
|
||||
|
||||
// egw2VTOD: owner -> ORGANIZER field
|
||||
if ($tfrom_id = $todo['info_owner']){
|
||||
$mailtoOrganizer = $GLOBALS['egw']->accounts->id2name($tfrom_id,'account_email');
|
||||
$vtodo->setAttribute('ORGANIZER', $this->mki_v_CAL_ADDRESS($tfrom_id));
|
||||
$vtodo->setParameter('ORGANIZER', $this->mki_p_CN($tfrom_id));
|
||||
}
|
||||
|
||||
$vtodo->setAttribute('CLASS',
|
||||
($todo['info_access'] == 'public')?'PUBLIC':'PRIVATE');
|
||||
// CATEGORIES, value= all category names from info_cat field comma-separated list
|
||||
// n.b. dont mind catid ==0 (this is none categorie, I think)
|
||||
if ($catids = $todo['info_cat']){
|
||||
$catnamescstr = $this->cats_ids2idnamescstr(explode(',',$catids));
|
||||
$vtodo->setAttribute('CATEGORIES',$catnamescstr);
|
||||
}
|
||||
|
||||
|
||||
// egw2vtodo status trafo:
|
||||
// done -> COMPLETE:lastmoddate, PERCENT-COMPLETE:100, STATUS:COMPLETED
|
||||
// ongoing -> STATUS: IN-PROCESS
|
||||
// offer -> STATUS: NEEDS-ACTION, PERCENT-COMPLETE:0
|
||||
switch ($todo['info_status']){
|
||||
case 'done':
|
||||
$vtodo->setAttribute('COMPLETED',$lastmodDate); // for ko35, lastmod?
|
||||
$vtodo->setAttribute('PERCENT-COMPLETE','100');
|
||||
$vtodo->setAttribute('STATUS','COMPLETED');
|
||||
break;
|
||||
case 'ongoing':
|
||||
$vtodo->setAttribute('STATUS','IN-PROCESS');
|
||||
break;
|
||||
case 'offer':
|
||||
$vtodo->setAttribute('STATUS','NEEDS-ACTION');
|
||||
# $vtodo->setAttribute('PERCENT-COMPLETE',"0");
|
||||
break;
|
||||
default:
|
||||
// check for percentages
|
||||
if (ereg('([0-9]+)%',$todo['info_status'],$matches)){
|
||||
$vtodo->setAttribute('PERCENT-COMPLETE',$matches[1]);
|
||||
$vtodo->setAttribute('STATUS','IN-PROCESS');
|
||||
}else{
|
||||
$vtodo->setAttribute('STATUS','NEEDS-ACTION');
|
||||
}
|
||||
}
|
||||
|
||||
if (is_numeric($eprio = $todo['info_priority']) && ($eprio >0) )
|
||||
$vtodo->setAttribute('PRIORITY',
|
||||
$this->mki_v_prio($eprio) );
|
||||
|
||||
# $vtodo->setAttribute('TRANSP','OPAQUE');
|
||||
|
||||
$hIcal->addComponent($vtodo);
|
||||
$vexpcnt += 1;
|
||||
}
|
||||
|
||||
return $vexpcnt; //return nof vtodos exported
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* @note PART OF COMPATIBILITY API for INFOLOG.VCALINFOLOG
|
||||
* @note UNTESTED
|
||||
* Export a single eGW task as a VTODO string
|
||||
*
|
||||
* @param $_taskID int/string id of the eGW task to be exported
|
||||
* @param $_version string version the produced iCalendar content should get
|
||||
* @return false|string on error | content of the resulting VTODO iCal element
|
||||
*/
|
||||
function exportVTODO($_taskID, $_version)
|
||||
{
|
||||
$hIcal = &new Horde_iCalendar;
|
||||
$hIcal->setAttribute('VERSION',$_version);
|
||||
$hIcal->setAttribute('METHOD','PUBLISH');
|
||||
|
||||
if(! $tcnt = $this->exportTodosOntoIcal(&$hIcal, array($_taskID), true))
|
||||
return false;
|
||||
|
||||
return $hIcal->exportvCalendar();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Convert the ical VTODOS components that are contained in de $hIcal Horde_iCalendar
|
||||
* to eGW todos and import these into the eGW calendar.
|
||||
* Depending on the value of $importMode, the conversion will generate either eGW
|
||||
* todos with completely new id s (DUPLICATE mode) or try to recover an egw id from
|
||||
* the VTODO;UID field (so called OVERWRITE mode). Note that because eGW currently
|
||||
* does not store todo uid field info in its database, such recovering is only
|
||||
* possible for previously exported todos.
|
||||
*
|
||||
* @param &$hIcal Horde_iCalendar object with ical VTODO objects
|
||||
* @param $importMode string toggle for duplicate (ICAL_IMODE_DUPLICATE)
|
||||
* or overwrite (ICAL_IMODE_OVERWRITE) import mode
|
||||
* @return $false|$timpcnt on error: false | on success: nof imported elms
|
||||
* @use .supportedFields() to steer the VTODOS to eGW todos conversion
|
||||
* @use members _guid2id()
|
||||
*/
|
||||
function importVTodosFromIcal(&$hIcal, $importMode='DUPLICATE')
|
||||
{
|
||||
|
||||
$overwritemode = stristr($importMode,'overwrite') ? true : false;
|
||||
# $ftid = $fixed_taskId;
|
||||
$timpcnt = 0; // nof todos imported
|
||||
$tidOk = true; // return true, if hIcal contains no vtodo components
|
||||
|
||||
foreach($hIcal->getComponents() as $component) {
|
||||
// ($ftid < 0) => recover id (overwritemode) or use no id
|
||||
// ($ftid > 0) => use this value to set the id (compatibility mode)
|
||||
|
||||
if(is_a($component, 'Horde_iCalendar_vtodo')){
|
||||
$tidOk = $this->_importVTodoIcalComponent(&$component, $overwritemode, -1);
|
||||
if (!$tidOk){
|
||||
error_log('infolog.bovtodos.importVTodosFromIcal(): '
|
||||
. ' ERROR importing VTODO ');
|
||||
break; // stop at first error
|
||||
}
|
||||
|
||||
|
||||
$timpcnt += 1; // nof imported ok vtodos
|
||||
}
|
||||
}
|
||||
return (!$tidOk) ? false : $timpcnt;
|
||||
}
|
||||
|
||||
|
||||
/* convert a single vtodo horde icalendar component to a eGW todo and write it to
|
||||
* the infolog system.
|
||||
*
|
||||
* @note this routine should better not be exported
|
||||
* @param &$hIcalComponent Horde_iCalendar_vtodo element that contains the VTODO
|
||||
* that is to be converted and imported
|
||||
* @param $overwriteMode boolean generate a new eGW todo (when false) or allow
|
||||
* overwrite of an existing one (when true)
|
||||
* @param $newtask_id int/string if >0 : the id of the eGW todo that must be
|
||||
* overwritten. if <0 : generation of new task or recover taskId from UID field
|
||||
* @return false | int on error: false | on success: the id of the eGW todo
|
||||
* that was produced/changed
|
||||
*/
|
||||
function _importVTodoIcalComponent(&$hIcalComponent, $overwriteMode, $newtask_id)
|
||||
{
|
||||
$ftid = $newtask_id;
|
||||
$todo = array(); //container for eGW todo
|
||||
$user_id = $this->owner; // we logged in?
|
||||
|
||||
if(!is_a($hIcalComponent, 'Horde_iCalendar_vtodo'))
|
||||
return false;
|
||||
|
||||
if($ftid > 0) {
|
||||
// just go for a change of the content of the eGW task with id=$ftid
|
||||
$todo['info_id'] = $ftid;
|
||||
// we will now ignore a UID field later in this VTodo
|
||||
}
|
||||
|
||||
// now process all the fields found
|
||||
foreach($hIcalComponent->_attributes as $attributes) {
|
||||
# error_log( $attributes['name'].' - '.$attributes['value']);
|
||||
//$attributes['value'] =
|
||||
// $GLOBALS['egw']->translation->convert($attributes['value'],'UTF-8');
|
||||
switch($attributes['name']){
|
||||
case 'UID':
|
||||
if ($ftid > 0) // fixed id mode so we got id from $newtask_id
|
||||
break;
|
||||
$vguid = $attributes['value'];
|
||||
if( $overwriteMode && $tid = $this->_guid2id($vguid)){
|
||||
// an old id was recovered from the UID field, we will use it
|
||||
$todo['info_id'] = $tid;
|
||||
#error_log('import: using existing id:'.$tid);
|
||||
} // else we leave the info_id empty so automatically a new todo gets created
|
||||
break;
|
||||
// rfc s4.8.1.3.egw2vtodo: public|private|confidential
|
||||
case 'CLASS':
|
||||
$todo['info_access'] = strtolower($attributes['value']);
|
||||
break;
|
||||
# case 'ORGANIZER':
|
||||
# $todo['info_from'] = $attributes['value'];
|
||||
# may be put it in info_responsible field ?
|
||||
# // full name + mailto see bovevents on a method to handle this
|
||||
break;
|
||||
|
||||
case 'DESCRIPTION':
|
||||
$todo['info_des'] = $attributes['value'];
|
||||
break;
|
||||
case 'DUE':
|
||||
$todo['info_enddate'] = $this->mke_DDT2utime($attributes['value']);
|
||||
break;
|
||||
case 'DTSTART':
|
||||
$todo['info_startdate'] = $this->mke_DDT2utime($attributes['value']);
|
||||
break;
|
||||
case 'PRIORITY':
|
||||
$todo['info_priority'] = $this->mke_prio($attributes['value']);
|
||||
break;
|
||||
// rfc s4.8.1.11 egw2vtodo status trafo: (now use it backwards)
|
||||
// done -> COMPLETE:lastmoddate, PERCENT-COMPLETE:100, STATUS:COMPLETED
|
||||
// ongoing -> STATUS: IN-PROCESS
|
||||
// offer -> STATUS: NEEDS-ACTION, PERCENT-COMPLETE:0
|
||||
case 'STATUS':
|
||||
switch (strtolower($attributes['value'])){
|
||||
case 'completed':
|
||||
$todo['info_status'] = 'done';
|
||||
break;
|
||||
case 'cancelled':
|
||||
$todo['info_status'] = 'done';
|
||||
break;
|
||||
case 'in-process':
|
||||
$todo['info_status'] = 'ongoing';
|
||||
break;
|
||||
default:
|
||||
// probably == 'needs-action'
|
||||
$todo['info_status'] = 'offer';
|
||||
}
|
||||
break;
|
||||
// date and time when completed
|
||||
case 'COMPLETED':
|
||||
$todo['info_status'] = 'done';
|
||||
break;
|
||||
case 'PERCENT-COMPLETE':
|
||||
$pcnt = (int) $attributes['value'];
|
||||
if ($pcnt < 1) {
|
||||
$todo['info_status'] = 'offer';
|
||||
}elseif($pcnt > 99) {
|
||||
$todo['info_status'] = 'done';
|
||||
}else{
|
||||
$todo['info_status'] = $pcnt . '%'; // better should do rounded to 10s
|
||||
}
|
||||
break;
|
||||
case 'SUMMARY':
|
||||
$todo['info_subject'] = $attributes['value'];
|
||||
break;
|
||||
case 'RELATED-TO':
|
||||
$todo['info_id_parent'] = $this->_guid2id($attributes['value']);
|
||||
break;
|
||||
// unfortunately infolog can handle only one cat atm
|
||||
case 'CATEGORIES':
|
||||
$catnames = explode(',',$attributes['value']);
|
||||
$catids = $this->cats_names2idscstr($catnames,$user_id,'infolog');
|
||||
$todo['info_cat'] = $catids;
|
||||
break;
|
||||
|
||||
case 'LAST-MODIFIED':
|
||||
$todo['info_datemodified'] = $attributes['value'];
|
||||
break;
|
||||
|
||||
default:
|
||||
// error_log('VTODO field:' .$attributes['name'] .':'
|
||||
// . $attributes['value'] . 'HAS NO CONVERSION YET');
|
||||
}
|
||||
}
|
||||
// error_log('todo=' . print_r($todo,true));
|
||||
|
||||
if($todo['info_subject'] == 'X-DELETE' && $tid){
|
||||
// delete the todo (secret HACK, donot use...)
|
||||
return $this->myinf->delete($tid);
|
||||
}else{
|
||||
$tidOk = $this->myinf->write($todo,true,false);
|
||||
// error_log('ok import id:'. $tidOk .' VTODO UID:' . $vguid);
|
||||
return $tidOk;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* @note PART OF COMPATIBILITY API for INFOLOG.VCALINFOLOG
|
||||
* @note UNTESTED
|
||||
* Import a single iCalendar VTODO string as eGW task(aka: todo)
|
||||
*
|
||||
* @param $_vcalData string content of an VTODO iCalender element
|
||||
* @param $_taskID int/string id of the eGW task to be overwritten
|
||||
* when < 0 a new task will get produced
|
||||
* @return false | int on error: false | on success: the id of the eGW todo
|
||||
* that was produced/changed
|
||||
*/
|
||||
function importVTODO(&$_vcalData, $_taskID=-1)
|
||||
{
|
||||
$hIcal = &new Horde_iCalendar;
|
||||
if(!$hIcal->parsevCalendar($_vcalData))
|
||||
return FALSE;
|
||||
|
||||
$components = $hIcal->getComponents();
|
||||
if(count($components) < 1)
|
||||
return false;
|
||||
|
||||
return $this->_importVTodoIcalComponent(&$components[0],
|
||||
true, $_taskID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
1278
egwical/inc/class.egwical.inc.php
Normal file
1278
egwical/inc/class.egwical.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
72
egwical/inc/class.vcalinfolog.inc.compat.php
Normal file
72
egwical/inc/class.vcalinfolog.inc.compat.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* @file
|
||||
* eGroupWare - compatibility replacement for file infolog/inc/class.vcalinfolog.inc.php
|
||||
* to start using the new egwical routines.
|
||||
*
|
||||
* http://www.egroupware.org *
|
||||
* @author Jan van Lieshout *
|
||||
* -------------------------------------------- *
|
||||
* This program is free software; you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU General Public License as published by the *
|
||||
* Free Software Foundation; either version 2 of the License. *
|
||||
* @package egwical
|
||||
* @version 0.9.02
|
||||
\**************************************************************************/
|
||||
|
||||
/* THIS CLASS IS JUST HERE FOR BACKWARD COMPATIBILITY */
|
||||
/* in future you should rewrite ical handling using the egwical class */
|
||||
|
||||
|
||||
//require_once EGW_SERVER_ROOT.'/icalsrv/inc/infolog/class.bovtodos.inc.php';
|
||||
|
||||
class vcalinfolog extends boinfolog
|
||||
{
|
||||
// introduce auxilliary egwical object
|
||||
var $ei;
|
||||
|
||||
// introduce a worker obj (also accessible via $ei but this is shorter..)
|
||||
var $wkobj;
|
||||
|
||||
function vcalinfolog()
|
||||
{
|
||||
bovtodos::bovtodos(); // call superclass constructor
|
||||
error_log("class: infolog.vcalinfolog DEPRECATED," .
|
||||
"\nplease use in future class: infolog.bovtodos \n now auto delegating ");
|
||||
error_log("warning class: vcalinfolog.vcalinfolog call DEPRECATED," .
|
||||
"\nplease rewrite your code to use egwical class" .
|
||||
"\n now temporary code fix used ");
|
||||
// The longer road, using egwicals cleverness:
|
||||
// $this->ei =& CreateObject('egwical.egwical');
|
||||
// $this->wkobj =& $this->ei->addRsc($this);
|
||||
// or the fast, shortcut, road for knowingly experts only:
|
||||
$this->wkobj =& CreateObject('egwical.boinfolog_vtodos');
|
||||
$this->wkobj->setRsc($this);
|
||||
|
||||
if ($this->wkobj == false){
|
||||
error_log('boical constructor: couldnot add bocal resource to egwical: FATAL');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now implement the compatibility methods, that are all moved to egwical!
|
||||
|
||||
function exportVTODO($_taskID, $_version)
|
||||
{
|
||||
return $this->wkobj->exportVTODO($_taskID, $_version);
|
||||
}
|
||||
|
||||
function importVTODO(&$_vcalData, $_taskID=-1)
|
||||
{
|
||||
return $this->wkobj->importVTODO($_vcalData, $_taskID);
|
||||
}
|
||||
|
||||
|
||||
// function setSupportedFields($_productManufacturer='file', $_productName='')
|
||||
// {
|
||||
// return $this->wkobj->setSupportedFields($_productManufacturer, $_productName);
|
||||
// }
|
||||
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user