Merge branch '2015.11-develop' into 2016.11
[tine20] / tine20 / Calendar / Setup / Update / Release9.php
1 <?php
2 /**
3  * Tine 2.0
4  *
5  * @package     Calendar
6  * @subpackage  Setup
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
8  * @copyright   Copyright (c) 2015 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Philipp Schüle <p.schuele@metaways.de>
10  */
11 class Calendar_Setup_Update_Release9 extends Setup_Update_Abstract
12 {
13     /**
14      * update to 9.1
15      * - identify base event via new base_event_id field instead of UID
16      */
17     public function update_0()
18     {
19         if ($this->getTableVersion('cal_events') < 10) {
20             $release8 = new Calendar_Setup_Update_Release8($this->_backend);
21             $release8->update_8();
22         }
23         $this->setApplicationVersion('Calendar', '9.1');
24     }
25
26     /**
27      * update to 9.2
28      *
29      * @see 0011266: increase size of event fields summary and location
30      */
31     public function update_1()
32     {
33         if ($this->getTableVersion('cal_events') < 11) {
34             $release8 = new Calendar_Setup_Update_Release8($this->_backend);
35             $release8->update_9();
36         }
37         $this->setApplicationVersion('Calendar', '9.2');
38     }
39
40     /**
41      * update to 9.3
42      *
43      * @see 0011312: Make resource notification handling and default status configurable
44      */
45     public function update_2()
46     {
47         if ($this->getTableVersion('cal_resources') < 3) {
48             $release8 = new Calendar_Setup_Update_Release8($this->_backend);
49             $release8->update_10();
50         }
51         $this->setApplicationVersion('Calendar', '9.3');
52     }
53
54     /**
55      * force activesync calendar resync for iOS devices
56      */
57     public function update_3()
58     {
59         $release8 = new Calendar_Setup_Update_Release8($this->_backend);
60         $release8->update_11();
61         $this->setApplicationVersion('Calendar', '9.4');
62     }
63
64     /**
65      * update to 9.5
66      *
67      * add rrule_constraints
68      */
69     public function update_4()
70     {
71         if (!$this->_backend->columnExists('rrule_constraints', 'cal_events')) {
72             $seqCol = '<field>
73                 <name>rrule_constraints</name>
74                 <type>text</type>
75                 <notnull>false</notnull>
76             </field>';
77
78             $declaration = new Setup_Backend_Schema_Field_Xml($seqCol);
79             $this->_backend->addCol('cal_events', $declaration);
80         }
81
82
83         $this->setTableVersion('cal_events', '12');
84         $this->setApplicationVersion('Calendar', '9.5');
85     }
86
87     /**
88      * update to 9.6
89      *
90      * add resource busy_type
91      */
92     public function update_5()
93     {
94         if (!$this->_backend->columnExists('busy_type', 'cal_resources')) {
95             $col = '<field>
96                 <name>busy_type</name>
97                 <type>text</type>
98                 <length>32</length>
99                 <default>BUSY</default>
100                 <notnull>true</notnull>
101             </field>';
102
103             $declaration = new Setup_Backend_Schema_Field_Xml($col);
104             $this->_backend->addCol('cal_resources', $declaration);
105         }
106
107         $this->setTableVersion('cal_resources', '4');
108         $this->setApplicationVersion('Calendar', '9.6');
109     }
110
111     /**
112      * update to 9.7
113      *
114      * add rrule_constraints background job
115      */
116     public function update_6()
117     {
118         $scheduler = Tinebase_Core::getScheduler();
119         Calendar_Scheduler_Task::addUpdateConstraintsExdatesTask($scheduler);
120
121         $this->setApplicationVersion('Calendar', '9.7');
122     }
123
124     /**
125      * update to 9.8
126      *
127      * Update Calendar Import Export definitions
128      */
129     public function update_7()
130     {
131         $app = Tinebase_Application::getInstance()->getApplicationByName('Calendar');
132         Setup_Controller::getInstance()->createImportExportDefinitions($app);
133         $this->setApplicationVersion('Calendar', '9.8');
134     }
135
136     /**
137      * fix displaycontainer in organizers attendee records
138      */
139     public function update_8()
140     {
141         $allBroken = $this->_db->query(
142             "SELECT " . $this->_db->quoteIdentifier('events.id') . " AS " . $this->_db->quoteIdentifier('event_id') . "," .
143             $this->_db->quoteIdentifier('events.is_deleted') . " AS " . $this->_db->quoteIdentifier('event_is_deleted') . "," .
144             $this->_db->quoteIdentifier('events.container_id') . "," .
145             $this->_db->quoteIdentifier('events.seq') . "," .
146             $this->_db->quoteIdentifier('attendee.id') . " AS " . $this->_db->quoteIdentifier('attendee_id') .
147             " FROM " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "cal_events") . " AS " . $this->_db->quoteIdentifier('events') .
148             " INNER JOIN " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "container") . " AS " . $this->_db->quoteIdentifier('container') . " ON " .
149             $this->_db->quoteIdentifier('events.container_id') . " = ". $this->_db->quoteIdentifier('container.id') . " AND " .
150             $this->_db->quoteIdentifier('container.type') . " = ". $this->_db->quote('personal') .
151             " INNER JOIN " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "accounts") . " AS " . $this->_db->quoteIdentifier('owner') . " ON " .
152             $this->_db->quoteIdentifier('container.owner_id') . " = ". $this->_db->quoteIdentifier('owner.id') .
153             " INNER JOIN " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "cal_attendee") . " AS " . $this->_db->quoteIdentifier('attendee') . " ON " .
154             $this->_db->quoteIdentifier('attendee.cal_event_id') . " = ". $this->_db->quoteIdentifier('events.id') . " AND " .
155             $this->_db->quoteIdentifier('attendee.user_id') . " = ". $this->_db->quoteIdentifier('owner.contact_id') . " AND " .
156             $this->_db->quoteIdentifier('attendee.user_type') . " IN (". $this->_db->quote(array('user', 'groupmember')) . ") AND " .
157             $this->_db->quoteIdentifier('attendee.displaycontainer_id') . " != ". $this->_db->quoteIdentifier('events.container_id')
158         )->fetchAll(Zend_Db::FETCH_ASSOC);
159
160         foreach ($allBroken as $broken) {
161             $time = Tinebase_DateTime::now()->toString();
162
163             $this->_db->query("START TRANSACTION");
164             $this->_db->query(
165                 "UPDATE " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "cal_attendee") .
166                 " SET " . $this->_db->quoteIdentifier("displaycontainer_id") . " = " . $this->_db->quote($broken['container_id']) .
167                 " WHERE " . $this->_db->quoteIdentifier("id") . " = " . $this->_db->quote($broken['attendee_id'])
168             );
169
170             // care for consistent history for client updates
171             if (!$broken['event_is_deleted']) {
172                 $this->_db->query(
173                     "UPDATE " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "cal_events") .
174                     " SET " . $this->_db->quoteIdentifier("seq") . " = (" . $this->_db->quoteIdentifier('seq') . " +1)," .
175                     $this->_db->quoteIdentifier("last_modified_time") . " = " . $this->_db->quote($time) .
176                     " WHERE " . $this->_db->quoteIdentifier("id") . " = " . $this->_db->quote($broken['event_id'])
177                 );
178                 $quotedIdentifier = $this->_db->quoteIdentifier("content_seq");
179                 $this->_db->query(
180                     "UPDATE " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "container") .
181                     " SET " . $quotedIdentifier . " = " .  new Zend_Db_Expr('(CASE WHEN ' . $quotedIdentifier . ' >= 1 THEN ' . $quotedIdentifier . ' + 1 ELSE 1 END)') .
182                     " WHERE " . $this->_db->quoteIdentifier("id") . " = " . $this->_db->quote($broken['container_id'])
183                 );
184                 $content_seq = Tinebase_Helper::array_value('content_seq', Tinebase_Helper::array_value(0, $this->_db->query(
185                     "SELECT " . $this->_db->quoteIdentifier('content_seq') .
186                     " FROM " . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "container") .
187                     " WHERE " . $this->_db->quoteIdentifier('id') . " = " . $this->_db->quote($broken['container_id'])
188                 )->fetchAll(Zend_Db::FETCH_ASSOC))) ?: 1;
189                 $this->_db->query(
190                     "INSERT INTO" . $this->_db->quoteIdentifier(SQL_TABLE_PREFIX . "container_content") .
191                     " (" .
192                     $this->_db->quoteIdentifier("id") . "," .
193                     $this->_db->quoteIdentifier("container_id") . "," .
194                     $this->_db->quoteIdentifier("record_id") . "," .
195                     $this->_db->quoteIdentifier("action") . "," .
196                     $this->_db->quoteIdentifier("content_seq") . "," .
197                     $this->_db->quoteIdentifier("time") .
198                     ") VALUES (" .
199                     $this->_db->quote(Tinebase_Record_Abstract::generateUID()) . "," .
200                     $this->_db->quote($broken['container_id']) . "," .
201                     $this->_db->quote($broken['event_id']) . "," .
202                     $this->_db->quote('update') . "," .
203                     $this->_db->quote($content_seq) . "," .
204                     $this->_db->quote($time) .
205                     ")"
206                 );
207             }
208             $this->_db->query("COMMIT");
209         }
210
211         // if called out of normal update process
212         if ($this->getApplicationVersion('Calendar') == '9.8') {
213             $this->setApplicationVersion('Calendar', '9.9');
214         }
215     }
216 }