From 28d45e28cb850b67c32115e52d314c06470f61e2 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Fri, 20 Oct 2017 16:31:41 +0200 Subject: [PATCH] move info_cc (email adddresses) to egw_infolog_users table --- infolog/inc/class.infolog_bo.inc.php | 3 +- infolog/inc/class.infolog_so.inc.php | 51 +++++++++++--- infolog/setup/setup.inc.php | 17 ++--- infolog/setup/tables_current.inc.php | 6 +- infolog/setup/tables_update.inc.php | 99 ++++++++++++++++++++++++++-- 5 files changed, 143 insertions(+), 33 deletions(-) diff --git a/infolog/inc/class.infolog_bo.inc.php b/infolog/inc/class.infolog_bo.inc.php index 49d8825c31..799889281f 100644 --- a/infolog/inc/class.infolog_bo.inc.php +++ b/infolog/inc/class.infolog_bo.inc.php @@ -6,9 +6,8 @@ * @author Ralf Becker * @author Joerg Lehrke * @package infolog - * @copyright (c) 2003-16 by Ralf Becker + * @copyright (c) 2003-17 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ use EGroupware\Api; diff --git a/infolog/inc/class.infolog_so.inc.php b/infolog/inc/class.infolog_so.inc.php index 6537b0a198..678b2e0c68 100644 --- a/infolog/inc/class.infolog_so.inc.php +++ b/infolog/inc/class.infolog_so.inc.php @@ -5,9 +5,8 @@ * @link http://www.egroupware.org * @author Ralf Becker * @package infolog - * @copyright (c) 2003-16 by Ralf Becker + * @copyright (c) 2003-17 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ use EGroupware\Api; @@ -417,7 +416,9 @@ class infolog_so if (!$where || !($this->data = $this->db->select($this->info_table, - '*,'.$this->db->group_concat('account_id').' AS info_responsible,'.$this->info_table.'.info_id AS info_id', + '*,'.$this->db->group_concat('account_id').' AS info_responsible,'. + $this->db->group_concat('info_res_attendee').' AS info_cc,'. + $this->info_table.'.info_id AS info_id', $where, __LINE__, __FILE__, false, "GROUP BY $this->info_table.info_id", 'infolog', 1, "LEFT JOIN $this->users_table ON $this->info_table.info_id=$this->users_table.info_id AND $this->users_table.info_res_deleted IS NULL")->fetch())) { @@ -436,6 +437,11 @@ class infolog_so if (!is_array($this->data['info_responsible'])) { $this->data['info_responsible'] = $this->data['info_responsible'] ? explode(',',$this->data['info_responsible']) : array(); + foreach($this->data['info_responsible'] as $k => $v) + { + if (!is_numeric($v)) unset($this->data['info_responsible'][$k]); + } + $this->data['info_responsible'] = array_values($this->data['info_responsible']); } // Cast back to integer $this->data['info_id_parent'] = (int)$this->data['info_id_parent']; @@ -668,8 +674,26 @@ class infolog_so //error_log("### soinfolog::write(".print_r($to_write,true).") where=".print_r($where,true)." returning id=".$this->data['info_id']); // update attendees/delegates - if (array_key_exists('info_responsible', $values)) + if (array_key_exists('info_responsible', $values) || array_key_exists('info_cc', $values)) { + $users = empty($values['info_responsible']) ? array() : + array_combine($values['info_responsible'], array_fill(0, count($values['info_responsible']), null)); + + foreach(!empty($values['info_cc']) ? explode(',', $values['info_cc']) : array() as $email) + { + $email = trim($email); + $matches = null; + if (preg_match('/<[^>]+@[^>]+>$/', $email, $matches)) + { + $hash = md5(strtolower($matches[1])); + } + else + { + $hash = md5(strtolower($email)); + } + $users[$hash] = $email; + } + // mark removed attendees as deleted $this->db->update($this->users_table, array( 'info_res_deleted' => true, @@ -678,25 +702,26 @@ class infolog_so 'info_id' => $this->data['info_id'], 'info_res_deleted IS NULL', )+(!$values['info_responsible'] ? array() : - array(1=>'account_id NOT IN ('.implode(',', array_map('intval', $values['info_responsible'])).')')), + array(1=>'account_id NOT IN ('.implode(',', array_map(array($this->db, 'quote'), array_keys($users))).')')), __LINE__, __FILE__, 'infolog'); // add newly added attendees - if ($values['info_responsible']) + if ($users) { - $old_responsible = array(); - foreach($this->db->select($this->users_table,'account_id',array( + $old_users = array(); + foreach($this->db->select($this->users_table,'account_id,info_res_attendee',array( 'info_id' => $this->data['info_id'], 'info_res_deleted IS NULL', ), __LINE__, __FILE__, false, '', 'infolog') as $row) { - $old_responsible[] = $row['account_id']; + $old_users[] = $row['account_id']; } - foreach(array_diff($values['info_responsible'], $old_responsible) as $account_id) + foreach(array_diff(array_keys($users), $old_users) as $account_id) { $this->db->insert($this->users_table, array( 'info_res_modifier' => $this->user, 'info_res_status' => 'NEEDS-ACTION', + 'info_res_attendee' => $users[$account_id], 'info_res_deleted' => null, ), array( 'info_id' => $this->data['info_id'], @@ -965,6 +990,7 @@ class infolog_so $cols = isset($query['cols']) ? $query['cols'] : 'main.*'; if (is_array($cols)) $cols = implode(',',$cols); $cols .= ','.$this->db->group_concat('attendees.account_id').' AS info_responsible'; + $cols .= ','.$this->db->group_concat('attendees.info_res_attendee').' AS info_cc'; $rs = $this->db->query($sql='SELECT '.$mysql_calc_rows.' '.$distinct.' '.$cols.' '.$info_customfield.' '.$sql_query. $query['append'].$ordermethod,__LINE__,__FILE__, (int) $query['start'],isset($query['start']) ? (int) $query['num_rows'] : -1,false,Api\Db::FETCH_ASSOC); @@ -985,6 +1011,11 @@ class infolog_so foreach($rs as $info) { $info['info_responsible'] = $info['info_responsible'] ? array_unique(explode(',',$info['info_responsible'])) : array(); + foreach($info['info_responsible'] as $k => $v) + { + if (!is_numeric($v)) unset($info['info_responsible'][$k]); + } + $info['info_responsible'] = array_values($info['info_responsible']); $ids[$info['info_id']] = $info; } diff --git a/infolog/setup/setup.inc.php b/infolog/setup/setup.inc.php index ddb37a8618..4ba97194ed 100644 --- a/infolog/setup/setup.inc.php +++ b/infolog/setup/setup.inc.php @@ -6,13 +6,12 @@ * @author Ralf Becker * @package infolog * @subpackage setup - * @copyright (c) 2003-16 by Ralf Becker + * @copyright (c) 2003-17 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ $setup_info['infolog']['name'] = 'infolog'; -$setup_info['infolog']['version'] = '16.1.004'; +$setup_info['infolog']['version'] = '17.1'; $setup_info['infolog']['app_order'] = 5; $setup_info['infolog']['tables'] = array('egw_infolog','egw_infolog_extra','egw_infolog_users'); $setup_info['infolog']['enable'] = 1; @@ -26,7 +25,7 @@ $setup_info['infolog']['maintainer'] = array( $setup_info['infolog']['license'] = 'GPL'; $setup_info['infolog']['description'] = '

