[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /*+********************************************************************************** 3 * The contents of this file are subject to the vtiger CRM Public License Version 1.0 4 * ("License"); You may not use this file except in compliance with the License 5 * The Original Code is: vtiger CRM Open Source 6 * The Initial Developer of the Original Code is vtiger. 7 * Portions created by vtiger are Copyright (C) vtiger. 8 * All Rights Reserved. 9 ************************************************************************************/ 10 include_once ('vtlib/Vtiger/PackageImport.php'); 11 12 /** 13 * Provides API to update module into vtiger CRM 14 * @package vtlib 15 */ 16 class Vtiger_PackageUpdate extends Vtiger_PackageImport { 17 18 var $_migrationinfo = false; 19 20 /** 21 * Constructor 22 */ 23 function Vtiger_PackageUpdate() { 24 parent::__construct(); 25 } 26 27 /** 28 * Initialize Update 29 * @access private 30 */ 31 function initUpdate($moduleInstance, $zipfile, $overwrite) { 32 $module = $this->getModuleNameFromZip($zipfile); 33 34 if(!$moduleInstance || $moduleInstance->name != $module) { 35 self::log('Module name mismatch!'); 36 return false; 37 } 38 39 if($module != null) { 40 $unzip = new Vtiger_Unzip($zipfile, $overwrite); 41 42 // Unzip selectively 43 $unzip->unzipAllEx( ".", 44 Array( 45 'include' => Array('templates', "modules/$module", 'cron', 'languages', 46 'settings/actions', 'settings/views', 'settings/models', 'settings/templates', 'settings/connectors', 'settings/libraries'), 47 // DEFAULT: excludes all not in include 48 ), 49 50 Array(// Templates folder to be renamed while copying 51 'templates' => "layouts/vlayout/modules/$module", 52 53 // Cron folder 54 'cron' => "cron/modules/$module", 55 56 // Settings folder 57 'settings/actions' => "modules/Settings/$module/actions", 58 'settings/views' => "modules/Settings/$module/views", 59 'settings/models' => "modules/Settings/$module/models", 60 'settings/connectors' => "modules/Settings/$module/connectors", 61 'settings/libraries' => "modules/Settings/$module/libraries", 62 63 // Settings templates folder 64 'settings/templates' => "layouts/vlayout/modules/Settings/$module", 65 'settings' => "modules/Settings", 66 ) 67 ); 68 69 // If data is not yet available 70 if(empty($this->_modulexml)) { 71 $this->__parseManifestFile($unzip); 72 } 73 74 if($unzip) $unzip->close(); 75 } 76 return $module; 77 } 78 79 /** 80 * Update Module from zip file 81 * @param Vtiger_Module Instance of the module to update 82 * @param String Zip file name 83 * @param Boolean True for overwriting existing module 84 */ 85 function update($moduleInstance, $zipfile, $overwrite=true) { 86 87 $module = $this->getModuleNameFromZip($zipfile); 88 89 if($module != null) { 90 // If data is not yet available 91 if(empty($this->_modulexml)) { 92 $this->__parseManifestFile($unzip); 93 } 94 95 $buildModuleArray = array(); 96 $installSequenceArray = array(); 97 $moduleBundle = (boolean)$this->_modulexml->modulebundle; 98 if($moduleBundle == true) { 99 $moduleList = (Array)$this->_modulexml->modulelist; 100 foreach($moduleList as $moduleInfos) { 101 foreach($moduleInfos as $moduleInfo) { 102 $moduleInfo = (Array)$moduleInfo; 103 $buildModuleArray[] = $moduleInfo; 104 $installSequenceArray[] = $moduleInfo['install_sequence']; 105 } 106 } 107 sort($installSequenceArray); 108 $unzip = new Vtiger_Unzip($zipfile); 109 $unzip->unzipAllEx($this->getTemporaryFilePath()); 110 foreach ($installSequenceArray as $sequence) { 111 foreach ($buildModuleArray as $moduleInfo) { 112 if($moduleInfo['install_sequence'] == $sequence) { 113 $moduleInstance = Vtiger_Module::getInstance($moduleInfo['name']); 114 $this->update($moduleInstance, $this->getTemporaryFilePath($moduleInfo['filepath']), $overwrite); 115 } 116 } 117 } 118 } else { 119 if(!$moduleInstance || $moduleInstance->name != $module) { 120 self::log('Module name mismatch!'); 121 return false; 122 } 123 $module = $this->initUpdate($moduleInstance, $zipfile, $overwrite); 124 // Call module update function 125 $this->update_Module($moduleInstance); 126 } 127 } 128 } 129 130 /** 131 * Update Module 132 * @access private 133 */ 134 function update_Module($moduleInstance) { 135 $tabname = $this->_modulexml->name; 136 $tablabel= $this->_modulexml->label; 137 $parenttab=$this->_modulexml->parent; 138 $tabversion=$this->_modulexml->version; 139 140 $isextension= false; 141 if(!empty($this->_modulexml->type)) { 142 $type = strtolower($this->_modulexml->type); 143 if($type == 'extension' || $type == 'language') 144 $isextension = true; 145 } 146 147 Vtiger_Module::fireEvent($moduleInstance->name, 148 Vtiger_Module::EVENT_MODULE_PREUPDATE); 149 150 // TODO Handle module property changes like menu, label etc... 151 /*if(!empty($parenttab) && $parenttab != '') { 152 $menuInstance = Vtiger_Menu::getInstance($parenttab); 153 $menuInstance->addModule($moduleInstance); 154 }*/ 155 156 $this->handle_Migration($this->_modulexml, $moduleInstance); 157 158 $this->update_Tables($this->_modulexml); 159 $this->update_Blocks($this->_modulexml, $moduleInstance); 160 $this->update_CustomViews($this->_modulexml, $moduleInstance); 161 $this->update_SharingAccess($this->_modulexml, $moduleInstance); 162 $this->update_Events($this->_modulexml, $moduleInstance); 163 $this->update_Actions($this->_modulexml, $moduleInstance); 164 $this->update_RelatedLists($this->_modulexml, $moduleInstance); 165 $this->update_CustomLinks($this->_modulexml, $moduleInstance); 166 $this->update_CronTasks($this->_modulexml); 167 $moduleInstance->__updateVersion($tabversion); 168 169 Vtiger_Module::fireEvent($moduleInstance->name, 170 Vtiger_Module::EVENT_MODULE_POSTUPDATE); 171 } 172 173 /** 174 * Parse migration information from manifest 175 * @access private 176 */ 177 function parse_Migration($modulenode) { 178 if(!$this->_migrations) { 179 $this->_migrations = Array(); 180 if(!empty($modulenode->migrations) && 181 !empty($modulenode->migrations->migration)) { 182 foreach($modulenode->migrations->migration as $migrationnode) { 183 $migrationattrs = $migrationnode->attributes(); 184 $migrationversion = $migrationattrs['version']; 185 $this->_migrations["$migrationversion"] = $migrationnode; 186 } 187 } 188 // Sort the migration details based on version 189 if(count($this->_migrations) > 1) { 190 uksort($this->_migrations, 'version_compare'); 191 } 192 } 193 } 194 195 /** 196 * Handle migration of the module 197 * @access private 198 */ 199 function handle_Migration($modulenode, $moduleInstance) { 200 // TODO Handle module migration SQL 201 $this->parse_Migration($modulenode); 202 $cur_version = $moduleInstance->version; 203 foreach($this->_migrations as $migversion=>$migrationnode) { 204 // Perform migration only for higher version than current 205 if(version_compare($cur_version, $migversion, '<')) { 206 self::log("Migrating to $migversion ... STARTED"); 207 if(!empty($migrationnode->tables) && !empty($migrationnode->tables->table)) { 208 foreach($migrationnode->tables->table as $tablenode) { 209 $tablename = $tablenode->name; 210 $tablesql = "$tablenode->sql"; // Convert to string 211 212 // Skip SQL which are destructive 213 if(Vtiger_Utils::IsDestructiveSql($tablesql)) { 214 self::log("SQL: $tablesql ... SKIPPED"); 215 } else { 216 // Supress any SQL query failures 217 self::log("SQL: $tablesql ... ", false); 218 Vtiger_Utils::ExecuteQuery($tablesql, true); 219 self::log("DONE"); 220 } 221 } 222 } 223 self::log("Migrating to $migversion ... DONE"); 224 } 225 } 226 } 227 228 /** 229 * Update Tables of the module 230 * @access private 231 */ 232 function update_Tables($modulenode) { 233 $this->import_Tables($modulenode); 234 } 235 236 /** 237 * Update Blocks of the module 238 * @access private 239 */ 240 function update_Blocks($modulenode, $moduleInstance) { 241 if(empty($modulenode->blocks) || empty($modulenode->blocks->block)) return; 242 243 foreach($modulenode->blocks->block as $blocknode) { 244 $blockInstance = Vtiger_Block::getInstance((string)$blocknode->label, $moduleInstance); 245 if(!$blockInstance) { 246 $blockInstance = $this->import_Block($modulenode, $moduleInstance, $blocknode); 247 } else { 248 $this->update_Block($modulenode, $moduleInstance, $blocknode, $blockInstance); 249 } 250 251 $this->update_Fields($blocknode, $blockInstance, $moduleInstance); 252 } 253 } 254 255 /** 256 * Update Block of the module 257 * @access private 258 */ 259 function update_Block($modulenode, $moduleInstance, $blocknode, $blockInstance) { 260 // TODO Handle block property update 261 } 262 263 /** 264 * Update Fields of the module 265 * @access private 266 */ 267 function update_Fields($blocknode, $blockInstance, $moduleInstance) { 268 if(empty($blocknode->fields) || empty($blocknode->fields->field)) return; 269 270 foreach($blocknode->fields->field as $fieldnode) { 271 $fieldInstance = Vtiger_Field::getInstance((string)$fieldnode->fieldname, $moduleInstance); 272 if(!$fieldInstance) { 273 $fieldInstance = $this->import_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode); 274 } else { 275 $this->update_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode, $fieldInstance); 276 } 277 $this->__AddModuleFieldToCache($moduleInstance, $fieldInstance->name, $fieldInstance); 278 } 279 } 280 281 /** 282 * Update Field of the module 283 * @access private 284 */ 285 function update_Field($blocknode, $blockInstance, $moduleInstance, $fieldnode, $fieldInstance) { 286 // TODO Handle field property update 287 288 if(!empty($fieldnode->helpinfo)) $fieldInstance->setHelpInfo($fieldnode->helpinfo); 289 if(!empty($fieldnode->masseditable)) $fieldInstance->setMassEditable($fieldnode->masseditable); 290 if(!empty($fieldnode->summaryfield)) $fieldInstance->setSummaryField($fieldnode->summaryfield); 291 } 292 293 /** 294 * Import Custom views of the module 295 * @access private 296 */ 297 function update_CustomViews($modulenode, $moduleInstance) { 298 if(empty($modulenode->customviews) || empty($modulenode->customviews->customview)) return; 299 foreach($modulenode->customviews->customview as $customviewnode) { 300 $filterInstance = Vtiger_Filter::getInstance($customviewnode->viewname, $moduleInstance); 301 if(!$filterInstance) { 302 $filterInstance = $this->import_CustomView($modulenode, $moduleInstance, $customviewnode); 303 } else { 304 $this->update_CustomView($modulenode, $moduleInstance, $customviewnode, $filterInstance); 305 } 306 } 307 } 308 309 /** 310 * Update Custom View of the module 311 * @access private 312 */ 313 function update_CustomView($modulenode, $moduleInstance, $customviewnode, $filterInstance) { 314 // TODO Handle filter property update 315 $filterInstance->delete(); 316 $filterInstance = $this->import_CustomView($modulenode, $moduleInstance, $customviewnode); 317 } 318 319 /** 320 * Update Sharing Access of the module 321 * @access private 322 */ 323 function update_SharingAccess($modulenode, $moduleInstance) { 324 if(empty($modulenode->sharingaccess)) return; 325 326 // TODO Handle sharing access property update 327 } 328 329 /** 330 * Update Events of the module 331 * @access private 332 */ 333 function update_Events($modulenode, $moduleInstance) { 334 if(empty($modulenode->events) || empty($modulenode->events->event)) return; 335 336 if(Vtiger_Event::hasSupport()) { 337 foreach($modulenode->events->event as $eventnode) { 338 $this->update_Event($modulenode, $moduleInstance, $eventnode); 339 } 340 } 341 } 342 343 /** 344 * Update Event of the module 345 * @access private 346 */ 347 function update_Event($modulenode, $moduleInstance, $eventnode) { 348 //Vtiger_Event::register($moduleInstance, $eventnode->eventname, $eventnode->classname, $eventnode->filename); 349 // TODO Handle event property update 350 } 351 352 /** 353 * Update actions of the module 354 * @access private 355 */ 356 function update_Actions($modulenode, $moduleInstance) { 357 if(empty($modulenode->actions) || empty($modulenode->actions->action)) return; 358 foreach($modulenode->actions->action as $actionnode) { 359 $this->update_Action($modulenode, $moduleInstance, $actionnode); 360 } 361 } 362 363 /** 364 * Update action of the module 365 * @access private 366 */ 367 function update_Action($modulenode, $moduleInstance, $actionnode) { 368 // TODO Handle action property update 369 } 370 371 /** 372 * Update related lists of the module 373 * @access private 374 */ 375 function update_RelatedLists($modulenode, $moduleInstance) { 376 if(empty($modulenode->relatedlists) || empty($modulenode->relatedlists->relatedlist)) return; 377 $moduleInstance->deleteRelatedLists(); 378 foreach($modulenode->relatedlists->relatedlist as $relatedlistnode) { 379 $relModuleInstance = $this->update_Relatedlist($modulenode, $moduleInstance, $relatedlistnode); 380 } 381 } 382 383 /** 384 * Import related list of the module. 385 * @access private 386 */ 387 function update_Relatedlist($modulenode, $moduleInstance, $relatedlistnode) { 388 $relModuleInstance = Vtiger_Module::getInstance((string)$relatedlistnode->relatedmodule); 389 $label = $relatedlistnode->label; 390 $actions = false; 391 if(!empty($relatedlistnode->actions) && !empty($relatedlistnode->actions->action)) { 392 $actions = Array(); 393 foreach($relatedlistnode->actions->action as $actionnode) { 394 $actions[] = "$actionnode"; 395 } 396 } 397 if($relModuleInstance) { 398 $moduleInstance->unsetRelatedList($relModuleInstance, "$label", "$relatedlistnode->function"); 399 $moduleInstance->setRelatedList($relModuleInstance, "$label", $actions, "$relatedlistnode->function"); 400 } 401 return $relModuleInstance; 402 } 403 404 function update_CustomLinks($modulenode, $moduleInstance) { 405 if(empty($modulenode->customlinks) || empty($modulenode->customlinks->customlink)) return; 406 $moduleInstance->deleteLinks(); 407 $this->import_CustomLinks($modulenode, $moduleInstance); 408 } 409 410 function update_CronTasks($modulenode) { 411 if(empty($modulenode->crons) || empty($modulenode->crons->cron)) return; 412 $cronTasks = Vtiger_Cron::listAllInstancesByModule($modulenode->name); 413 foreach ($modulenode->crons->cron as $importCronTask) { 414 foreach($cronTasks as $cronTask) { 415 if($cronTask->getName() == $importCronTask->name && $importCronTask->handler == $cronTask->getHandlerFile()) { 416 Vtiger_Cron::deregister($importCronTask->name); 417 } 418 } 419 if(empty($importCronTask->status)){ 420 $cronTask->status = Vtiger_Cron::$STATUS_DISABLED; 421 } else { 422 $cronTask->status = Vtiger_Cron::$STATUS_ENABLED; 423 } 424 if((empty($importCronTask->sequence))){ 425 $importCronTask->sequence=Vtiger_Cron::nextSequence(); 426 } 427 Vtiger_Cron::register("$importCronTask->name","$importCronTask->handler", "$importCronTask->frequency", "$modulenode->name","$importCronTask->status","$importCronTask->sequence","$importCronTask->description"); 428 } 429 } 430 } 431 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |