Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F6063444
tasklist_database_driver.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
26 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
{
const
IS_COMPLETE_SQL
=
"(status='COMPLETED' OR (complete=1 AND status=''))"
;
public
$undelete
=
true
;
// yes, we can
public
$sortable
=
false
;
public
$alarm_types
=
array
(
'DISPLAY'
);
private
$rc
;
private
$plugin
;
private
$lists
=
array
();
private
$list_ids
=
''
;
private
$tags
=
array
();
private
$db_tasks
=
'tasks'
;
private
$db_lists
=
'tasklists'
;
/**
* Default constructor
*/
public
function
__construct
(
$plugin
)
{
$this
->
rc
=
$plugin
->
rc
;
$this
->
plugin
=
$plugin
;
// read database config
$db
=
$this
->
rc
->
get_dbh
();
$this
->
db_lists
=
$this
->
rc
->
config
->
get
(
'db_table_lists'
,
$db
->
table_name
(
$this
->
db_lists
));
$this
->
db_tasks
=
$this
->
rc
->
config
->
get
(
'db_table_tasks'
,
$db
->
table_name
(
$this
->
db_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
[
'listname'
]
=
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
))
{
$prop
=
array
(
'name'
=>
'Default'
,
'color'
=>
'000000'
);
if
(
$this
->
create_list
(
$prop
))
$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
,
strval
(
$prop
[
'name'
]),
strval
(
$prop
[
'color'
]),
$prop
[
'showalarms'
]?
1
:
0
);
if
(
$result
)
return
$this
->
rc
->
db
->
insert_id
(
$this
->
db_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=?"
,
$list_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
;
}
/**
* Search for shared or otherwise not listed tasklists the user has access
*
* @param string Search string
* @param string Section/source to search
* @return array List of tasklists
*/
public
function
search_lists
(
$query
,
$source
)
{
return
array
();
}
/**
* Get a list of tags to assign tasks to
*
* @return array List of tags
*/
public
function
get_tags
()
{
return
array_values
(
array_unique
(
$this
->
tags
,
SORT_STRING
));
}
/**
* 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 NOT "
.
self
::
IS_COMPLETE_SQL
,
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 '
.
self
::
IS_COMPLETE_SQL
;
else
if
(
empty
(
$filter
[
'since'
]))
// don't show complete tasks by default
$sql_add
.=
' AND NOT '
.
self
::
IS_COMPLETE_SQL
;
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
)
.
')'
;
}
if
(
$filter
[
'since'
]
&&
is_numeric
(
$filter
[
'since'
]))
{
$sql_add
.=
' AND changed >= '
.
$this
->
rc
->
db
->
quote
(
date
(
'Y-m-d H:i:s'
,
$filter
[
'since'
]));
}
$tasks
=
array
();
if
(!
empty
(
$list_ids
))
{
$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 NOT "
.
self
::
IS_COMPLETE_SQL
,
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
);
}
/**
* Remove alarm dismissal or snooze state
*
* @param string Task identifier
*/
public
function
clear_alarms
(
$id
)
{
// Nothing to do here. Alarms are reset in edit_task()
}
/**
* 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'
]);
// decode serialized alarms
if
(
$rec
[
'alarms'
])
{
$rec
[
'valarms'
]
=
$this
->
unserialize_alarms
(
$rec
[
'alarms'
]);
unset
(
$rec
[
'alarms'
]);
}
// decode serialze recurrence rules
if
(
$rec
[
'recurrence'
])
{
$rec
[
'recurrence'
]
=
$this
->
unserialize_recurrence
(
$rec
[
'recurrence'
]);
}
if
(!
empty
(
$rec
[
'tags'
]))
{
$this
->
tags
=
array_merge
(
$this
->
tags
,
(
array
)
$rec
[
'tags'
]);
}
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
;
if
(
is_array
(
$prop
[
'valarms'
]))
{
$prop
[
'alarms'
]
=
$this
->
serialize_alarms
(
$prop
[
'valarms'
]);
}
if
(
is_array
(
$prop
[
'recurrence'
]))
{
$prop
[
'recurrence'
]
=
$this
->
serialize_recurrence
(
$prop
[
'recurrence'
]);
}
foreach
(
array
(
'parent_id'
,
'date'
,
'time'
,
'startdate'
,
'starttime'
,
'alarms'
,
'recurrence'
,
'status'
)
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, flagged, complete, status, alarms, recurrence, 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
[
'flagged'
]
?
1
:
0
,
intval
(
$prop
[
'complete'
]),
$prop
[
'status'
],
$prop
[
'alarms'
],
$prop
[
'recurrence'
],
$notify_at
);
if
(
$result
)
return
$this
->
rc
->
db
->
insert_id
(
$this
->
db_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
)
{
if
(
is_array
(
$prop
[
'valarms'
]))
{
$prop
[
'alarms'
]
=
$this
->
serialize_alarms
(
$prop
[
'valarms'
]);
}
if
(
is_array
(
$prop
[
'recurrence'
]))
{
$prop
[
'recurrence'
]
=
$this
->
serialize_recurrence
(
$prop
[
'recurrence'
]);
}
$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'
,
'recurrence'
,
'status'
)
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
[
'valarms'
]
&&
!
$this
->
is_complete
(
$task
))
{
$alarm
=
libcalendaring
::
get_next_alarm
(
$task
,
'task'
);
if
(
$alarm
[
'time'
]
&&
in_array
(
$alarm
[
'action'
],
$this
->
alarm_types
))
return
date
(
'Y-m-d H:i:s'
,
$alarm
[
'time'
]);
}
return
null
;
}
/**
* Helper method to serialize the list of alarms into a string
*/
private
function
serialize_alarms
(
$valarms
)
{
foreach
((
array
)
$valarms
as
$i
=>
$alarm
)
{
if
(
$alarm
[
'trigger'
]
instanceof
DateTime
)
{
$valarms
[
$i
][
'trigger'
]
=
'@'
.
$alarm
[
'trigger'
]->
format
(
'c'
);
}
}
return
$valarms
?
json_encode
(
$valarms
)
:
null
;
}
/**
* Helper method to decode a serialized list of alarms
*/
private
function
unserialize_alarms
(
$alarms
)
{
// decode json serialized alarms
if
(
$alarms
&&
$alarms
[
0
]
==
'['
)
{
$valarms
=
json_decode
(
$alarms
,
true
);
foreach
(
$valarms
as
$i
=>
$alarm
)
{
if
(
$alarm
[
'trigger'
][
0
]
==
'@'
)
{
try
{
$valarms
[
$i
][
'trigger'
]
=
new
DateTime
(
substr
(
$alarm
[
'trigger'
],
1
));
}
catch
(
Exception
$e
)
{
unset
(
$valarms
[
$i
]);
}
}
}
}
// convert legacy alarms data
else
if
(
strlen
(
$alarms
))
{
list
(
$trigger
,
$action
)
=
explode
(
':'
,
$alarms
,
2
);
if
(
$trigger
=
libcalendaring
::
parse_alaram_value
(
$trigger
))
{
$valarms
=
array
(
array
(
'action'
=>
$action
,
'trigger'
=>
$trigger
[
3
]
?:
$trigger
[
0
]));
}
}
return
$valarms
;
}
/**
* Helper method to serialize task recurrence properties
*/
private
function
serialize_recurrence
(
$recurrence
)
{
foreach
((
array
)
$recurrence
as
$k
=>
$val
)
{
if
(
$val
instanceof
DateTime
)
{
$recurrence
[
$k
]
=
'@'
.
$val
->
format
(
'c'
);
}
}
return
$recurrence
?
json_encode
(
$recurrence
)
:
null
;
}
/**
* Helper method to decode a serialized task recurrence struct
*/
private
function
unserialize_recurrence
(
$ser
)
{
if
(
strlen
(
$ser
))
{
$recurrence
=
json_decode
(
$ser
,
true
);
foreach
((
array
)
$recurrence
as
$k
=>
$val
)
{
if
(
$val
[
0
]
==
'@'
)
{
try
{
$recurrence
[
$k
]
=
new
DateTime
(
substr
(
$val
,
1
));
}
catch
(
Exception
$e
)
{
unset
(
$recurrence
[
$k
]);
}
}
}
}
else
{
$recurrence
=
''
;
}
return
$recurrence
;
}
/**
* Handler for user_delete plugin hook
*/
public
function
user_delete
(
$args
)
{
$db
=
$this
->
rc
->
db
;
$list_ids
=
array
();
$lists
=
$db
->
query
(
"SELECT tasklist_id FROM "
.
$this
->
db_lists
.
" WHERE user_id=?"
,
$args
[
'user'
]->
ID
);
while
(
$row
=
$db
->
fetch_assoc
(
$lists
))
{
$list_ids
[]
=
$row
[
'tasklist_id'
];
}
if
(!
empty
(
$list_ids
))
{
foreach
(
array
(
$this
->
db_tasks
,
$this
->
db_lists
)
as
$table
)
{
$db
->
query
(
sprintf
(
"DELETE FROM $table WHERE tasklist_id IN (%s)"
,
join
(
','
,
$list_ids
)));
}
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Fri, May 22, 4:06 AM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
780129
Default Alt Text
tasklist_database_driver.php (26 KB)
Attached To
Mode
R14 roundcubemail-plugins-kolab
Attached
Detach File
Event Timeline
Log In to Comment