Changeset View
Changeset View
Standalone View
Standalone View
plugins/tasklist/drivers/database/tasklist_database_driver.php
Show First 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | class tasklist_database_driver extends tasklist_driver | ||||
public function create_list(&$prop) | public function create_list(&$prop) | ||||
{ | { | ||||
$result = $this->rc->db->query( | $result = $this->rc->db->query( | ||||
"INSERT INTO " . $this->db_lists | "INSERT INTO " . $this->db_lists | ||||
. " (`user_id`, `name`, `color`, `showalarms`)" | . " (`user_id`, `name`, `color`, `showalarms`)" | ||||
. " VALUES (?, ?, ?, ?)", | . " VALUES (?, ?, ?, ?)", | ||||
$this->rc->user->ID, | $this->rc->user->ID, | ||||
strval($prop['name']), | strval($prop['name']), | ||||
strval($prop['color']), | isset($prop['color']) ? strval($prop['color']) : '', | ||||
$prop['showalarms'] ? 1 : 0 | !empty($prop['showalarms']) ? 1 : 0 | ||||
); | ); | ||||
if ($result) { | if ($result) { | ||||
$prop['rights'] = 'lrswikxtea'; | $prop['rights'] = 'lrswikxtea'; | ||||
return $this->rc->db->insert_id($this->db_lists); | return $this->rc->db->insert_id($this->db_lists); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Update properties of an existing tasklist | * Update properties of an existing tasklist | ||||
* | * | ||||
* @param array Hash array with list properties | * @param array Hash array with list properties | ||||
* @return boolean True on success, Fales on failure | * @return boolean True on success, Fales on failure | ||||
* @see tasklist_driver::edit_list() | * @see tasklist_driver::edit_list() | ||||
*/ | */ | ||||
public function edit_list(&$prop) | public function edit_list(&$prop) | ||||
{ | { | ||||
$query = $this->rc->db->query( | $query = $this->rc->db->query( | ||||
"UPDATE " . $this->db_lists . " SET `name` = ?, `color` = ?, `showalarms` = ?" | "UPDATE " . $this->db_lists . " SET `name` = ?, `color` = ?, `showalarms` = ?" | ||||
. " WHERE `tasklist_id` = ? AND `user_id` = ?", | . " WHERE `tasklist_id` = ? AND `user_id` = ?", | ||||
strval($prop['name']), | strval($prop['name']), | ||||
strval($prop['color']), | isset($prop['color']) ? strval($prop['color']) : '', | ||||
$prop['showalarms'] ? 1 : 0, | !empty($prop['showalarms']) ? 1 : 0, | ||||
$prop['id'], | $prop['id'], | ||||
$this->rc->user->ID | $this->rc->user->ID | ||||
); | ); | ||||
return $this->rc->db->affected_rows($query); | return $this->rc->db->affected_rows($query); | ||||
} | } | ||||
/** | /** | ||||
* Set active/subscribed state of a list | * Set active/subscribed state of a list | ||||
* | * | ||||
* @param array Hash array with list properties | * @param array Hash array with list properties | ||||
* @return boolean True on success, Fales on failure | * @return boolean True on success, Fales on failure | ||||
* @see tasklist_driver::subscribe_list() | * @see tasklist_driver::subscribe_list() | ||||
*/ | */ | ||||
public function subscribe_list($prop) | public function subscribe_list($prop) | ||||
{ | { | ||||
$hidden = array_flip(explode(',', $this->rc->config->get('hidden_tasklists', ''))); | $hidden = array_flip(explode(',', $this->rc->config->get('hidden_tasklists', ''))); | ||||
if ($prop['active']) { | if (!empty($prop['active'])) { | ||||
unset($hidden[$prop['id']]); | unset($hidden[$prop['id']]); | ||||
} | } | ||||
else { | else { | ||||
$hidden[$prop['id']] = 1; | $hidden[$prop['id']] = 1; | ||||
} | } | ||||
return $this->rc->user->save_prefs(array('hidden_tasklists' => join(',', array_keys($hidden)))); | return $this->rc->user->save_prefs(array('hidden_tasklists' => join(',', array_keys($hidden)))); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | function list_tasks($filter, $lists = null) | ||||
$lists = explode(',', (string) $lists); | $lists = explode(',', (string) $lists); | ||||
} | } | ||||
// only allow to select from lists of this user | // 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))); | $list_ids = array_map(array($this->rc->db, 'quote'), array_intersect($lists, array_keys($this->lists))); | ||||
$sql_add = ''; | $sql_add = ''; | ||||
// add filter criteria | // add filter criteria | ||||
if ($filter['from'] || ($filter['mask'] & tasklist::FILTER_MASK_TODAY)) { | if ($filter) { | ||||
$sql_add .= " AND (`date` IS NULL OR `date` >= ?)"; | if (!empty($filter['from']) || ($filter['mask'] & tasklist::FILTER_MASK_TODAY)) { | ||||
$datefrom = $filter['from']; | $sql_add .= " AND (`date` IS NULL OR `date` >= " . $this->rc->db->quote($filter['from']) . ")"; | ||||
} | } | ||||
if ($filter['to']) { | |||||
if (!empty($filter['to'])) { | |||||
if ($filter['mask'] & tasklist::FILTER_MASK_OVERDUE) { | if ($filter['mask'] & tasklist::FILTER_MASK_OVERDUE) { | ||||
$sql_add .= " AND (`date` IS NOT NULL AND `date` <= " . $this->rc->db->quote($filter['to']) . ")"; | $sql_add .= " AND (`date` IS NOT NULL AND `date` <= " . $this->rc->db->quote($filter['to']) . ")"; | ||||
} | } | ||||
else { | else { | ||||
$sql_add .= " AND (`date` IS NULL OR `date` <= " . $this->rc->db->quote($filter['to']) . ")"; | $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) { | if ($filter['mask'] & tasklist::FILTER_MASK_NODATE) { | ||||
$sql_add = " AND `date` IS NULL"; | $sql_add = " AND `date` IS NULL"; | ||||
} | } | ||||
if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE) { | if ($filter['mask'] & tasklist::FILTER_MASK_COMPLETE) { | ||||
$sql_add .= " AND " . self::IS_COMPLETE_SQL; | $sql_add .= " AND " . self::IS_COMPLETE_SQL; | ||||
} | } | ||||
else if (empty($filter['since'])) { | else if (empty($filter['since'])) { | ||||
// don't show complete tasks by default | // don't show complete tasks by default | ||||
$sql_add .= " AND NOT " . self::IS_COMPLETE_SQL; | $sql_add .= " AND NOT " . self::IS_COMPLETE_SQL; | ||||
} | } | ||||
if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED) { | if ($filter['mask'] & tasklist::FILTER_MASK_FLAGGED) { | ||||
$sql_add .= " AND `flagged` = 1"; | $sql_add .= " AND `flagged` = 1"; | ||||
} | } | ||||
// compose (slow) SQL query for searching | // compose (slow) SQL query for searching | ||||
// FIXME: improve searching using a dedicated col and normalized values | // FIXME: improve searching using a dedicated col and normalized values | ||||
if ($filter['search']) { | if ($filter['search']) { | ||||
$sql_query = array(); | $sql_query = array(); | ||||
foreach (array('title', 'description', 'organizer', 'attendees') as $col) { | foreach (array('title', 'description', 'organizer', 'attendees') as $col) { | ||||
$sql_query[] = $this->rc->db->ilike($col, '%' . $filter['search'] . '%'); | $sql_query[] = $this->rc->db->ilike($col, '%' . $filter['search'] . '%'); | ||||
} | } | ||||
$sql_add = " AND (" . join(" OR ", $sql_query) . ")"; | $sql_add = " AND (" . join(" OR ", $sql_query) . ")"; | ||||
} | } | ||||
if ($filter['since'] && is_numeric($filter['since'])) { | if (!empty($filter['since']) && is_numeric($filter['since'])) { | ||||
$sql_add .= " AND `changed` >= " . $this->rc->db->quote(date('Y-m-d H:i:s', $filter['since'])); | $sql_add .= " AND `changed` >= " . $this->rc->db->quote(date('Y-m-d H:i:s', $filter['since'])); | ||||
} | } | ||||
if ($filter['uid']) { | if (!empty($filter['uid'])) { | ||||
$sql_add .= " AND `uid` IN (" . implode(',', array_map(array($this->rc->db, 'quote'), $filter['uid'])) . ")"; | $sql_add .= " AND `uid` IN (" . implode(',', array_map(array($this->rc->db, 'quote'), $filter['uid'])) . ")"; | ||||
} | } | ||||
} | |||||
$tasks = array(); | $tasks = array(); | ||||
if (!empty($list_ids)) { | if (!empty($list_ids)) { | ||||
$result = $this->rc->db->query("SELECT * FROM " . $this->db_tasks | $result = $this->rc->db->query("SELECT * FROM " . $this->db_tasks | ||||
. " WHERE `tasklist_id` IN (" . join(',', $list_ids) . ")" | . " WHERE `tasklist_id` IN (" . join(',', $list_ids) . ")" | ||||
. " AND `del` = 0" . $sql_add | . " AND `del` = 0" . $sql_add | ||||
. " ORDER BY `parent_id`, `task_id` ASC", | . " ORDER BY `parent_id`, `task_id` ASC" | ||||
$datefrom | |||||
); | ); | ||||
while ($result && ($rec = $this->rc->db->fetch_assoc($result))) { | while ($result && ($rec = $this->rc->db->fetch_assoc($result))) { | ||||
$tasks[] = $this->_read_postprocess($rec); | $tasks[] = $this->_read_postprocess($rec); | ||||
} | } | ||||
} | } | ||||
return $tasks; | return $tasks; | ||||
Show All 9 Lines | class tasklist_database_driver extends tasklist_driver | ||||
* @return array Hash array with task properties or false if not found | * @return array Hash array with task properties or false if not found | ||||
*/ | */ | ||||
public function get_task($prop, $filter = 0) | public function get_task($prop, $filter = 0) | ||||
{ | { | ||||
if (is_string($prop)) { | if (is_string($prop)) { | ||||
$prop['uid'] = $prop; | $prop['uid'] = $prop; | ||||
} | } | ||||
$query_col = $prop['id'] ? 'task_id' : 'uid'; | $query_col = !empty($prop['id']) ? 'task_id' : 'uid'; | ||||
$result = $this->rc->db->query("SELECT * FROM " . $this->db_tasks | $result = $this->rc->db->query("SELECT * FROM " . $this->db_tasks | ||||
. " WHERE `tasklist_id` IN (" . $this->list_ids . ")" | . " WHERE `tasklist_id` IN (" . $this->list_ids . ")" | ||||
. " AND `$query_col` = ? AND `del` = 0", | . " AND `$query_col` = ? AND `del` = 0", | ||||
$prop['id'] ? $prop['id'] : $prop['uid'] | !empty($prop['id']) ? $prop['id'] : $prop['uid'] | ||||
); | ); | ||||
if ($result && ($rec = $this->rc->db->fetch_assoc($result))) { | if ($result && ($rec = $this->rc->db->fetch_assoc($result))) { | ||||
return $this->_read_postprocess($rec); | return $this->_read_postprocess($rec); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 160 Lines • ▼ Show 20 Lines | class tasklist_database_driver extends tasklist_driver | ||||
* @param array Hash array with task properties (see header of this file) | * @param array Hash array with task properties (see header of this file) | ||||
* | * | ||||
* @return mixed New event ID on success, False on error | * @return mixed New event ID on success, False on error | ||||
* @see tasklist_driver::create_task() | * @see tasklist_driver::create_task() | ||||
*/ | */ | ||||
public function create_task($prop) | public function create_task($prop) | ||||
{ | { | ||||
// check list permissions | // check list permissions | ||||
$list_id = $prop['list'] ? $prop['list'] : reset(array_keys($this->lists)); | $list_id = !empty($prop['list']) ? $prop['list'] : reset(array_keys($this->lists)); | ||||
if (!$this->lists[$list_id] || $this->lists[$list_id]['readonly']) { | if (empty($this->lists[$list_id]) || !empty($this->lists[$list_id]['readonly'])) { | ||||
return false; | return false; | ||||
} | } | ||||
if (is_array($prop['valarms'])) { | if (!empty($prop['valarms'])) { | ||||
$prop['alarms'] = $this->serialize_alarms($prop['valarms']); | $prop['alarms'] = $this->serialize_alarms($prop['valarms']); | ||||
} | } | ||||
if (is_array($prop['recurrence'])) { | if (!empty($prop['recurrence'])) { | ||||
$prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']); | $prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']); | ||||
} | } | ||||
if (array_key_exists('complete', $prop)) { | if (array_key_exists('complete', $prop)) { | ||||
$prop['complete'] = number_format($prop['complete'], 2, '.', ''); | $prop['complete'] = number_format($prop['complete'], 2, '.', ''); | ||||
} | } | ||||
foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) { | foreach (array('parent_id', 'date', 'time', 'startdate', 'starttime', 'alarms', 'recurrence', 'status') as $col) { | ||||
if (empty($prop[$col])) { | if (empty($prop[$col])) { | ||||
Show All 12 Lines | public function create_task($prop) | ||||
$list_id, | $list_id, | ||||
$prop['uid'], | $prop['uid'], | ||||
$prop['parent_id'], | $prop['parent_id'], | ||||
$prop['title'], | $prop['title'], | ||||
$prop['date'], | $prop['date'], | ||||
$prop['time'], | $prop['time'], | ||||
$prop['startdate'], | $prop['startdate'], | ||||
$prop['starttime'], | $prop['starttime'], | ||||
strval($prop['description']), | isset($prop['description']) ? strval($prop['description']) : '', | ||||
join(',', (array)$prop['tags']), | !empty($prop['tags']) ? join(',', (array)$prop['tags']) : '', | ||||
$prop['flagged'] ? 1 : 0, | !empty($prop['flagged']) ? 1 : 0, | ||||
$prop['complete'] ?: 0, | !empty($prop['complete']) ?: 0, | ||||
strval($prop['status']), | strval($prop['status']), | ||||
$prop['alarms'], | isset($prop['alarms']) ? $prop['alarms'] : '', | ||||
$prop['recurrence'], | isset($prop['recurrence']) ? $prop['recurrence'] : '', | ||||
$notify_at | $notify_at | ||||
); | ); | ||||
if ($result) { | if ($result) { | ||||
return $this->rc->db->insert_id($this->db_tasks); | return $this->rc->db->insert_id($this->db_tasks); | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Update an task entry with the given data | * Update an task entry with the given data | ||||
* | * | ||||
* @param array Hash array with task properties | * @param array Hash array with task properties | ||||
* | * | ||||
* @return boolean True on success, False on error | * @return boolean True on success, False on error | ||||
* @see tasklist_driver::edit_task() | * @see tasklist_driver::edit_task() | ||||
*/ | */ | ||||
public function edit_task($prop) | public function edit_task($prop) | ||||
{ | { | ||||
if (is_array($prop['valarms'])) { | if (isset($prop['valarms'])) { | ||||
$prop['alarms'] = $this->serialize_alarms($prop['valarms']); | $prop['alarms'] = $this->serialize_alarms($prop['valarms']); | ||||
} | } | ||||
if (is_array($prop['recurrence'])) { | if (isset($prop['recurrence'])) { | ||||
$prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']); | $prop['recurrence'] = $this->serialize_recurrence($prop['recurrence']); | ||||
} | } | ||||
if (array_key_exists('complete', $prop)) { | if (array_key_exists('complete', $prop)) { | ||||
$prop['complete'] = number_format($prop['complete'], 2, '.', ''); | $prop['complete'] = number_format($prop['complete'], 2, '.', ''); | ||||
} | } | ||||
$sql_set = array(); | $sql_set = array(); | ||||
foreach (array('title', 'description', 'flagged', 'complete') as $col) { | foreach (array('title', 'description', 'flagged', 'complete') as $col) { | ||||
Show All 14 Lines | public function edit_task($prop) | ||||
} | } | ||||
if (isset($prop['date']) || isset($prop['time']) || isset($prop['alarms'])) { | if (isset($prop['date']) || isset($prop['time']) || isset($prop['alarms'])) { | ||||
$notify_at = $this->_get_notification($prop); | $notify_at = $this->_get_notification($prop); | ||||
$sql_set[] = $this->rc->db->quote_identifier('notify') . '=' . (empty($notify_at) ? 'NULL' : $this->rc->db->quote($notify_at)); | $sql_set[] = $this->rc->db->quote_identifier('notify') . '=' . (empty($notify_at) ? 'NULL' : $this->rc->db->quote($notify_at)); | ||||
} | } | ||||
// moved from another list | // moved from another list | ||||
if ($prop['_fromlist'] && ($newlist = $prop['list'])) { | if (!empty($prop['_fromlist']) && ($newlist = $prop['list'])) { | ||||
$sql_set[] = $this->rc->db->quote_identifier('tasklist_id') . '=' . $this->rc->db->quote($newlist); | $sql_set[] = $this->rc->db->quote_identifier('tasklist_id') . '=' . $this->rc->db->quote($newlist); | ||||
} | } | ||||
$result = $this->rc->db->query("UPDATE " . $this->db_tasks | $result = $this->rc->db->query("UPDATE " . $this->db_tasks | ||||
. " SET `changed` = " . $this->rc->db->now() . ($sql_set ? ', ' . join(', ', $sql_set) : '') | . " SET `changed` = " . $this->rc->db->now() . ($sql_set ? ', ' . join(', ', $sql_set) : '') | ||||
. " WHERE `task_id` = ? AND `tasklist_id` IN (" . $this->list_ids . ")", | . " WHERE `task_id` = ? AND `tasklist_id` IN (" . $this->list_ids . ")", | ||||
$prop['id'] | $prop['id'] | ||||
); | ); | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | public function undelete_task($prop) | ||||
return $this->rc->db->affected_rows($result); | return $this->rc->db->affected_rows($result); | ||||
} | } | ||||
/** | /** | ||||
* Compute absolute time to notify the user | * Compute absolute time to notify the user | ||||
*/ | */ | ||||
private function _get_notification($task) | private function _get_notification($task) | ||||
{ | { | ||||
if ($task['valarms'] && !$this->is_complete($task)) { | if (!empty($task['valarms']) && !$this->is_complete($task)) { | ||||
$alarm = libcalendaring::get_next_alarm($task, 'task'); | $alarm = libcalendaring::get_next_alarm($task, 'task'); | ||||
if ($alarm['time'] && in_array($alarm['action'], $this->alarm_types)) { | if (!empty($alarm['time']) && in_array($alarm['action'], $this->alarm_types)) { | ||||
return date('Y-m-d H:i:s', $alarm['time']); | return date('Y-m-d H:i:s', $alarm['time']); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Helper method to serialize the list of alarms into a string | * Helper method to serialize the list of alarms into a string | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 101 Lines • Show Last 20 Lines |