f04a54e066b680f6608f6c82f51880ca23f3dc9f
[tine20] / tine20 / Tinebase / Setup / Update / Release10.php
1 <?php
2 /**
3  * Tine 2.0
4  *
5  * @package     Tinebase
6  * @subpackage  Setup
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL3
8  * @copyright   Copyright (c) 2016-2017 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Philipp Schüle <p.schuele@metaways.de>
10  */
11 class Tinebase_Setup_Update_Release10 extends Setup_Update_Abstract
12 {
13     /**
14      * update to 10.1
15      *
16      * @see 0012162: create new MailFiler application
17      */
18     public function update_0()
19     {
20         $this->_addIsDeletedToTreeNodes();
21
22         $release9 = new Tinebase_Setup_Update_Release9($this->_backend);
23         $release9->update_9();
24         $this->setApplicationVersion('Tinebase', '10.1');
25     }
26
27     /**
28      * update to 10.2
29      *
30      * @see 0012300: add container owner column
31      */
32     public function update_1()
33     {
34         $release9 = new Tinebase_Setup_Update_Release9($this->_backend);
35         try {
36             $release9->update_4();
37         } catch (Zend_Db_Exception $zde) {
38             Tinebase_Exception::log($zde);
39         }
40         $this->setApplicationVersion('Tinebase', '10.2');
41     }
42
43     /**
44      * update to 10.3
45      *
46      * change length of groups.description column from varchar(255) to text
47      */
48     public function update_2()
49     {
50         $release9 = new Tinebase_Setup_Update_Release9($this->_backend);
51         $release9->update_5();
52         $this->setApplicationVersion('Tinebase', '10.3');
53     }
54
55     /**
56      * update to 10.4
57      *
58      * dd numberables
59      */
60     public function update_3()
61     {
62         $release9 = new Tinebase_Setup_Update_Release9($this->_backend);
63         $release9->update_10();
64         $this->setApplicationVersion('Tinebase', '10.4');
65     }
66
67     /**
68      * needs to be done again to make sure we have the column!
69      *
70      * @see 0012300: add container owner column
71      */
72     public function update_4()
73     {
74         $release9 = new Tinebase_Setup_Update_Release9($this->_backend);
75         try {
76             $release9->update_4();
77         } catch (Zend_Db_Exception $zde) {
78             Tinebase_Exception::log($zde);
79         }
80         $this->setApplicationVersion('Tinebase', '10.5');
81     }
82
83     /**
84      * update to 10.6
85      *
86      * add account sync scheduler job
87      */
88     public function update_5()
89     {
90         $scheduler = Tinebase_Core::getScheduler();
91         Tinebase_Scheduler_Task::addAccountSyncTask($scheduler);
92
93         $this->setApplicationVersion('Tinebase', '10.6');
94     }
95
96     /**
97      * update to 10.7
98      *
99      * update timemachine_modlog table
100      */
101     public function update_6()
102     {
103         if (!$this->_backend->columnExists('instance_id', 'timemachine_modlog')) {
104
105             $this->_backend->renameTable('timemachine_modlog', 'timemachine_modlog_bkp');
106             $db = Tinebase_Core::getDb();
107             if ($db instanceof Zend_Db_Adapter_Pdo_Pgsql) {
108                 $db->exec('ALTER INDEX "' . SQL_TABLE_PREFIX . 'timemachine_modlog_pkey" RENAME TO ' . SQL_TABLE_PREFIX . 'timemachine_modlog_pkey_bkp');
109                 $db->exec('ALTER INDEX "' . SQL_TABLE_PREFIX . 'timemachine_modlog_seq" RENAME TO ' . SQL_TABLE_PREFIX . 'timemachine_modlog_seq_bkp');
110                 $db->exec('ALTER INDEX "' . SQL_TABLE_PREFIX . 'timemachine_modlog_unique-fields_key" RENAME TO "' . SQL_TABLE_PREFIX . 'timemachine_modlog_unique-fields_key_bkp"');
111             }
112
113             $this->_backend->createTable(new Setup_Backend_Schema_Table_Xml('<table>
114                 <name>timemachine_modlog</name>
115                 <version>5</version>
116                 <declaration>
117                     <field>
118                         <name>id</name>
119                         <type>text</type>
120                         <length>40</length>
121                         <notnull>true</notnull>
122                     </field>
123                     <field>
124                         <name>instance_id</name>
125                         <type>text</type>
126                         <length>40</length>
127                         <notnull>false</notnull>
128                     </field>
129                     <field>
130                         <name>instance_seq</name>
131                         <type>integer</type>
132                         <notnull>true</notnull>
133                         <autoincrement>true</autoincrement>
134                     </field>
135                     <field>
136                         <name>change_type</name>
137                         <type>text</type>
138                         <length>40</length>
139                         <notnull>false</notnull>
140                     </field>
141                     <field>
142                         <name>application_id</name>
143                         <type>text</type>
144                         <length>40</length>
145                         <notnull>true</notnull>
146                     </field>
147                     <field>
148                         <name>record_id</name>
149                         <type>text</type>
150                         <length>40</length>
151                         <notnull>false</notnull>
152                     </field>
153                     <field>
154                         <name>record_type</name>
155                         <type>text</type>
156                         <length>64</length>
157                         <notnull>false</notnull>
158                     </field>
159                     <field>
160                         <name>record_backend</name>
161                         <type>text</type>
162                         <length>64</length>
163                         <notnull>false</notnull>
164                     </field>
165                     <field>
166                         <name>modification_time</name>
167                         <type>datetime</type>
168                         <notnull>true</notnull>
169                     </field>
170                     <field>
171                         <name>modification_account</name>
172                         <type>text</type>
173                         <length>40</length>
174                         <notnull>true</notnull>
175                     </field>
176                     <field>
177                         <name>modified_attribute</name>
178                         <type>text</type>
179                         <length>64</length>
180                         <notnull>false</notnull>
181                     </field>
182                     <field>
183                         <name>old_value</name>
184                         <type>clob</type>
185                     </field>
186                     <field>
187                         <name>new_value</name>
188                         <type>clob</type>
189                     </field>
190                     <field>
191                         <name>seq</name>
192                         <type>integer</type>
193                         <length>64</length>
194                     </field>
195                     <field>
196                         <name>client</name>
197                         <type>text</type>
198                         <length>255</length>
199                         <notnull>true</notnull>
200                     </field>
201                     <index>
202                         <name>id</name>
203                         <primary>true</primary>
204                         <field>
205                             <name>id</name>
206                         </field>
207                     </index>
208                     <index>
209                         <name>instance_id</name>
210                         <field>
211                             <name>instance_id</name>
212                         </field>
213                     </index>
214                     <index>
215                         <name>instance_seq</name>
216                         <unique>true</unique>
217                         <field>
218                             <name>instance_seq</name>
219                         </field>
220                     </index>
221                     <index>
222                         <name>seq</name>
223                         <field>
224                             <name>seq</name>
225                         </field>
226                     </index>
227                     <index>
228                         <name>unique-fields</name>
229                         <unique>true</unique>
230                         <field>
231                             <name>application_id</name>
232                         </field>
233                         <field>
234                             <name>record_id</name>
235                         </field>
236                         <field>
237                             <name>record_type</name>
238                         </field>
239                         <field>
240                             <name>modification_time</name>
241                         </field>
242                         <field>
243                             <name>modification_account</name>
244                         </field>
245                         <field>
246                             <name>modified_attribute</name>
247                         </field>
248                         <field>
249                             <name>seq</name>
250                         </field>
251                     </index>
252                 </declaration>
253             </table>'));
254
255
256
257             $appIds[] = Tinebase_Application::getInstance()->getApplicationByName('Addressbook')->getId();
258             if (Tinebase_Application::getInstance()->isInstalled('Calendar')) {
259                 $appIds[] = Tinebase_Application::getInstance()->getApplicationByName('Calendar')->getId();
260             }
261
262             $select = $db->select()->from(SQL_TABLE_PREFIX . 'timemachine_modlog_bkp')->order('modification_time ASC')
263                 ->where($db->quoteInto($db->quoteIdentifier('application_id') . ' IN (?)', $appIds))
264                 ->where($db->quoteInto($db->quoteIdentifier('record_type') . ' IN (?)', array('Addressbook_Model_Contact', 'Calendar_Model_Resource')))
265                 ->where($db->quoteInto($db->quoteIdentifier('modified_attribute') . ' IN (?)', array('email', 'email_home')));
266
267             $stmt = $db->query($select);
268             $resultArray = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
269
270             if (count($resultArray) > 0) {
271                 foreach($resultArray as $row) {
272                     $row['client'] = 'update script';
273                     $db->insert(SQL_TABLE_PREFIX . 'timemachine_modlog', $row);
274                 }
275             }
276
277             $this->setTableVersion('timemachine_modlog', '5');
278         }
279
280         $this->setApplicationVersion('Tinebase', '10.7');
281     }
282
283     /**
284      * update to 10.8
285      *
286      * update roles and application table
287      */
288     public function update_7()
289     {
290         if (!$this->_backend->columnExists('is_deleted', 'roles')) {
291             $query = $this->_backend->addAddCol(null, 'roles',
292                 new Setup_Backend_Schema_Field_Xml('<field>
293                     <name>is_deleted</name>
294                     <type>boolean</type>
295                     <default>false</default>
296                 </field>'), 'last_modified_time'
297             );
298             $query = $this->_backend->addAddCol($query, 'roles',
299                 new Setup_Backend_Schema_Field_Xml('<field>
300                     <name>deleted_by</name>
301                     <type>text</type>
302                     <length>40</length>
303                 </field>'), 'is_deleted'
304             );
305             $query = $this->_backend->addAddCol($query, 'roles',
306                 new Setup_Backend_Schema_Field_Xml('<field>
307                     <name>deleted_time</name>
308                     <type>datetime</type>
309                 </field>'), 'deleted_by'
310             );
311             $query = $this->_backend->addAddCol($query, 'roles',
312                 new Setup_Backend_Schema_Field_Xml('<field>
313                     <name>seq</name>
314                     <type>integer</type>
315                     <notnull>true</notnull>
316                     <default>0</default>
317                 </field>'), 'deleted_time'
318             );
319             $this->_backend->execQueryVoid($query);
320             $this->setTableVersion('roles', '2');
321         }
322
323         if (!$this->_backend->columnExists('state', 'applications')) {
324
325             $this->_backend->addCol('applications',
326                 new Setup_Backend_Schema_Field_Xml('<field>
327                     <name>state</name>
328                     <type>text</type>
329                     <length>65535</length>
330                     <notnull>false</notnull>
331                 </field>')
332             );
333
334             $this->setTableVersion('applications', '4');
335         }
336
337         $this->setApplicationVersion('Tinebase', '10.8');
338     }
339
340     /**
341      * update to 10.9
342      *
343      * add client row to timemachine_modlog
344      *
345      * @see 0012830: add client user agent to modlog
346      */
347     public function update_8()
348     {
349         if (! $this->_backend->columnExists('client', 'timemachine_modlog')) {
350             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
351                     <name>client</name>
352                     <type>text</type>
353                     <length>255</length>
354                     <notnull>true</notnull>
355                 </field>');
356             $this->_backend->addCol('timemachine_modlog', $declaration);
357
358             $this->setTableVersion('timemachine_modlog', '5');
359         }
360
361         $this->setApplicationVersion('Tinebase', '10.9');
362     }
363
364     /**
365      * update to 10.10
366      *
367      * adding path filter feature switch & structure update
368      */
369     public function update_9()
370     {
371         $this->_addIsDeletedToTreeNodes();
372
373         $this->dropTable('path');
374
375         $declaration = new Setup_Backend_Schema_Table_Xml('<table>
376             <name>path</name>
377             <version>2</version>
378             <requirements>
379                 <required>mysql >= 5.6.4</required>
380             </requirements>
381             <declaration>
382                 <field>
383                     <name>id</name>
384                     <type>text</type>
385                     <length>40</length>
386                     <notnull>true</notnull>
387                 </field>
388                 <field>
389                     <name>path</name>
390                     <type>text</type>
391                     <length>65535</length>
392                     <notnull>true</notnull>
393                 </field>
394                 <field>
395                     <name>shadow_path</name>
396                     <type>text</type>
397                     <length>65535</length>
398                     <notnull>true</notnull>
399                 </field>
400                 <field>
401                     <name>creation_time</name>
402                     <type>datetime</type>
403                 </field>
404                 <index>
405                     <name>id</name>
406                     <primary>true</primary>
407                     <field>
408                         <name>id</name>
409                     </field>
410                 </index>
411                 <index>
412                 <name>path</name>
413                     <fulltext>true</fulltext>
414                     <field>
415                         <name>path</name>
416                     </field>
417                 </index>
418                 <index>
419                     <name>shadow_path</name>
420                     <fulltext>true</fulltext>
421                     <field>
422                         <name>shadow_path</name>
423                     </field>
424                 </index>
425             </declaration>
426         </table>');
427
428         $this->createTable('path', $declaration, 'Tinebase', 2);
429
430         try {
431             $setupUser = Setup_Update_Abstract::getSetupFromConfigOrCreateOnTheFly();
432             if ($setupUser) {
433                 Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
434                 Tinebase_Controller::getInstance()->rebuildPaths();
435             } else {
436                 if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) {
437                     Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__
438                         . ' Could not find valid setupuser. Skipping rebuildPaths: you might need to run this manually.');
439                 }
440             }
441         } catch (Exception $e) {
442             Tinebase_Exception::log($e);
443             Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__
444                 . ' Skipping rebuildPaths: you might need to run this manually.');
445         }
446
447         $this->setApplicationVersion('Tinebase', '10.10');
448     }
449
450     /**
451      * update to 10.11
452      *
453      * create external_fulltext table
454      */
455     public function update_10()
456     {
457         $this->_backend->createTable(new Setup_Backend_Schema_Table_Xml('<table>
458             <name>external_fulltext</name>
459             <version>1</version>
460             <declaration>
461                 <field>
462                     <name>id</name>
463                     <type>text</type>
464                     <length>40</length>
465                     <notnull>true</notnull>
466                 </field>
467                 <field>
468                     <name>text_data</name>
469                     <type>text</type>
470                     <length>2147483647</length>
471                     <notnull>true</notnull>
472                 </field>
473                 <index>
474                     <name>id</name>
475                     <primary>true</primary>
476                     <field>
477                         <name>id</name>
478                     </field>
479                 </index>
480                 <index>
481                     <name>text_data</name>
482                     <fulltext>true</fulltext>
483                     <field>
484                         <name>text_data</name>
485                     </field>
486                 </index>
487             </declaration>
488         </table>'), 'Tinebase', 'external_fulltext');
489
490         $this->setApplicationVersion('Tinebase', '10.11');
491     }
492
493     /**
494      * update to 10.12
495      *
496      * add revision_size to tree_fileobjects
497      */
498     public function update_11()
499     {
500
501         if (!$this->_backend->columnExists('total_size', 'tree_fileobjects')) {
502             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
503                     <name>revision_size</name>
504                     <type>integer</type>
505                     <notnull>true</notnull>
506                     <default>0</default>
507                 </field>');
508
509             $query = $this->_backend->addAddCol('', 'tree_fileobjects', $declaration);
510
511             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
512                     <name>indexed_hash</name>
513                     <type>text</type>
514                     <length>40</length>
515                 </field>');
516
517             $query = $this->_backend->addAddCol($query, 'tree_fileobjects', $declaration);
518
519             $this->_backend->execQueryVoid($query);
520
521             $this->setTableVersion('tree_fileobjects', '4');
522         }
523
524         $this->setApplicationVersion('Tinebase', '10.12');
525     }
526
527     /**
528      * add tree_node_acl
529      */
530     public function update_12()
531     {
532         if (! $this->_backend->columnExists('acl_node', 'tree_nodes')) {
533             $declaration = new Setup_Backend_Schema_Field_Xml(
534                 '<field>
535                     <name>acl_node</name>
536                     <type>text</type>
537                     <length>40</length>
538                 </field>
539             ');
540             $query = $this->_backend->addAddCol('', 'tree_nodes', $declaration);
541             $declaration = new Setup_Backend_Schema_Field_Xml(
542                 '<field>
543                     <name>revisionProps</name>
544                     <type>text</type>
545                     <length>65535</length>
546                 </field>');
547             $query = $this->_backend->addAddCol($query, 'tree_nodes', $declaration);
548             $this->_backend->execQueryVoid($query);
549
550             $this->setTableVersion('tree_nodes', 2);
551
552             $declaration = new Setup_Backend_Schema_Table_Xml('<table>
553             <name>tree_node_acl</name>
554             <version>1</version>
555             <declaration>
556                 <field>
557                     <name>id</name>
558                     <type>text</type>
559                     <length>40</length>
560                     <notnull>true</notnull>
561                 </field>
562                 <field>
563                     <name>record_id</name>
564                     <type>text</type>
565                     <length>40</length>
566                     <notnull>true</notnull>
567                 </field>
568                 <field>
569                     <name>account_type</name>
570                     <type>text</type>
571                     <length>32</length>
572                     <default>user</default>
573                     <notnull>true</notnull>
574                 </field>
575                 <field>
576                     <name>account_id</name>
577                     <type>text</type>
578                     <length>40</length>
579                     <notnull>true</notnull>
580                 </field>
581                 <field>
582                     <name>account_grant</name>
583                     <type>text</type>
584                     <length>40</length>
585                     <notnull>true</notnull>
586                 </field>
587
588                 <index>
589                     <name>record_id-account-type-account_id-account_grant</name>
590                     <primary>true</primary>
591                     <field>
592                         <name>id</name>
593                     </field>
594                     <field>
595                         <name>record_id</name>
596                     </field>
597                     <field>
598                         <name>account_type</name>
599                     </field>
600                     <field>
601                         <name>account_id</name>
602                     </field>
603                     <field>
604                         <name>account_grant</name>
605                     </field>
606                 </index>
607                 <index>
608                     <name>id-account_type-account_id</name>
609                     <field>
610                         <name>record_id</name>
611                     </field>
612                     <field>
613                         <name>account_type</name>
614                     </field>
615                     <field>
616                         <name>account_id</name>
617                     </field>
618                 </index>
619                 <index>
620                     <name>tree_node_acl::record_id--tree_nodes::id</name>
621                     <field>
622                         <name>record_id</name>
623                     </field>
624                     <foreign>true</foreign>
625                     <reference>
626                         <table>tree_nodes</table>
627                         <field>id</field>
628                         <ondelete>cascade</ondelete>
629                     </reference>
630                 </index>
631             </declaration>
632         </table>');
633             $this->createTable('tree_node_acl', $declaration);
634         }
635
636         $this->setApplicationVersion('Tinebase', '10.13');
637     }
638
639     /**
640      * update to 10.14
641      *
642      * add file revision cleanup task to scheduler
643      */
644     public function update_13()
645     {
646         $scheduler = Tinebase_Core::getScheduler();
647         Tinebase_Scheduler_Task::addFileRevisionCleanupTask($scheduler);
648
649         $this->setApplicationVersion('Tinebase', '10.14');
650     }
651
652     /**
653      * update to 10.15
654      *
655      * update record_observer
656      */
657     public function update_14()
658     {
659         $this->dropTable('record_observer', 'Tinebase');
660
661         $this->createTable('record_observer', new Setup_Backend_Schema_Table_Xml('<table>
662             <name>record_observer</name>
663             <version>4</version>
664             <declaration>
665                 <field>
666                     <name>id</name>
667                     <type>integer</type>
668                     <autoincrement>true</autoincrement>
669                 </field>
670                 <field>
671                     <name>observable_model</name>
672                     <type>text</type>
673                     <length>100</length>
674                     <notnull>true</notnull>
675                 </field>
676                 <field>
677                     <name>observable_identifier</name>
678                     <type>text</type>
679                     <length>40</length>
680                     <notnull>true</notnull>
681                 </field>
682                 <field>
683                     <name>observer_model</name>
684                     <type>text</type>
685                     <length>100</length>
686                     <notnull>true</notnull>
687                 </field>
688                 <field>
689                     <name>observer_identifier</name>
690                     <type>text</type>
691                     <length>40</length>
692                     <notnull>true</notnull>
693                 </field>
694                 <field>
695                     <name>observed_event</name>
696                     <type>text</type>
697                     <length>100</length>
698                     <notnull>true</notnull>
699                 </field>
700                 <field>
701                     <name>created_by</name>
702                     <type>text</type>
703                     <length>40</length>
704                 </field>
705                 <field>
706                     <name>creation_time</name>
707                     <type>datetime</type>
708                     <notnull>true</notnull>
709                 </field>
710                 <index>
711                     <name>id</name>
712                     <primary>true</primary>
713                     <field>
714                         <name>id</name>
715                     </field>
716                 </index>
717                 <index>
718                     <name>observable-observer-event</name>
719                     <unique>true</unique>
720                     <field>
721                         <name>observable_model</name>
722                     </field>
723                     <field>
724                         <name>observable_identifier</name>
725                     </field>
726                     <field>
727                         <name>observer_model</name>
728                     </field>
729                     <field>
730                         <name>observer_identifier</name>
731                     </field>
732                     <field>
733                         <name>observed_event</name>
734                     </field>
735                 </index>
736                 <index>
737                     <name>observer</name>
738                     <field>
739                         <name>observer_model</name>
740                     </field>
741                     <field>
742                         <name>observer_identifier</name>
743                     </field>
744                 </index>
745             </declaration>
746         </table>'), 'Tinebase', 3);
747
748         $this->setApplicationVersion('Tinebase', '10.15');
749     }
750
751     /**
752      * update to 10.16
753      *
754      * add container xprops column
755      */
756     public function update_15()
757     {
758         if (! $this->_backend->columnExists('xprops', 'container')) {
759             $declaration = new Setup_Backend_Schema_Field_Xml(
760                 '<field>
761                     <name>xprops</name>
762                     <type>text</type>
763                     <notnull>false</notnull>
764                     <default>NULL</default>
765                 </field>
766             ');
767             $this->_backend->addCol('container', $declaration);
768             $this->setTableVersion('container', 12);
769         }
770
771         $this->setApplicationVersion('Tinebase', '10.16');
772     }
773
774     /**
775      * update node acl: find all nodes that have containers, copy acl to node and remove container
776      *
777      * TODO allow to call from cli?
778      */
779     public function update_16()
780     {
781         $this->_addIsDeletedToTreeNodes();
782
783         // this is needed for filesystem operations
784         $this->_addRevisionPreviewCountCol();
785
786         $applications = Tinebase_Application::getInstance()->getApplications();
787         $setupUser = Setup_Update_Abstract::getSetupFromConfigOrCreateOnTheFly();
788         if ($setupUser) {
789             Tinebase_Core::set(Tinebase_Core::USER, $setupUser);
790         }
791         foreach ($applications as $application) {
792             if ($setupUser && ! $setupUser->hasRight($application, Tinebase_Acl_Rights::RUN)) {
793                 if (Tinebase_Core::isLogLevel(Zend_Log::ERR)) {
794                     Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__
795                         . ' Skipping ' . $application->name . ' because setupuser has no RUN right');
796                 }
797                 continue;
798             }
799
800             $this->_migrateAclForApplication($application, Tinebase_FileSystem::FOLDER_TYPE_PERSONAL);
801             $this->_migrateAclForApplication($application, Tinebase_FileSystem::FOLDER_TYPE_SHARED);
802         }
803
804         $this->setApplicationVersion('Tinebase', '10.17');
805     }
806
807     /**
808      * @param $application
809      * @param $type
810      */
811     protected function _migrateAclForApplication($application, $type)
812     {
813         $path = Tinebase_FileSystem::getInstance()->getApplicationBasePath(
814             $application->name,
815             $type
816         );
817         try {
818             $parentNode = Tinebase_FileSystem::getInstance()->stat($path);
819         } catch (Tinebase_Exception_NotFound $tenf) {
820             return;
821         }
822
823         $childNodes = Tinebase_FileSystem::getInstance()->getTreeNodeChildren($parentNode);
824
825         if (count($childNodes) === 0) {
826             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
827                 . " No container nodes found for application " . $application->name);
828             return;
829         }
830
831         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
832             . ' ' . count($childNodes) . " nodes found for application " . $application->name);
833
834         if ($type === Tinebase_FileSystem::FOLDER_TYPE_PERSONAL) {
835             foreach ($childNodes as $accountNode) {
836                 $personalNodes = Tinebase_FileSystem::getInstance()->getTreeNodeChildren($accountNode);
837                 $this->_moveAclFromContainersToNodes($personalNodes);
838             }
839         } else {
840             // shared
841             $this->_moveAclFromContainersToNodes($childNodes);
842         }
843     }
844
845     /**
846      * @param Tinebase_Record_RecordSet $nodes
847      *
848      * TODO move to TFS?
849      */
850     protected function _moveAclFromContainersToNodes(Tinebase_Record_RecordSet $nodes)
851     {
852         foreach ($nodes as $node) {
853             try {
854                 $container = Tinebase_Container::getInstance()->getContainerById($node->name);
855             } catch (Tinebase_Exception_NotFound $tenf) {
856                 // already converted
857                 continue;
858             } catch (Tinebase_Exception_InvalidArgument $teia) {
859                 // already converted
860                 continue;
861             }
862             //print_r($container->toArray());
863             if ($container->model === 'HumanResources_Model_Employee') {
864                 // fix broken HR template container to prevent problems when removing data
865                 $container->model = 'Tinebase_Model_Tree_Node';
866                 Tinebase_Container::getInstance()->update($container);
867             }
868
869             // set container acl in node
870             $grants = Tinebase_Container::getInstance()->getGrantsOfContainer($container, /* ignore acl */ true);
871             Tinebase_FileSystem::getInstance()->setGrantsForNode($node, $grants);
872
873             // set container name in node
874             $node->name = $container->name;
875             // check if node exists and if yes: attach uid
876             $parentNode = Tinebase_FileSystem::getInstance()->get($node->parent_id);
877             $parentPath = Tinebase_FileSystem::getInstance()->getPathOfNode($parentNode, true);
878             if (Tinebase_FileSystem::getInstance()->fileExists($parentPath . '/' . $node->name)) {
879                 $node->name .= ' ' . Tinebase_Record_Abstract::generateUID(8);
880             }
881
882             $node->acl_node = $node->getId();
883             Tinebase_FileSystem::getInstance()->update($node);
884             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
885                 . ' Updated node acl for ' . $node->name .' (container id: ' . $container->getId() . ')');
886
887             // remove old acl container
888             Tinebase_Container::getInstance()->deleteContainer($container, /* ignore acl */ true);
889             if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
890                 . ' Removed old container ' . $container->name);
891         }
892     }
893
894     /**
895      * update to 10.18
896      *
897      * Add fulltext index for description field
898      */
899     public function update_17()
900     {
901         $declaration = new Setup_Backend_Schema_Index_Xml('
902             <index>
903                 <name>description</name>
904                 <fulltext>true</fulltext>
905                 <field>
906                     <name>description</name>
907                 </field>
908             </index>
909         ');
910
911         $this->_backend->addIndex('tree_fileobjects', $declaration);
912
913         $this->setTableVersion('tree_fileobjects', '5');
914         $this->setApplicationVersion('Tinebase', '10.18');
915     }
916
917     /**
918      * update to 10.19
919      *
920      * Add fulltext search index for tags description
921      */
922     public function update_18()
923     {
924         $declaration = new Setup_Backend_Schema_Index_Xml('
925             <index>
926                 <name>description</name>
927                 <fulltext>true</fulltext>
928                 <field>
929                     <name>description</name>
930                 </field>
931             </index>
932         ');
933
934         try {
935             $this->_backend->dropIndex('tags', 'description');
936         } catch (Exception $e) {
937             // Ignore, if there is no index, we can just go on and create one.
938         }
939
940         $this->_backend->addIndex('tags', $declaration);
941
942         $this->setTableVersion('tags', 8);
943         $this->setApplicationVersion('Tinebase', '10.19');
944     }
945
946     /**
947      * update to 10.20
948      *
949      * Make tags description a longtext field
950      */
951     public function update_19()
952     {
953         $declaration = new Setup_Backend_Schema_Field_Xml('
954             <field>
955                 <name>description</name>
956                 <!--Long text!-->
957                 <length>2147483647</length>
958                 <type>text</type>
959                 <default>NULL</default>
960             </field>
961         ');
962
963         $this->_backend->alterCol('tags', $declaration);
964
965         $this->setTableVersion('tags', 9);
966         $this->setApplicationVersion('Tinebase', '10.20');
967     }
968
969     /**
970      * update to 10.21
971      *
972      * add new file system tasks to scheduler
973      */
974     public function update_20()
975     {
976         $scheduler = Tinebase_Core::getScheduler();
977         Tinebase_Scheduler_Task::addFileSystemSizeRecalculation($scheduler);
978         Tinebase_Scheduler_Task::addFileSystemCheckIndexTask($scheduler);
979
980         $this->setApplicationVersion('Tinebase', '10.21');
981     }
982
983     /**
984      * update to 10.22
985      *
986      * add favorite column to importexport_definition
987      */
988     public function update_21()
989     {
990         if (! $this->_backend->columnExists('favorite', 'importexport_definition')) {
991             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
992                     <name>icon_class</name>
993                     <type>text</type>
994                     <length>255</length>
995                 </field>');
996             $this->_backend->addCol('importexport_definition', $declaration);
997
998             $declaration = new Setup_Backend_Schema_Field_Xml('
999                 <field>
1000                     <name>favorite</name>
1001                     <type>boolean</type>
1002                 </field>');
1003             $this->_backend->addCol('importexport_definition', $declaration);
1004
1005             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
1006                     <name>order</name>
1007                     <type>integer</type>
1008                     <notnull>true</notnull>
1009                     <default>0</default>
1010                 </field>');
1011             $this->_backend->addCol('importexport_definition', $declaration);
1012
1013             $this->setTableVersion('importexport_definition', 9);
1014         }
1015
1016         $this->setApplicationVersion('Tinebase', '10.22');
1017     }
1018
1019     /**
1020      * update to 10.23
1021      *
1022      * add preview_count column to tree_filerevisions
1023      */
1024     public function update_22()
1025     {
1026         $this->_addRevisionPreviewCountCol();
1027         $this->setApplicationVersion('Tinebase', '10.23');
1028     }
1029
1030     protected function _addRevisionPreviewCountCol()
1031     {
1032         if (! $this->_backend->columnExists('preview_count', 'tree_filerevisions')) {
1033             $declaration = new Setup_Backend_Schema_Field_Xml(
1034                 '<field>
1035                     <name>preview_count</name>
1036                     <type>integer</type>
1037                     <length>64</length>
1038                     <notnull>true</notnull>
1039                     <default>0</default>
1040                 </field>');
1041             $this->_backend->addCol('tree_filerevisions', $declaration);
1042             $this->setTableVersion('tree_filerevisions', 2);
1043         }
1044     }
1045
1046     /**
1047      * update to 10.24
1048      *
1049      * 0013032: add GRANT_DOWNLOAD
1050      * 0013034: add GRANT_PUBLISH
1051      */
1052     public function update_23()
1053     {
1054         $this->_addNotificationProps();
1055         $this->_addIsDeletedToTreeNodes();
1056
1057         // get all folder nodes with own acl
1058         $searchFilter = new Tinebase_Model_Tree_Node_Filter(array(
1059             array(
1060                 'field'     => 'type',
1061                 'operator'  => 'equals',
1062                 'value'     => Tinebase_Model_Tree_FileObject::TYPE_FOLDER
1063             )
1064         ), Tinebase_Model_Filter_FilterGroup::CONDITION_AND, array('ignoreAcl' => true));
1065         $folders = Tinebase_FileSystem::getInstance()->searchNodes($searchFilter);
1066         $updateCount = 0;
1067         foreach ($folders as $folder) {
1068             if ($folder->acl_node === $folder->getId()) {
1069                 $grants = Tinebase_FileSystem::getInstance()->getGrantsOfContainer($folder, /* ignoreAcl */ true);
1070                 foreach ($grants as $grant) {
1071                     // add download & publish for admins and only download for the rest
1072                     if ($grant->{Tinebase_Model_Grants::GRANT_ADMIN}) {
1073                         $grant->{Tinebase_Model_Grants::GRANT_DOWNLOAD} = true;
1074                         $grant->{Tinebase_Model_Grants::GRANT_PUBLISH} = true;
1075                     } else {
1076                         $grant->{Tinebase_Model_Grants::GRANT_DOWNLOAD} = true;
1077                     }
1078                 }
1079                 Tinebase_FileSystem::getInstance()->setGrantsForNode($folder, $grants);
1080                 $updateCount++;
1081             }
1082         }
1083
1084         if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__
1085             . ' Added DOWNLOAD & PUBLISH grants to ' . $updateCount . ' folder nodes');
1086
1087         $this->setApplicationVersion('Tinebase', '10.24');
1088     }
1089
1090     /**
1091      * update to 10.25
1092      *
1093      * add notification props
1094      */
1095     public function update_24()
1096     {
1097         $this->_addNotificationProps();
1098         $this->setApplicationVersion('Tinebase', '10.25');
1099     }
1100
1101     protected function _addNotificationProps()
1102     {
1103         if (! $this->_backend->columnExists('notificationProps', 'tree_nodes')) {
1104             $declaration = new Setup_Backend_Schema_Field_Xml(
1105                 '<field>
1106                     <name>notificationProps</name>
1107                     <type>text</type>
1108                     <length>65535</length>
1109                 </field>
1110             ');
1111             $this->_backend->addCol('tree_nodes', $declaration);
1112             $this->setTableVersion('tree_nodes', 3);
1113         }
1114     }
1115
1116     /**
1117      * update to 10.26
1118      *
1119      * add scope column to importexport_definition
1120      */
1121     public function update_25()
1122     {
1123         if (! $this->_backend->columnExists('scope', 'importexport_definition')) {
1124             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
1125                     <name>scope</name>
1126                     <type>text</type>
1127                     <length>255</length>
1128                 </field>');
1129             $this->_backend->addCol('importexport_definition', $declaration);
1130
1131             $this->setTableVersion('importexport_definition', 10);
1132         }
1133
1134         $this->setApplicationVersion('Tinebase', '10.26');
1135     }
1136
1137     /**
1138      * update to 10.27
1139      *
1140      * change role_accounts id to uuid
1141      */
1142     public function update_26()
1143     {
1144         $declaration = new Setup_Backend_Schema_Field_Xml('<field>
1145                     <name>id</name>
1146                     <type>text</type>
1147                     <length>40</length>
1148                 </field>');
1149         $this->_backend->alterCol('role_accounts', $declaration);
1150
1151         $this->setTableVersion('role_accounts', 4);
1152         $this->setApplicationVersion('Tinebase', '10.27');
1153     }
1154
1155     /**
1156      * update to 10.28
1157      *
1158      * add scope column to importexport_definition
1159      */
1160     public function update_27()
1161     {
1162         if (! $this->_backend->columnExists('format', 'importexport_definition')) {
1163             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
1164                     <name>format</name>
1165                     <type>text</type>
1166                     <length>255</length>
1167                 </field>');
1168             $this->_backend->addCol('importexport_definition', $declaration);
1169
1170             $this->setTableVersion('importexport_definition', 11);
1171         }
1172
1173         $this->setApplicationVersion('Tinebase', '10.28');
1174     }
1175
1176     /**
1177      * update to 10.29
1178      *
1179      * add scope column to importexport_definition
1180      */
1181     public function update_28()
1182     {
1183         $this->_addIsDeletedToTreeNodes();
1184
1185         foreach (Tinebase_Application::getInstance()->getApplications() as $application) {
1186             Setup_Controller::getInstance()->createImportExportDefinitions($application);
1187         }
1188
1189         $this->setApplicationVersion('Tinebase', '10.29');
1190     }
1191
1192     /**
1193      * update to 10.30
1194      *
1195      * add scope column to importexport_definition
1196      */
1197     public function update_29()
1198     {
1199         $this->_backend->dropIndex('record_observer', 'observable-observer-event');
1200
1201         $this->_backend->alterCol('record_observer', new Setup_Backend_Schema_Field_Xml('<field>
1202                     <name>observable_identifier</name>
1203                     <type>text</type>
1204                     <length>40</length>
1205                     <notnull>false</notnull>
1206                 </field>'));
1207
1208         $this->_backend->addIndex('record_observer', new Setup_Backend_Schema_Index_Xml('<index>
1209                     <name>observable-observer-event</name>
1210                     <unique>true</unique>
1211                     <field>
1212                         <name>observable_model</name>
1213                     </field>
1214                     <field>
1215                         <name>observed_event</name>
1216                     </field>
1217                     <field>
1218                         <name>observable_identifier</name>
1219                     </field>
1220                     <field>
1221                         <name>observer_model</name>
1222                     </field>
1223                     <field>
1224                         <name>observer_identifier</name>
1225                     </field>
1226                 </index>'));
1227
1228         $this->setTableVersion('record_observer', 5);
1229
1230         $this->setApplicationVersion('Tinebase', '10.30');
1231     }
1232
1233     /**
1234      * update to 10.31
1235      *
1236      * add is_deleted column to tree nodes
1237      */
1238     public function update_30()
1239     {
1240         $this->_addIsDeletedToTreeNodes();
1241
1242         $this->setApplicationVersion('Tinebase', '10.31');
1243     }
1244
1245     protected function _addIsDeletedToTreeNodes()
1246     {
1247         if (! $this->_backend->columnExists('is_deleted', 'tree_nodes')) {
1248             $declaration = new Setup_Backend_Schema_Field_Xml('<field>
1249                     <name>is_deleted</name>
1250                     <type>boolean</type>
1251                     <default>false</default>
1252                     <notnull>true</notnull>
1253                 </field>');
1254             $this->_backend->addCol('tree_nodes', $declaration);
1255
1256             $this->setTableVersion('tree_nodes', 4);
1257         }
1258     }
1259
1260     /**
1261      * update to 10.32
1262      *
1263      * change container id from int to uuid
1264      */
1265     public function update_31()
1266     {
1267         //ATTENTION foreign constraints
1268
1269         try {
1270             $this->_backend->dropForeignKey('container_acl', 'container_acl::container_id--container::id');
1271         } catch (Exception $e) {}
1272         try {
1273             $this->_backend->dropForeignKey('container_content', 'container_content::container_id--container::id');
1274         } catch (Exception $e) {}
1275
1276         if ($this->_backend->tableExists('addressbook')) {
1277             try {
1278                 $this->_backend->dropForeignKey('addressbook', 'addressbook::container_id--container::id');
1279             } catch (Exception $e) {}
1280         }
1281         if ($this->_backend->tableExists('cal_events')) {
1282             try {
1283                 $this->_backend->dropForeignKey('cal_events', 'cal_events::container_id--container::id');
1284             } catch (Exception $e) {}
1285         }
1286         if ($this->_backend->tableExists('cal_resources')) {
1287             try {
1288                 $this->_backend->dropForeignKey('cal_resources', 'cal_resources::container_id--container::id');
1289             } catch (Exception $e) {}
1290         }
1291         if ($this->_backend->tableExists('cal_attendee')) {
1292             try {
1293                 $this->_backend->dropForeignKey('cal_attendee', 'cal_attendee::displaycontainer_id--container::id');
1294             } catch (Exception $e) {}
1295         }
1296         if ($this->_backend->tableExists('metacrm_lead')) {
1297             try {
1298                 $this->_backend->dropForeignKey('metacrm_lead', 'metacrm_lead::container_id--container::id');
1299             } catch (Exception $e) {}
1300         }
1301         if ($this->_backend->tableExists('sales_contracts')) {
1302             try {
1303                 $this->_backend->dropForeignKey('sales_contracts', 'sales_contracts::container_id--container::id');
1304             } catch (Exception $e) {}
1305         }
1306         if ($this->_backend->tableExists('timetracker_timeaccount')) {
1307             try {
1308                 $this->_backend->dropForeignKey('timetracker_timeaccount', 'timeaccount::container_id--container::id');
1309             } catch (Exception $e) {}
1310         }
1311
1312         if (version_compare($this->getApplicationVersion('Tinebase'), '10.32') < 0 ) {
1313             if ($this->getTableVersion('container') < 13) {
1314                 $this->_backend->alterCol('container', new Setup_Backend_Schema_Field_Xml('<field>
1315                             <name>id</name>
1316                             <type>text</type>
1317                             <length>40</length>
1318                             <notnull>true</notnull>
1319                         </field>'));
1320                 $this->setTableVersion('container', 13);
1321             }
1322
1323             if ($this->getTableVersion('container_acl') < 4) {
1324                 $this->_backend->alterCol('container_acl', new Setup_Backend_Schema_Field_Xml('<field>
1325                             <name>container_id</name>
1326                             <type>text</type>
1327                             <length>40</length>
1328                             <notnull>true</notnull>
1329                         </field>'));
1330                 $this->setTableVersion('container_acl', 4);
1331             }
1332
1333             if ($this->getTableVersion('container_content') < 3) {
1334                 $this->_backend->alterCol('container_content', new Setup_Backend_Schema_Field_Xml('<field>
1335                             <name>container_id</name>
1336                             <type>text</type>
1337                             <length>40</length>
1338                             <notnull>true</notnull>
1339                         </field>'));
1340                 $this->setTableVersion('container_content', 3);
1341             }
1342         }
1343
1344         if (version_compare($this->getApplicationVersion('Addressbook'), '10.6') < 0 ) {
1345             if ($this->getTableVersion('addressbook') < 25) {
1346                 $this->_backend->alterCol('addressbook', new Setup_Backend_Schema_Field_Xml('<field>
1347                     <name>container_id</name>
1348                     <type>text</type>
1349                     <length>40</length>
1350                     <notnull>false</notnull>
1351                 </field>'));
1352                 $this->setTableVersion('addressbook', 25);
1353             }
1354
1355             if ($this->getTableVersion('addressbook_lists') < 6) {
1356                 $this->_backend->alterCol('addressbook_lists', new Setup_Backend_Schema_Field_Xml('<field>
1357                     <name>container_id</name>
1358                     <type>text</type>
1359                     <length>40</length>
1360                     <notnull>false</notnull>
1361                 </field>'));
1362                 $this->setTableVersion('addressbook_lists', 25);
1363             }
1364
1365             $this->setApplicationVersion('Addressbook', '10.6');
1366         }
1367
1368         if (Tinebase_Application::getInstance()->isInstalled('Calendar') &&
1369                 version_compare($this->getApplicationVersion('Calendar'), '10.8') < 0 ) {
1370             if ($this->getTableVersion('cal_events') < 14) {
1371                 $this->_backend->alterCol('cal_events', new Setup_Backend_Schema_Field_Xml('<field>
1372                     <name>container_id</name>
1373                     <type>text</type>
1374                     <length>40</length>
1375                     <notnull>false</notnull>
1376                 </field>'));
1377                 $this->setTableVersion('cal_events', 14);
1378             }
1379
1380             if ($this->getTableVersion('cal_attendee') < 6) {
1381                 $this->_backend->alterCol('cal_attendee', new Setup_Backend_Schema_Field_Xml('<field>
1382                     <name>displaycontainer_id</name>
1383                     <type>text</type>
1384                     <length>40</length>
1385                     <notnull>false</notnull>
1386                 </field>'));
1387                 $this->setTableVersion('cal_attendee', 6);
1388             }
1389
1390             if ($this->getTableVersion('cal_resources') < 6) {
1391                 $this->_backend->alterCol('cal_resources', new Setup_Backend_Schema_Field_Xml('<field>
1392                     <name>container_id</name>
1393                     <type>text</type>
1394                     <length>40</length>
1395                     <notnull>false</notnull>
1396                 </field>'));
1397                 $this->setTableVersion('cal_resources', 6);
1398             }
1399
1400             $this->setApplicationVersion('Calendar', '10.8');
1401         }
1402
1403         if (Tinebase_Application::getInstance()->isInstalled('Crm') &&
1404             version_compare($this->getApplicationVersion('Crm'), '10.2') < 0 ) {
1405             if ($this->getTableVersion('metacrm_lead') < 10) {
1406                 $this->_backend->alterCol('metacrm_lead', new Setup_Backend_Schema_Field_Xml('<field>
1407                     <name>container_id</name>
1408                     <type>text</type>
1409                     <length>40</length>
1410                     <notnull>false</notnull>
1411                 </field>'));
1412                 $this->setTableVersion('metacrm_lead', 10);
1413             }
1414             $this->setApplicationVersion('Crm', '10.2');
1415         }
1416
1417         if (Tinebase_Application::getInstance()->isInstalled('Events') &&
1418             version_compare($this->getApplicationVersion('Events'), '10.2') < 0 ) {
1419             if ($this->getTableVersion('events_event') < 3) {
1420                 $this->_backend->alterCol('events_event', new Setup_Backend_Schema_Field_Xml('<field>
1421                     <name>container_id</name>
1422                     <type>text</type>
1423                     <length>40</length>
1424                     <notnull>false</notnull>
1425                 </field>'));
1426                 $this->setTableVersion('events_event', 3);
1427             }
1428             $this->setApplicationVersion('Events', '10.2');
1429         }
1430
1431         if (Tinebase_Application::getInstance()->isInstalled('Projects') &&
1432             version_compare($this->getApplicationVersion('Projects'), '10.2') < 0 ) {
1433             if ($this->getTableVersion('projects_project') < 4) {
1434                 $this->_backend->alterCol('projects_project', new Setup_Backend_Schema_Field_Xml('<field>
1435                     <name>container_id</name>
1436                     <type>text</type>
1437                     <length>40</length>
1438                     <notnull>false</notnull>
1439                 </field>'));
1440                 $this->setTableVersion('projects_project', 4);
1441             }
1442             $this->setApplicationVersion('Projects', '10.2');
1443         }
1444
1445         if (Tinebase_Application::getInstance()->isInstalled('Sales') &&
1446             version_compare($this->getApplicationVersion('Sales'), '10.9') < 0 ) {
1447             if ($this->getTableVersion('sales_contracts') < 10) {
1448                 $this->_backend->alterCol('sales_contracts', new Setup_Backend_Schema_Field_Xml('<field>
1449                     <name>container_id</name>
1450                     <type>text</type>
1451                     <length>40</length>
1452                     <notnull>true</notnull>
1453                 </field>'));
1454                 $this->setTableVersion('sales_contracts', 10);
1455             }
1456             $this->setApplicationVersion('Sales', '10.9');
1457         }
1458
1459         if (Tinebase_Application::getInstance()->isInstalled('SimpleFAQ') &&
1460             version_compare($this->getApplicationVersion('SimpleFAQ'), '10.1') < 0 ) {
1461             if ($this->getTableVersion('simple_faq') < 3) {
1462                 $this->_backend->alterCol('simple_faq', new Setup_Backend_Schema_Field_Xml('<field>
1463                     <name>container_id</name>
1464                     <type>text</type>
1465                     <length>40</length>
1466                     <notnull>false</notnull>
1467                 </field>'));
1468                 $this->setTableVersion('simple_faq', 3);
1469             }
1470             $this->setApplicationVersion('SimpleFAQ', '10.1');
1471         }
1472
1473         if (Tinebase_Application::getInstance()->isInstalled('Tasks') &&
1474             version_compare($this->getApplicationVersion('Tasks'), '10.2') < 0 ) {
1475             if ($this->getTableVersion('tasks') < 10) {
1476                 $this->_backend->alterCol('tasks', new Setup_Backend_Schema_Field_Xml('<field>
1477                     <name>container_id</name>
1478                     <type>text</type>
1479                     <length>40</length>
1480                     <notnull>false</notnull>
1481                 </field>'));
1482                 $this->setTableVersion('tasks', 10);
1483             }
1484             $this->setApplicationVersion('Tasks', '10.2');
1485         }
1486
1487         if (Tinebase_Application::getInstance()->isInstalled('Timetracker') &&
1488             version_compare($this->getApplicationVersion('Timetracker'), '10.3') < 0 ) {
1489             if ($this->getTableVersion('timetracker_timeaccount') < 12) {
1490                 $this->_backend->alterCol('timetracker_timeaccount', new Setup_Backend_Schema_Field_Xml('<field>
1491                     <name>container_id</name>
1492                     <type>text</type>
1493                     <length>40</length>
1494                     <notnull>false</notnull>
1495                 </field>'));
1496                 $this->setTableVersion('timetracker_timeaccount', 12);
1497             }
1498             $this->setApplicationVersion('Timetracker', '10.3');
1499         }
1500
1501         $this->_backend->addForeignKey('container_content', new Setup_Backend_Schema_Index_Xml('<index>
1502                     <name>container_content::container_id--container::id</name>
1503                     <field>
1504                         <name>container_id</name>
1505                     </field>
1506                     <foreign>true</foreign>
1507                     <reference>
1508                         <table>container</table>
1509                         <field>id</field>
1510                         <ondelete>cascade</ondelete>
1511                     </reference>
1512                 </index>'));
1513
1514         $this->_backend->addForeignKey('container_acl', new Setup_Backend_Schema_Index_Xml('<index>
1515                     <name>container_acl::container_id--container::id</name>
1516                     <field>
1517                         <name>container_id</name>
1518                     </field>
1519                     <foreign>true</foreign>
1520                     <reference>
1521                         <table>container</table>
1522                         <field>id</field>
1523                         <ondelete>cascade</ondelete>
1524                         <!-- add onupdate? -->
1525                     </reference>
1526                 </index>'));
1527
1528         if ($this->_backend->tableExists('timeaccount')) {
1529             $this->_backend->addForeignKey('timeaccount', new Setup_Backend_Schema_Index_Xml('<index>
1530                     <name>timeaccount::container_id--container::id</name>
1531                     <field>
1532                         <name>container_id</name>
1533                     </field>
1534                     <foreign>true</foreign>
1535                     <reference>
1536                         <table>container</table>
1537                         <field>id</field>
1538                     </reference>
1539                 </index>'));
1540         }
1541
1542         if ($this->_backend->tableExists('sales_contracts')) {
1543             $this->_backend->addForeignKey('sales_contracts', new Setup_Backend_Schema_Index_Xml('<index>
1544                     <name>sales_contracts::container_id--container::id</name>
1545                     <field>
1546                         <name>container_id</name>
1547                     </field>
1548                     <foreign>true</foreign>
1549                     <reference>
1550                         <table>container</table>
1551                         <field>id</field>
1552                     </reference>
1553                 </index>'));
1554         }
1555
1556         if ($this->_backend->tableExists('metacrm_lead')) {
1557             $this->_backend->addForeignKey('metacrm_lead', new Setup_Backend_Schema_Index_Xml('<index>
1558                     <name>metacrm_lead::container_id--container::id</name>
1559                     <field>
1560                         <name>container_id</name>
1561                     </field>
1562                     <foreign>true</foreign>
1563                     <reference>
1564                         <table>container</table>
1565                         <field>id</field>
1566                     </reference>
1567                 </index>'));
1568         }
1569
1570         if ($this->_backend->tableExists('cal_events')) {
1571             $this->_backend->addForeignKey('cal_events', new Setup_Backend_Schema_Index_Xml('<index>
1572                     <name>cal_resources::container_id--container::id</name>
1573                     <field>
1574                         <name>container_id</name>
1575                     </field>
1576                     <foreign>true</foreign>
1577                     <reference>
1578                         <table>container</table>
1579                         <field>id</field>
1580                     </reference>
1581                 </index>'));
1582         }
1583
1584         if ($this->_backend->tableExists('cal_events')) {
1585             $this->_backend->addForeignKey('cal_events', new Setup_Backend_Schema_Index_Xml('<index>
1586                     <name>cal_events::container_id--container::id</name>
1587                     <field>
1588                         <name>container_id</name>
1589                     </field>
1590                     <foreign>true</foreign>
1591                     <reference>
1592                         <table>container</table>
1593                         <field>id</field>
1594                     </reference>
1595                 </index>'));
1596         }
1597
1598         if ($this->_backend->tableExists('cal_attendee')) {
1599             $this->_backend->addForeignKey('cal_attendee', new Setup_Backend_Schema_Index_Xml('<index>
1600                     <name>cal_attendee::displaycontainer_id--container::id</name>
1601                     <field>
1602                         <name>displaycontainer_id</name>
1603                     </field>
1604                     <foreign>true</foreign>
1605                     <reference>
1606                         <table>container</table>
1607                         <field>id</field>
1608                     </reference>
1609                 </index>'));
1610         }
1611
1612         if ($this->_backend->tableExists('addressbook')) {
1613             $this->_backend->addForeignKey('addressbook', new Setup_Backend_Schema_Index_Xml('<index>
1614                     <name>addressbook::container_id--container::id</name>
1615                     <field>
1616                         <name>container_id</name>
1617                     </field>
1618                     <foreign>true</foreign>
1619                     <reference>
1620                         <table>container</table>
1621                         <field>id</field>
1622                     </reference>
1623                 </index>'));
1624         }
1625
1626         $this->setApplicationVersion('Tinebase', '10.32');
1627     }
1628
1629     /**
1630      * update to 10.33
1631      *
1632      * change role id from int to uuid
1633      */
1634     public function update_32()
1635     {
1636         try {
1637             $this->_backend->dropForeignKey('role_rights', 'role_rights::role_id--roles::id');
1638         } catch (Exception $e) {}
1639         try {
1640             $this->_backend->dropForeignKey('role_accounts', 'role_accounts::role_id--roles::id');
1641         } catch (Exception $e) {}
1642
1643         if ($this->getTableVersion('roles') < 3) {
1644             $this->_backend->alterCol('roles', new Setup_Backend_Schema_Field_Xml('<field>
1645                             <name>id</name>
1646                             <type>text</type>
1647                             <length>40</length>
1648                             <notnull>true</notnull>
1649                         </field>'));
1650             $this->setTableVersion('roles', 3);
1651         }
1652
1653         if ($this->getTableVersion('role_rights') < 3) {
1654             $this->_backend->alterCol('role_rights', new Setup_Backend_Schema_Field_Xml('<field>
1655                             <name>id</name>
1656                             <type>text</type>
1657                             <length>40</length>
1658                             <notnull>true</notnull>
1659                         </field>'));
1660
1661             $this->_backend->alterCol('role_rights', new Setup_Backend_Schema_Field_Xml('<field>
1662                             <name>role_id</name>
1663                             <type>text</type>
1664                             <length>40</length>
1665                             <notnull>true</notnull>
1666                         </field>'));
1667             $this->setTableVersion('role_rights', 3);
1668         }
1669
1670         if ($this->getTableVersion('role_accounts') < 5) {
1671             $this->_backend->alterCol('role_accounts', new Setup_Backend_Schema_Field_Xml('<field>
1672                             <name>role_id</name>
1673                             <type>text</type>
1674                             <length>40</length>
1675                             <notnull>true</notnull>
1676                         </field>'));
1677             $this->setTableVersion('role_accounts', 5);
1678         }
1679
1680         if ($this->_backend->tableExists('role_rights')) {
1681             $this->_backend->addForeignKey('role_rights', new Setup_Backend_Schema_Index_Xml('<index>
1682                     <name>role_rights::role_id--roles::id</name>
1683                     <field>
1684                         <name>role_id</name>
1685                     </field>
1686                     <foreign>true</foreign>
1687                     <reference>
1688                         <table>roles</table>
1689                         <field>id</field>
1690                         <ondelete>cascade</ondelete>
1691                     </reference>
1692                 </index>'));
1693         }
1694
1695         if ($this->_backend->tableExists('role_accounts')) {
1696             $this->_backend->addForeignKey('role_accounts', new Setup_Backend_Schema_Index_Xml('<index>
1697                     <name>role_accounts::role_id--roles::id</name>
1698                     <field>
1699                         <name>role_id</name>
1700                     </field>
1701                     <foreign>true</foreign>
1702                     <reference>
1703                         <table>roles</table>
1704                         <field>id</field>
1705                         <ondelete>cascade</ondelete>
1706                     </reference>
1707                 </index>'));
1708         }
1709
1710         $this->setApplicationVersion('Tinebase', '10.33');
1711     }
1712 }