CRM (customer-relation-management) type app using Addressbook providing - Todo List, Notes and Phonelog. InfoLog is orininaly based on eGroupWare\'s + Todo List, Notes and Phonelog. InfoLog is orininaly based on EGroupware\'s old ToDo-List and has the features of all 3 mentioned applications plus fully working ACL (including Add+Private attributes, add for to addreplys/subtasks).

Responsibility for a task (ToDo) or a phonecall can be delegated to an other @@ -36,13 +35,7 @@ $setup_info['infolog']['description'] = the contact/address, project or calendar view.

Other documents / files can be linked to InfoLog entries and are store in the VFS (eGroupWare\'s virtual file system).

'; -$setup_info['infolog']['note'] = - '

There is a CSV import (in the admin-section) to import existing data. - It allows to interactivly assign fields, customize the values with regular - expressions and direct calls to php-functions (e.g. to link the phone calls - (again) to the addressbook entrys).

-

More information about InfoLog and the current development-status can be found on the - InfoLog page on our Website.

'; +$setup_info['infolog']['note'] = ''; /* The hooks this app includes, needed for hooks registration */ $setup_info['infolog']['hooks']['settings'] = 'infolog_hooks::settings'; @@ -70,5 +63,3 @@ $setup_info['infolog']['depends'][] = array( 'appname' => 'api', 'versions' => Array('16.1') ); - - diff --git a/infolog/setup/tables_current.inc.php b/infolog/setup/tables_current.inc.php index 6b0254abe9..433ebd5a47 100644 --- a/infolog/setup/tables_current.inc.php +++ b/infolog/setup/tables_current.inc.php @@ -6,9 +6,8 @@ * @author Ralf Becker * @package infolog * @subpackage setup - * @copyright (c) 2003-13 by Ralf Becker + * @copyright (c) 2003-17 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id$ */ $phpgw_baseline = array( @@ -41,7 +40,6 @@ $phpgw_baseline = array( 'info_location' => array('type' => 'varchar','precision' => '255','comment' => 'textfield location'), 'info_custom_from' => array('type' => 'int','precision' => '1','comment' => 'tick-box to show infolog_from'), 'info_uid' => array('type' => 'ascii','precision' => '128','comment' => 'unique id of the infolog-entry'), - 'info_cc' => array('type' => 'varchar','precision' => '255','comment' => 'textfield for email-adress to be notified via email of changes'), 'caldav_name' => array('type' => 'ascii','precision' => '128','comment' => 'name part of CalDAV URL, if specified by client'), 'info_etag' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'etag, not yet used'), 'info_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'timestamp of the creation date'), @@ -67,7 +65,7 @@ $phpgw_baseline = array( 'fd' => array( 'info_res_id' => array('type' => 'auto','nullable' => False,'comment' => 'auto id'), 'info_id' => array('type' => 'int','precision' => '4','nullable' => False), - 'account_id' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False,'comment' => 'attendee'), + 'account_id' => array('type' => 'ascii','meta' => 'account','precision' => '32','nullable' => False,'comment' => 'account_id or md5 of lowercased email'), 'info_res_deleted' => array('type' => 'bool','comment' => 'NULL or true, not false!'), 'info_res_modified' => array('type' => 'timestamp','meta' => 'timestamp','default' => 'current_timestamp','comment' => 'last modification time'), 'info_res_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'modifying user'), diff --git a/infolog/setup/tables_update.inc.php b/infolog/setup/tables_update.inc.php index 66b578e55c..6d4ab81d43 100644 --- a/infolog/setup/tables_update.inc.php +++ b/infolog/setup/tables_update.inc.php @@ -6,13 +6,11 @@ * @author Ralf Becker * @package infolog * @subpackage setup - * @copyright (c) 2003-16 by Ralf Becker + * @copyright (c) 2003-17 by Ralf Becker * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License * @version $Id$ */ -use EGroupware\Api; - function infolog_upgrade0_9_11() { $GLOBALS['egw_setup']->oProc->RenameColumn('phpgw_infolog','info_datecreated','info_datemodified'); @@ -987,4 +985,97 @@ function infolog_upgrade16_1_003() ),'info_addr'); return $GLOBALS['setup_info']['infolog']['currentver'] = '16.1.004'; -} \ No newline at end of file +} + +/** + * Move comma-separated info_cc (CC email addresses) to egw_info_users and drop info_cc column + * + * @return string + */ +function infolog_upgrade16_1_004() +{ + // make account_id column ascii(32) to store either numeric account_id or md5 of email + $GLOBALS['egw_setup']->oProc->AlterColumn('egw_infolog_users', 'account_id', array( + 'type' => 'ascii', + 'precision' => '32', + 'nullable' => false, + )); + + $n = 0; + $chunk_size = 500; + do + { + $i = 0; + foreach($GLOBALS['egw_setup']->db->select('egw_infolog', 'info_id,info_cc', + "info_cc <> ''", __LINE__, __FILE__, + $n*$chunk_size, 'ORDER BY info_id', 'infolog', $chunk_size) as $row) + { + foreach(array_unique(explode(',', $row['info_cc'])) as $email) + { + if ($email) + { + $email = trim($email); + $matches = null; + if (preg_match('/<([^>]+@[^>])>$/', $email, $matches)) + { + $hash = md5(strtolower($matches[1])); + } + else + { + $hash = md5(strtolower($email)); + } + $GLOBALS['egw_setup']->db->insert('egw_infolog_users', array( + 'info_id' => $row['info_id'], + 'account_id' => $hash, + 'info_res_attendee' => $email, + ), false, __LINE__, __FILE__, 'infolog'); + } + } + ++$i; + } + ++$n; + } + while ($i == $chunk_size); + + $GLOBALS['egw_setup']->oProc->DropColumn('egw_infolog',array( + 'fd' => array( + 'info_id' => array('type' => 'auto','nullable' => False,'comment' => 'id of the infolog-entry'), + 'info_type' => array('type' => 'varchar','precision' => '40','nullable' => False,'default' => 'task','comment' => 'infolog-type e.g. task, phone, email or note'), + 'info_from' => array('type' => 'varchar','precision' => '255','comment' => 'text of the primary link'), + 'info_subject' => array('type' => 'varchar','precision' => '255','comment' => 'title of the infolog-entry'), + 'info_des' => array('type' => 'longtext','comment' => 'desciption of the infolog-entry'), + 'info_owner' => array('type' => 'int','meta' => 'account','precision' => '4','nullable' => False,'comment' => 'owner of the entry, can be account or group'), + 'info_access' => array('type' => 'ascii','precision' => '10','default' => 'public','comment' => 'public or privat'), + 'info_cat' => array('type' => 'int','meta' => 'category','precision' => '4','nullable' => False,'default' => '0','comment' => 'category id'), + 'info_datemodified' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'comment' => 'timestamp of the last mofification'), + 'info_startdate' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'default' => '0','comment' => 'timestamp of the startdate'), + 'info_enddate' => array('type' => 'int','meta' => 'timestamp','precision' => '8','nullable' => False,'default' => '0','comment' => 'timestamp of the enddate'), + 'info_id_parent' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'id of the parent infolog'), + 'info_planned_time' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'pm-field: planned time'), + 'info_replanned_time' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'pm-field: replanned time'), + 'info_used_time' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'pm-field: used time'), + 'info_status' => array('type' => 'varchar','precision' => '40','default' => 'done','comment' => 'status e.g. ongoing, done ...'), + 'info_confirm' => array('type' => 'ascii','precision' => '10','default' => 'not'), + 'info_modifier' => array('type' => 'int','meta' => 'user','precision' => '4','nullable' => False,'default' => '0','comment' => 'account id of the last modifier'), + 'info_link_id' => array('type' => 'int','precision' => '4','nullable' => False,'default' => '0','comment' => 'id of the primary link'), + 'info_priority' => array('type' => 'int','precision' => '2','default' => '1','comment' => '0=Low, 1=Normal, 2=High, 3=Urgent'), + 'pl_id' => array('type' => 'int','precision' => '4','comment' => 'pm-field: id of the pricelist'), + 'info_price' => array('type' => 'float','precision' => '8','comment' => 'pm-field: price-field'), + 'info_percent' => array('type' => 'int','meta' => 'percent','precision' => '2','default' => '0','comment' => 'percentage of completion'), + 'info_datecompleted' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'timestamp of completion'), + 'info_location' => array('type' => 'varchar','precision' => '255','comment' => 'textfield location'), + 'info_custom_from' => array('type' => 'int','precision' => '1','comment' => 'tick-box to show infolog_from'), + 'info_uid' => array('type' => 'ascii','precision' => '128','comment' => 'unique id of the infolog-entry'), + 'caldav_name' => array('type' => 'ascii','precision' => '128','comment' => 'name part of CalDAV URL, if specified by client'), + 'info_etag' => array('type' => 'int','precision' => '4','default' => '0','comment' => 'etag, not yet used'), + 'info_created' => array('type' => 'int','meta' => 'timestamp','precision' => '8','comment' => 'timestamp of the creation date'), + 'info_creator' => array('type' => 'int','meta' => 'user','precision' => '4','comment' => 'account id of the creator') + ), + 'pk' => array('info_id'), + 'fk' => array(), + 'ix' => array('caldav_name','info_owner','info_datemodified','info_id_parent'), + 'uc' => array() + ),'info_cc'); + + return $GLOBALS['setup_info']['infolog']['currentver'] = '17.1'; +}