Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117758807
tasklist_database_driver.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
21 KB
Referenced Files
None
Subscribers
None
tasklist_database_driver.php
View Options
<?php
/**
* Database driver for the Tasklist plugin
*
* @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/>.
*/
class
tasklist_database_driver
extends
tasklist_driver
{
public
$undelete
=
true
;
// yes, we can
public
$sortable
=
false
;
public
$alarm_types
=
array
(
'DISPLAY'
,
'EMAIL'
);
private
$rc
;
private
$plugin
;
private
$cache
=
array
();
private
$lists
=
array
();
private
$list_ids
=
''
;
private
$db_tasks
=
'tasks'
;
private
$db_lists
=
'tasklists'
;
private
$sequence_tasks
=
'task_ids'
;
private
$sequence_lists
=
'tasklist_ids'
;
/**
* Default constructor
*/
public
function
__construct
(
$plugin
)
{
$this
->
rc
=
$plugin
->
rc
;
$this
->
plugin
=
$plugin
;
// read database config
$this
->
db_lists
=
$this
->
rc
->
config
->
get
(
'db_table_lists'
,
$this
->
db_lists
);
$this
->
db_tasks
=
$this
->
rc
->
config
->
get
(
'db_table_tasks'
,
$this
->
db_tasks
);
$this
->
sequence_lists
=
$this
->
rc
->
config
->
get
(
'db_sequence_lists'
,
$this
->
sequence_lists
);
$this
->
sequence_tasks
=
$this
->
rc
->
config
->
get
(
'db_sequence_tasks'
,
$this
->
sequence_tasks
);
$this
->
_read_lists
();
}
/**
* Read available calendars for the current user and store them internally
*/
private
function
_read_lists
()
{
$hidden
=
array_filter
(
explode
(
','
,
$this
->
rc
->
config
->
get
(
'hidden_tasklists'
,
''
)));
if
(!
empty
(
$this
->
rc
->
user
->
ID
))
{
$list_ids
=
array
();
$result
=
$this
->
rc
->
db
->
query
(
"SELECT *, tasklist_id AS id FROM "
.
$this
->
db_lists
.
"
WHERE user_id=?
ORDER BY CASE WHEN name='INBOX' THEN 0 ELSE 1 END, name"
,
$this
->
rc
->
user
->
ID
);
while
(
$result
&&
(
$arr
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
)))
{
$arr
[
'showalarms'
]
=
intval
(
$arr
[
'showalarms'
]);
$arr
[
'active'
]
=
!
in_array
(
$arr
[
'id'
],
$hidden
);
$arr
[
'name'
]
=
html
::
quote
(
$arr
[
'name'
]);
$arr
[
'editable'
]
=
true
;
$this
->
lists
[
$arr
[
'id'
]]
=
$arr
;
$list_ids
[]
=
$this
->
rc
->
db
->
quote
(
$arr
[
'id'
]);
}
$this
->
list_ids
=
join
(
','
,
$list_ids
);
}
}
/**
* Get a list of available tasks lists from this source
*/
public
function
get_lists
()
{
// attempt to create a default list for this user
if
(
empty
(
$this
->
lists
))
{
if
(
$this
->
create_list
(
array
(
'name'
=>
'Default'
,
'color'
=>
'000000'
)))
$this
->
_read_lists
();
}
return
$this
->
lists
;
}
/**
* Create a new list assigned to the current user
*
* @param array Hash array with list properties
* @return mixed ID of the new list on success, False on error
* @see tasklist_driver::create_list()
*/
public
function
create_list
(
$prop
)
{
$result
=
$this
->
rc
->
db
->
query
(
"INSERT INTO "
.
$this
->
db_lists
.
"
(user_id, name, color, showalarms)
VALUES (?, ?, ?, ?)"
,
$this
->
rc
->
user
->
ID
,
$prop
[
'name'
],
$prop
[
'color'
],
$prop
[
'showalarms'
]?
1
:
0
);
if
(
$result
)
return
$this
->
rc
->
db
->
insert_id
(
$this
->
sequence_lists
);
return
false
;
}
/**
* Update properties of an existing tasklist
*
* @param array Hash array with list properties
* @return boolean True on success, Fales on failure
* @see tasklist_driver::edit_list()
*/
public
function
edit_list
(
$prop
)
{
$query
=
$this
->
rc
->
db
->
query
(
"UPDATE "
.
$this
->
db_lists
.
"
SET name=?, color=?, showalarms=?
WHERE tasklist_id=?
AND user_id=?"
,
$prop
[
'name'
],
$prop
[
'color'
],
$prop
[
'showalarms'
]?
1
:
0
,
$prop
[
'id'
],
$this
->
rc
->
user
->
ID
);
return
$this
->
rc
->
db
->
affected_rows
(
$query
);
}
/**
* Set active/subscribed state of a list
*
* @param array Hash array with list properties
* @return boolean True on success, Fales on failure
* @see tasklist_driver::subscribe_list()
*/
public
function
subscribe_list
(
$prop
)
{
$hidden
=
array_flip
(
explode
(
','
,
$this
->
rc
->
config
->
get
(
'hidden_tasklists'
,
''
)));
if
(
$prop
[
'active'
])
unset
(
$hidden
[
$prop
[
'id'
]]);
else
$hidden
[
$prop
[
'id'
]]
=
1
;
return
$this
->
rc
->
user
->
save_prefs
(
array
(
'hidden_tasklists'
=>
join
(
','
,
array_keys
(
$hidden
))));
}
/**
* Delete the given list with all its contents
*
* @param array Hash array with list properties
* @return boolean True on success, Fales on failure
* @see tasklist_driver::remove_list()
*/
public
function
remove_list
(
$prop
)
{
$list_id
=
$prop
[
'id'
];
if
(
$this
->
lists
[
$list_id
])
{
// delete all tasks linked with this list
$this
->
rc
->
db
->
query
(
"DELETE FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id=?"
,
$lisr_id
);
// delete list record
$query
=
$this
->
rc
->
db
->
query
(
"DELETE FROM "
.
$this
->
db_lists
.
"
WHERE tasklist_id=?
AND user_id=?"
,
$list_id
,
$this
->
rc
->
user
->
ID
);
return
$this
->
rc
->
db
->
affected_rows
(
$query
);
}
return
false
;
}
/**
* Get number of tasks matching the given filter
*
* @param array List of lists to count tasks of
* @return array Hash array with counts grouped by status (all|flagged|today|tomorrow|overdue|nodate)
* @see tasklist_driver::count_tasks()
*/
function
count_tasks
(
$lists
=
null
)
{
if
(
empty
(
$lists
))
$lists
=
array_keys
(
$this
->
lists
);
else
if
(
is_string
(
$lists
))
$lists
=
explode
(
','
,
$lists
);
// only allow to select from lists of this user
$list_ids
=
array_map
(
array
(
$this
->
rc
->
db
,
'quote'
),
array_intersect
(
$lists
,
array_keys
(
$this
->
lists
)));
$today_date
=
new
DateTime
(
'now'
,
$this
->
plugin
->
timezone
);
$today
=
$today_date
->
format
(
'Y-m-d'
);
$tomorrow_date
=
new
DateTime
(
'now + 1 day'
,
$this
->
plugin
->
timezone
);
$tomorrow
=
$tomorrow_date
->
format
(
'Y-m-d'
);
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"SELECT task_id, flagged, date FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id IN (%s)
AND del=0 AND complete<1"
,
join
(
','
,
$list_ids
)
));
$counts
=
array
(
'all'
=>
0
,
'flagged'
=>
0
,
'today'
=>
0
,
'tomorrow'
=>
0
,
'overdue'
=>
0
,
'nodate'
=>
0
);
while
(
$result
&&
(
$rec
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
)))
{
$counts
[
'all'
]++;
if
(
$rec
[
'flagged'
])
$counts
[
'flagged'
]++;
if
(
empty
(
$rec
[
'date'
]))
$counts
[
'nodate'
]++;
else
if
(
$rec
[
'date'
]
==
$today
)
$counts
[
'today'
]++;
else
if
(
$rec
[
'date'
]
==
$tomorrow
)
$counts
[
'tomorrow'
]++;
else
if
(
$rec
[
'date'
]
<
$today
)
$counts
[
'overdue'
]++;
}
return
$counts
;
}
/**
* Get all taks records matching the given filter
*
* @param array Hash array wiht filter criterias
* @param array List of lists to get tasks from
* @return array List of tasks records matchin the criteria
* @see tasklist_driver::list_tasks()
*/
function
list_tasks
(
$filter
,
$lists
=
null
)
{
if
(
empty
(
$lists
))
$lists
=
array_keys
(
$this
->
lists
);
else
if
(
is_string
(
$lists
))
$lists
=
explode
(
','
,
$lists
);
// only allow to select from lists of this user
$list_ids
=
array_map
(
array
(
$this
->
rc
->
db
,
'quote'
),
array_intersect
(
$lists
,
array_keys
(
$this
->
lists
)));
$sql_add
=
''
;
// add filter criteria
if
(
$filter
[
'from'
]
||
(
$filter
[
'mask'
]
&
tasklist
::
FILTER_MASK_TODAY
))
{
$sql_add
.=
' AND (date IS NULL OR date >= ?)'
;
$datefrom
=
$filter
[
'from'
];
}
if
(
$filter
[
'to'
])
{
if
(
$filter
[
'mask'
]
&
tasklist
::
FILTER_MASK_OVERDUE
)
$sql_add
.=
' AND (date IS NOT NULL AND date <= '
.
$this
->
rc
->
db
->
quote
(
$filter
[
'to'
])
.
')'
;
else
$sql_add
.=
' AND (date IS NULL OR date <= '
.
$this
->
rc
->
db
->
quote
(
$filter
[
'to'
])
.
')'
;
}
// special case 'today': also show all events with date before today
if
(
$filter
[
'mask'
]
&
tasklist
::
FILTER_MASK_TODAY
)
{
$datefrom
=
date
(
'Y-m-d'
,
0
);
}
if
(
$filter
[
'mask'
]
&
tasklist
::
FILTER_MASK_NODATE
)
$sql_add
=
' AND date IS NULL'
;
if
(
$filter
[
'mask'
]
&
tasklist
::
FILTER_MASK_COMPLETE
)
$sql_add
.=
' AND complete=1'
;
else
// don't show complete tasks by default
$sql_add
.=
' AND complete<1'
;
if
(
$filter
[
'mask'
]
&
tasklist
::
FILTER_MASK_FLAGGED
)
$sql_add
.=
' AND flagged=1'
;
// compose (slow) SQL query for searching
// FIXME: improve searching using a dedicated col and normalized values
if
(
$filter
[
'search'
])
{
$sql_query
=
array
();
foreach
(
array
(
'title'
,
'description'
,
'organizer'
,
'attendees'
)
as
$col
)
$sql_query
[]
=
$this
->
rc
->
db
->
ilike
(
$col
,
'%'
.
$filter
[
'search'
].
'%'
);
$sql_add
=
'AND ('
.
join
(
' OR '
,
$sql_query
)
.
')'
;
}
$tasks
=
array
();
if
(!
empty
(
$list_ids
))
{
$datecol
=
$this
->
rc
->
db
->
quote_identifier
(
'date'
);
$timecol
=
$this
->
rc
->
db
->
quote_identifier
(
'time'
);
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"SELECT * FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id IN (%s)
AND del=0
%s
ORDER BY parent_id, task_id ASC"
,
join
(
','
,
$list_ids
),
$sql_add
),
$datefrom
);
while
(
$result
&&
(
$rec
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
)))
{
$tasks
[]
=
$this
->
_read_postprocess
(
$rec
);
}
}
return
$tasks
;
}
/**
* Return data of a specific task
*
* @param mixed Hash array with task properties or task UID
* @return array Hash array with task properties or false if not found
*/
public
function
get_task
(
$prop
)
{
if
(
is_string
(
$prop
))
$prop
[
'uid'
]
=
$prop
;
$query_col
=
$prop
[
'id'
]
?
'task_id'
:
'uid'
;
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"SELECT * FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id IN (%s)
AND %s=?
AND del=0"
,
$this
->
list_ids
,
$query_col
),
$prop
[
'id'
]
?
$prop
[
'id'
]
:
$prop
[
'uid'
]
);
if
(
$result
&&
(
$rec
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
)))
{
return
$this
->
_read_postprocess
(
$rec
);
}
return
false
;
}
/**
* Get all decendents of the given task record
*
* @param mixed Hash array with task properties or task UID
* @param boolean True if all childrens children should be fetched
* @return array List of all child task IDs
*/
public
function
get_childs
(
$prop
,
$recursive
=
false
)
{
// resolve UID first
if
(
is_string
(
$prop
))
{
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"SELECT task_id AS id, tasklist_id AS list FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id IN (%s)
AND uid=?"
,
$this
->
list_ids
),
$prop
);
$prop
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
);
}
$childs
=
array
();
$task_ids
=
array
(
$prop
[
'id'
]);
// query for childs (recursively)
while
(!
empty
(
$task_ids
))
{
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"SELECT task_id AS id FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id IN (%s)
AND parent_id IN (%s)
AND del=0"
,
$this
->
list_ids
,
join
(
','
,
array_map
(
array
(
$this
->
rc
->
db
,
'quote'
),
$task_ids
))
));
$task_ids
=
array
();
while
(
$result
&&
(
$rec
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
)))
{
$childs
[]
=
$rec
[
'id'
];
$task_ids
[]
=
$rec
[
'id'
];
}
if
(!
$recursive
)
break
;
}
return
$childs
;
}
/**
* Get a list of pending alarms to be displayed to the user
*
* @param integer Current time (unix timestamp)
* @param mixed List of list IDs to show alarms for (either as array or comma-separated string)
* @return array A list of alarms, each encoded as hash array with task properties
* @see tasklist_driver::pending_alarms()
*/
public
function
pending_alarms
(
$time
,
$lists
=
null
)
{
if
(
empty
(
$lists
))
$lists
=
array_keys
(
$this
->
lists
);
else
if
(
is_string
(
$lists
))
$lists
=
explode
(
','
,
$lists
);
// only allow to select from calendars with activated alarms
$list_ids
=
array
();
foreach
(
$lists
as
$lid
)
{
if
(
$this
->
lists
[
$lid
]
&&
$this
->
lists
[
$lid
][
'showalarms'
])
$list_ids
[]
=
$lid
;
}
$list_ids
=
array_map
(
array
(
$this
->
rc
->
db
,
'quote'
),
$list_ids
);
$alarms
=
array
();
if
(!
empty
(
$list_ids
))
{
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"SELECT * FROM "
.
$this
->
db_tasks
.
"
WHERE tasklist_id IN (%s)
AND notify <= %s AND complete < 1"
,
join
(
','
,
$list_ids
),
$this
->
rc
->
db
->
fromunixtime
(
$time
)
));
while
(
$result
&&
(
$rec
=
$this
->
rc
->
db
->
fetch_assoc
(
$result
)))
$alarms
[]
=
$this
->
_read_postprocess
(
$rec
);
}
return
$alarms
;
}
/**
* Feedback after showing/sending an alarm notification
*
* @see tasklist_driver::dismiss_alarm()
*/
public
function
dismiss_alarm
(
$task_id
,
$snooze
=
0
)
{
// set new notifyat time or unset if not snoozed
$notify_at
=
$snooze
>
0
?
date
(
'Y-m-d H:i:s'
,
time
()
+
$snooze
)
:
null
;
$query
=
$this
->
rc
->
db
->
query
(
sprintf
(
"UPDATE "
.
$this
->
db_tasks
.
"
SET changed=%s, notify=?
WHERE task_id=?
AND tasklist_id IN ("
.
$this
->
list_ids
.
")"
,
$this
->
rc
->
db
->
now
()),
$notify_at
,
$task_id
);
return
$this
->
rc
->
db
->
affected_rows
(
$query
);
}
/**
* Map some internal database values to match the generic "API"
*/
private
function
_read_postprocess
(
$rec
)
{
$rec
[
'id'
]
=
$rec
[
'task_id'
];
$rec
[
'list'
]
=
$rec
[
'tasklist_id'
];
$rec
[
'changed'
]
=
new
DateTime
(
$rec
[
'changed'
]);
$rec
[
'tags'
]
=
array_filter
(
explode
(
','
,
$rec
[
'tags'
]));
if
(!
$rec
[
'parent_id'
])
unset
(
$rec
[
'parent_id'
]);
unset
(
$rec
[
'task_id'
],
$rec
[
'tasklist_id'
],
$rec
[
'created'
]);
return
$rec
;
}
/**
* Add a single task to the database
*
* @param array Hash array with task properties (see header of this file)
* @return mixed New event ID on success, False on error
* @see tasklist_driver::create_task()
*/
public
function
create_task
(
$prop
)
{
// check list permissions
$list_id
=
$prop
[
'list'
]
?
$prop
[
'list'
]
:
reset
(
array_keys
(
$this
->
lists
));
if
(!
$this
->
lists
[
$list_id
]
||
$this
->
lists
[
$list_id
][
'readonly'
])
return
false
;
foreach
(
array
(
'parent_id'
,
'date'
,
'time'
,
'startdate'
,
'starttime'
,
'alarms'
)
as
$col
)
{
if
(
empty
(
$prop
[
$col
]))
$prop
[
$col
]
=
null
;
}
$notify_at
=
$this
->
_get_notification
(
$prop
);
$result
=
$this
->
rc
->
db
->
query
(
sprintf
(
"INSERT INTO "
.
$this
->
db_tasks
.
"
(tasklist_id, uid, parent_id, created, changed, title, date, time, startdate, starttime, description, tags, alarms, notify)
VALUES (?, ?, ?, %s, %s, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
,
$this
->
rc
->
db
->
now
(),
$this
->
rc
->
db
->
now
()
),
$list_id
,
$prop
[
'uid'
],
$prop
[
'parent_id'
],
$prop
[
'title'
],
$prop
[
'date'
],
$prop
[
'time'
],
$prop
[
'startdate'
],
$prop
[
'starttime'
],
strval
(
$prop
[
'description'
]),
join
(
','
,
(
array
)
$prop
[
'tags'
]),
$prop
[
'alarms'
],
$notify_at
);
if
(
$result
)
return
$this
->
rc
->
db
->
insert_id
(
$this
->
sequence_tasks
);
return
false
;
}
/**
* Update an task entry with the given data
*
* @param array Hash array with task properties
* @return boolean True on success, False on error
* @see tasklist_driver::edit_task()
*/
public
function
edit_task
(
$prop
)
{
$sql_set
=
array
();
foreach
(
array
(
'title'
,
'description'
,
'flagged'
,
'complete'
)
as
$col
)
{
if
(
isset
(
$prop
[
$col
]))
$sql_set
[]
=
$this
->
rc
->
db
->
quote_identifier
(
$col
)
.
'='
.
$this
->
rc
->
db
->
quote
(
$prop
[
$col
]);
}
foreach
(
array
(
'parent_id'
,
'date'
,
'time'
,
'startdate'
,
'starttime'
,
'alarms'
)
as
$col
)
{
if
(
isset
(
$prop
[
$col
]))
$sql_set
[]
=
$this
->
rc
->
db
->
quote_identifier
(
$col
)
.
'='
.
(
empty
(
$prop
[
$col
])
?
'NULL'
:
$this
->
rc
->
db
->
quote
(
$prop
[
$col
]));
}
if
(
isset
(
$prop
[
'tags'
]))
$sql_set
[]
=
$this
->
rc
->
db
->
quote_identifier
(
'tags'
)
.
'='
.
$this
->
rc
->
db
->
quote
(
join
(
','
,
(
array
)
$prop
[
'tags'
]));
if
(
isset
(
$prop
[
'date'
])
||
isset
(
$prop
[
'time'
])
||
isset
(
$prop
[
'alarms'
]))
{
$notify_at
=
$this
->
_get_notification
(
$prop
);
$sql_set
[]
=
$this
->
rc
->
db
->
quote_identifier
(
'notify'
)
.
'='
.
(
empty
(
$notify_at
)
?
'NULL'
:
$this
->
rc
->
db
->
quote
(
$notify_at
));
}
// moved from another list
if
(
$prop
[
'_fromlist'
]
&&
(
$newlist
=
$prop
[
'list'
]))
{
$sql_set
[]
=
'tasklist_id='
.
$this
->
rc
->
db
->
quote
(
$newlist
);
}
$query
=
$this
->
rc
->
db
->
query
(
sprintf
(
"UPDATE "
.
$this
->
db_tasks
.
"
SET changed=%s %s
WHERE task_id=?
AND tasklist_id IN (%s)"
,
$this
->
rc
->
db
->
now
(),
(
$sql_set
?
', '
.
join
(
', '
,
$sql_set
)
:
''
),
$this
->
list_ids
),
$prop
[
'id'
]
);
return
$this
->
rc
->
db
->
affected_rows
(
$query
);
}
/**
* Move a single task to another list
*
* @param array Hash array with task properties:
* @return boolean True on success, False on error
* @see tasklist_driver::move_task()
*/
public
function
move_task
(
$prop
)
{
return
$this
->
edit_task
(
$prop
);
}
/**
* Remove a single task from the database
*
* @param array Hash array with task properties
* @param boolean Remove record irreversible
* @return boolean True on success, False on error
* @see tasklist_driver::delete_task()
*/
public
function
delete_task
(
$prop
,
$force
=
true
)
{
$task_id
=
$prop
[
'id'
];
if
(
$task_id
&&
$force
)
{
$query
=
$this
->
rc
->
db
->
query
(
"DELETE FROM "
.
$this
->
db_tasks
.
"
WHERE task_id=?
AND tasklist_id IN ("
.
$this
->
list_ids
.
")"
,
$task_id
);
}
else
if
(
$task_id
)
{
$query
=
$this
->
rc
->
db
->
query
(
sprintf
(
"UPDATE "
.
$this
->
db_tasks
.
"
SET changed=%s, del=1
WHERE task_id=?
AND tasklist_id IN (%s)"
,
$this
->
rc
->
db
->
now
(),
$this
->
list_ids
),
$task_id
);
}
return
$this
->
rc
->
db
->
affected_rows
(
$query
);
}
/**
* Restores a single deleted task (if supported)
*
* @param array Hash array with task properties
* @return boolean True on success, False on error
* @see tasklist_driver::undelete_task()
*/
public
function
undelete_task
(
$prop
)
{
$query
=
$this
->
rc
->
db
->
query
(
sprintf
(
"UPDATE "
.
$this
->
db_tasks
.
"
SET changed=%s, del=0
WHERE task_id=?
AND tasklist_id IN (%s)"
,
$this
->
rc
->
db
->
now
(),
$this
->
list_ids
),
$prop
[
'id'
]
);
return
$this
->
rc
->
db
->
affected_rows
(
$query
);
}
/**
* Compute absolute time to notify the user
*/
private
function
_get_notification
(
$task
)
{
if
(
$task
[
'alarms'
]
&&
$task
[
'complete'
]
<
1
||
strpos
(
$task
[
'alarms'
],
'@'
)
!==
false
)
{
$alarm
=
calendarlibcalendaring
::
get_next_alarm
(
$task
);
if
(
$alarm
[
'time'
]
&&
$alarm
[
'action'
]
==
'DISPLAY'
)
return
date
(
'Y-m-d H:i:s'
,
$alarm
[
'time'
]);
}
return
null
;
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Apr 4 2026, 9:58 AM (4 w, 2 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
9a/01/57d157f66d0207633570b5bb1bb9
Default Alt Text
tasklist_database_driver.php (21 KB)
Attached To
Mode
rRPK roundcubemail-plugins-kolab
Attached
Detach File
Event Timeline