[ 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 11 chdir(dirname(__FILE__) . '/../..'); 12 include_once 'vtlib/Vtiger/Module.php'; 13 include_once 'vtlib/Vtiger/Package.php'; 14 include_once 'includes/main/WebUI.php'; 15 16 include_once 'include/Webservices/Utils.php'; 17 18 class Vtiger_Tools_Console_Controller { 19 const PROMPT_ANY = 1; 20 const PROMPT_OPTIONAL = 2; 21 const PROMPT_NUMERIC = 3; 22 const PROMPT_ALPHANUMERIC = 4; 23 const PROMPT_NAME = 5; 24 const PROMPT_LABEL = 6; 25 const PROMPT_PATH = 7; 26 27 protected $interactive = true; 28 protected $arguments = array(); 29 30 protected function __construct() { } 31 32 public function setArguments($args, $interactive) { 33 $this->arguments = $args; 34 $this->interactive = $interactive; 35 return $this; 36 } 37 38 protected function handle() { 39 global $argv; 40 $this->arguments = $argv; 41 42 // Discard the script name. 43 array_shift($this->arguments); 44 45 if ($this->arguments) { 46 $this->arguments = explode('=', $this->arguments[0]); 47 $this->interactive = false; 48 } 49 50 $this->welcome(); 51 $this->options(); 52 } 53 54 protected function welcome() { 55 if ($this->interactive) { 56 echo "Welcome to Vtiger CRM Creator.\n"; 57 echo "This tool will enable you to get started with developing extensions with ease.\n"; 58 echo "Have a good time. Press CTRL+C to \"quit\".\n"; 59 } 60 } 61 62 protected function options() { 63 if ($this->interactive) { 64 echo "Choose the options below:\n"; 65 echo "1. Create New Module.\n"; 66 echo "2. Create New Layout.\n"; 67 echo "3. Create New Language Pack.\n"; 68 echo "4. Create Test Language Pack.\n"; 69 echo "5. Import Module.\n"; 70 echo "6. Update Module.\n"; 71 echo "7. Remove Module.\n"; 72 $option = $this->prompt("Enter your choice: ", self::PROMPT_NUMERIC); 73 } else { 74 $option = array_shift($this->arguments); 75 switch ($option) { 76 case '--import': $option = 5; break; 77 case '--update': $option = 6; break; 78 case '--remove': $option = 7; break; 79 } 80 } 81 82 try { 83 switch (intval($option)) { 84 case 1: $this->handleCreateModule(); break; 85 case 2: $this->handleCreateLayout(); break; 86 case 3: $this->handleCreateLanguage(); break; 87 case 4: $this->handleCreateTestLanguage(); break; 88 case 5: $this->handleImportModule(); break; 89 case 6: $this->handleUpdateModule(); break; 90 case 7: $this->handleRemoveModule(); break; 91 } 92 } catch (Exception $e) { 93 echo "ERROR: " .$e->getMessage() . "\n"; 94 echo $e->getTraceAsString(); 95 echo "\n"; 96 } 97 } 98 99 protected function prompt($msg='', $type=self::PROMPT_ANY) { 100 do { 101 if ($msg) echo $msg; 102 $value = trim(fgets(STDIN)); 103 104 if (!$value && $type == self::PROMPT_OPTIONAL) { 105 return $value; 106 107 } else if ($value) { 108 109 switch ($type) { 110 case self::PROMPT_NUMERIC: 111 if (is_numeric($value)) { 112 return $value; 113 } 114 break; 115 case self::PROMPT_ALPHANUMERIC: 116 if (!preg_match("/^[a-zA-Z0-9]+$/", $value)) { 117 return $value; 118 } 119 break; 120 case self::PROMPT_NAME: 121 if (!preg_match("/^[a-zA-Z][^a-zA-Z0-9_ ]*$/", $value)) { 122 return $value; 123 } 124 break; 125 case self::PROMPT_LABEL: 126 if (!preg_match("/^[a-zA-Z0-9_ ]+$/", $value)) { 127 return $value; 128 } 129 break; 130 case self::PROMPT_PATH: 131 if (!preg_match("/^[a-zA-Z0-9_:+.-\/\\\\]+$/", $value)) { 132 return $value; 133 } 134 default: 135 return $value; 136 } 137 } 138 } while (true); 139 } 140 141 protected function toAlphaNumeric($value) { 142 return preg_replace("/[^a-zA-Z0-9_]/", "", $value); 143 } 144 145 protected function findFiles($dir, $file_pattern, &$files) { 146 $items = glob($dir . '/*', GLOB_NOSORT); 147 foreach ($items as $item) { 148 if (is_file($item)) { 149 if (!$file_pattern || preg_match("/$file_pattern/", $item)) { 150 $files[] = $item; 151 } 152 } else if (is_dir($item) && ($dir != $item)) { 153 $this->findFiles($item, $file_pattern, $files); 154 } 155 } 156 } 157 158 // Option Handlers 159 protected function handleCreateModule() { 160 $controller = new Vtiger_Tools_Console_ModuleController(); 161 $controller->setArguments($this->arguments, $this->interactive)->handle(); 162 } 163 164 protected function handleCreateLanguage() { 165 $controller = new Vtiger_Tools_Console_LanguageController(); 166 $controller->setArguments($this->arguments, $this->interactive)->handle(); 167 } 168 169 protected function handleCreateTestLanguage() { 170 $controller = new Vtiger_Tools_Console_TestLanguageController(); 171 $controller->setArguments($this->arguments, $this->interactive)->handle(); 172 } 173 174 protected function handleCreateLayout() { 175 $controller = new Vtiger_Tools_Console_LayoutController(); 176 $controller->setArguments($this->arguments, $this->interactive)->handle(); 177 } 178 179 protected function handleImportModule() { 180 $controller = new Vtiger_Tools_Console_ImportController(); 181 $controller->setArguments($this->arguments, $this->interactive)->handle(); 182 } 183 184 protected function handleUpdateModule() { 185 $controller = new Vtiger_Tools_Console_UpdateController(); 186 $controller->setArguments($this->arguments, $this->interactive)->handle(); 187 } 188 189 protected function handleRemoveModule() { 190 $controller = new Vtiger_Tools_Console_RemoveController(); 191 $controller->setArguments($this->arguments, $this->interactive)->handle(); 192 } 193 194 // Static 195 public static function run() { 196 $singleton = new self(); 197 $singleton->handle(); 198 } 199 } 200 201 class Vtiger_Tools_Console_ModuleController extends Vtiger_Tools_Console_Controller { 202 203 public function handle() { 204 echo ">>> MODULE <<<\n"; 205 206 $moduleInformation = array(); 207 do { 208 $moduleInformation['name'] = ucwords($this->prompt("Enter module name: ", self::PROMPT_NAME)); 209 $module = $this->find($moduleInformation['name']); 210 if (!$module) { 211 break; 212 } 213 echo "ERROR: " . $moduleInformation['name'] . " module already exists, try another.\n"; 214 } while (true); 215 216 $moduleInformation['entityfieldlabel'] = 'Name'; 217 218 $entityfieldlabel = ucwords($this->prompt(sprintf("Entity field (%s): ", 219 $moduleInformation['entityfieldlabel']), self::PROMPT_OPTIONAL)); 220 if ($entityfieldlabel) { 221 $moduleInformation['entityfieldlael'] = $entityfieldlabel; 222 } 223 224 echo "Creating ..."; 225 $this->create($moduleInformation); 226 echo "DONE.\n"; 227 } 228 229 public function find($name) { 230 return Vtiger_Module::getInstance($name); 231 } 232 233 protected function create($moduleInformation) { 234 $moduleInformation['entityfieldname'] = strtolower($this->toAlphaNumeric($moduleInformation['entityfieldlabel'])); 235 236 $module = new Vtiger_Module(); 237 $module->name = $moduleInformation['name']; 238 $module->save(); 239 240 $module->initTables(); 241 242 $block = new Vtiger_Block(); 243 $block->label = 'LBL_'. strtoupper($module->name) . '_INFORMATION'; 244 $module->addBlock($block); 245 246 $blockcf = new Vtiger_Block(); 247 $blockcf->label = 'LBL_CUSTOM_INFORMATION'; 248 $module->addBlock($blockcf); 249 250 $field1 = new Vtiger_Field(); 251 $field1->name = $moduleInformation['entityfieldname']; 252 $field1->label= $moduleInformation['entityfieldlabel']; 253 $field1->uitype= 2; 254 $field1->column = $field1->name; 255 $field1->columntype = 'VARCHAR(255)'; 256 $field1->typeofdata = 'V~M'; 257 $block->addField($field1); 258 259 $module->setEntityIdentifier($field1); 260 261 /** Common fields that should be in every module, linked to vtiger CRM core table */ 262 $field2 = new Vtiger_Field(); 263 $field2->name = 'assigned_user_id'; 264 $field2->label = 'Assigned To'; 265 $field2->table = 'vtiger_crmentity'; 266 $field2->column = 'smownerid'; 267 $field2->uitype = 53; 268 $field2->typeofdata = 'V~M'; 269 $block->addField($field2); 270 271 $field3 = new Vtiger_Field(); 272 $field3->name = 'CreatedTime'; 273 $field3->label= 'Created Time'; 274 $field3->table = 'vtiger_crmentity'; 275 $field3->column = 'createdtime'; 276 $field3->uitype = 70; 277 $field3->typeofdata = 'T~O'; 278 $field3->displaytype= 2; 279 $block->addField($field3); 280 281 $field4 = new Vtiger_Field(); 282 $field4->name = 'ModifiedTime'; 283 $field4->label= 'Modified Time'; 284 $field4->table = 'vtiger_crmentity'; 285 $field4->column = 'modifiedtime'; 286 $field4->uitype = 70; 287 $field4->typeofdata = 'T~O'; 288 $field4->displaytype= 2; 289 $block->addField($field4); 290 291 // Create default custom filter (mandatory) 292 $filter1 = new Vtiger_Filter(); 293 $filter1->name = 'All'; 294 $filter1->isdefault = true; 295 $module->addFilter($filter1); 296 // Add fields to the filter created 297 $filter1->addField($field1)->addField($field2, 1)->addField($field3, 2); 298 299 // Set sharing access of this module 300 $module->setDefaultSharing(); 301 302 // Enable and Disable available tools 303 $module->enableTools(Array('Import', 'Export', 'Merge')); 304 305 // Initialize Webservice support 306 $module->initWebservice(); 307 308 // Create files 309 $this->createFiles($module, $field1); 310 } 311 312 protected function createFiles(Vtiger_Module $module, Vtiger_Field $entityField) { 313 $targetpath = 'modules/' . $module->name; 314 315 if (!is_file($targetpath)) { 316 mkdir($targetpath); 317 mkdir($targetpath . '/language'); 318 319 $templatepath = 'vtlib/ModuleDir/6.0.0'; 320 321 $moduleFileContents = file_get_contents($templatepath . '/ModuleName.php'); 322 $replacevars = array( 323 'ModuleName' => $module->name, 324 '<modulename>' => strtolower($module->name), 325 '<entityfieldlabel>' => $entityField->label, 326 '<entitycolumn>' => $entityField->column, 327 '<entityfieldname>' => $entityField->name, 328 ); 329 330 foreach ($replacevars as $key => $value) { 331 $moduleFileContents = str_replace($key, $value, $moduleFileContents); 332 } 333 file_put_contents($targetpath.'/'.$module->name.'.php', $moduleFileContents); 334 } 335 } 336 337 } 338 339 class Vtiger_Tools_Console_LayoutController extends Vtiger_Tools_Console_Controller { 340 341 // Similar grouped patterns to identify the line on which tpl filename is specified. 342 const VIEWERREGEX = '/\$viewer->(view|fetch)[^\(]*\(([^\)]+)/'; 343 const RETURNTPLREGEX = '/(return)([ ]+[\'"]+[^;]+)/'; 344 345 const TPLREGEX = '/[\'"]([^\'"]+)/'; 346 347 public function handle() { 348 echo ">>> LAYOUT <<<\n"; 349 350 $layoutInformation = array(); 351 do { 352 $layoutInformation['name'] = strtolower($this->prompt("Enter layout name: ", self::PROMPT_NAME)); 353 if (!file_exists( 'layouts/' . $layoutInformation['name'])) { 354 break; 355 } 356 echo "ERROR: " . $layoutInformation['name'] . " already exists, try another.\n"; 357 } while (true); 358 359 echo "Creating ..."; 360 $this->create($layoutInformation); 361 echo "DONE.\n"; 362 } 363 364 protected function create($layoutInformation) { 365 $files = array(); 366 $this->findFiles( 'includes', '.php$', $files); 367 $this->findFiles( 'modules', '.php$', $files); 368 369 $layoutdir = 'layouts/' . $layoutInformation['name'] . '/'; 370 371 foreach ($files as $file) { 372 $tplfolder = $layoutdir . "modules/Vtiger"; 373 if (preg_match("/modules\/([^\/]+)\/([^\/]+)\//", $file, $fmatch)) { 374 $tplfolder = $layoutdir . "modules/" . $fmatch[1]; 375 if ($fmatch[1] == 'Settings') { 376 $tplfolder .= '/' . $fmatch[2]; 377 } 378 } 379 380 $tpls = array(); 381 $this->findTemplateNames($file, $tpls); 382 $tpls = array_unique($tpls); 383 384 if ($tpls) { 385 foreach ($tpls as $tpl) { 386 $tplname = basename($tpl, true); 387 // Fix sub-directory path 388 $tplpath = $tplfolder . '/'. substr($tpl, 0, strpos($tpl, $tplname)); 389 if (!file_exists($tplpath)) { 390 mkdir($tplpath, 0755, true); 391 } 392 if (!file_exists($tplpath.$tplname)) { 393 $initialContent = "{* License Text *}\n"; 394 // Enable debug to make it easy to implement. 395 $initialContent.= "{debug}{* REMOVE THIS LINE AFTER IMPLEMENTATION *}\n\n"; 396 file_put_contents($tplpath.$tplname, $initialContent); 397 } 398 file_put_contents($tplpath.$tplname, "{* $file *}\n", FILE_APPEND); 399 } 400 } 401 } 402 } 403 404 protected function findTemplateNames($file, &$tpls, $inreturn=false) { 405 $contents = file_get_contents($file); 406 407 $regex = $inreturn ? self::RETURNTPLREGEX : self::VIEWERREGEX; 408 if (preg_match_all($regex, $contents, $matches)) { 409 foreach ($matches[2] as $match) { 410 if (preg_match(self::TPLREGEX, $match, $matches2)) { 411 if (stripos($matches2[1], '.tpl') !== false) { 412 $tpls[] = $matches2[1]; 413 } 414 } 415 } 416 // Viewer files can also have return tpl calls - find them. 417 if (!$inreturn) { 418 $this->findTemplateNames($file, $tpls, true); 419 } 420 } 421 } 422 } 423 424 class Vtiger_Tools_Console_LanguageController extends Vtiger_Tools_Console_Controller { 425 426 const BASE_LANG_PREFIX = 'en_us'; 427 428 public function handle() { 429 echo ">>> LANGUAGE <<<\n"; 430 431 $languageInformation = array(); 432 do { 433 $languageInformation['prefix'] = strtolower($this->prompt("Enter (languagecode_countrycode): ", self::PROMPT_NAME)); 434 if (!file_exists( 'languages/' . $languageInformation['prefix'])) { 435 break; 436 } 437 echo "ERROR: " . $languageInformation['prefix'] . " already exists, try another.\n"; 438 } while (true); 439 440 echo "Creating ..."; 441 $this->create($languageInformation); 442 echo "DONE.\n"; 443 } 444 445 protected function create($languageInformation) { 446 $files = array(); 447 $this->findFiles( 'languages/'.self::BASE_LANG_PREFIX, '.php$', $files); 448 449 foreach ($files as $file) { 450 $filename = basename($file, true); 451 $dir = substr($file, 0, strpos($file, $filename)); 452 $dir = str_replace('languages/'.self::BASE_LANG_PREFIX, 'languages/'.$languageInformation['prefix'], $dir); 453 if (!file_exists($dir)) mkdir($dir); 454 455 if (isset($languageInformation['prefix_value'])) { 456 $contents = file_get_contents($file); 457 $contents = preg_replace("/(=>[^'\"]+['\"])(.*)/", sprintf('$1%s$2', $languageInformation['prefix_value']), $contents); 458 file_put_contents($dir.'/'.$filename, $contents); 459 } else { 460 copy($file, $dir.'/'.$filename); 461 } 462 } 463 } 464 465 protected function deploy($languageInformation) { 466 if (!isset($languageInformation['label'])) { 467 echo "Language label not specified."; 468 return; 469 } 470 471 $db = PearDatabase::getInstance(); 472 $check = $db->pquery('SELECT 1 FROM vtiger_language WHERE prefix=?', $languageInformation['prefix']); 473 if ($check && $db->num_rows($check)) { 474 ; 475 } else { 476 $db->pquery('INSERT INTO vtiger_language (id,name,prefix,label,lastupdated,isdefault,active) VALUES(?,?,?,?,?,?,?)', 477 array($db->getUniqueId('vtiger_language'), $languageInformation['label'], $languageInformation['prefix'], 478 $languageInformation['label'], date('Y-m-d H:i:s'), 0, 1)); 479 } 480 } 481 } 482 483 class Vtiger_Tools_Console_TestLanguageController extends Vtiger_Tools_Console_LanguageController { 484 485 public function handle() { 486 echo ">>> TEST LANGUAGE <<<\n"; 487 488 $languageInformation = array('label' => 'TEST', 'prefix' => 'te_st', 'prefix_value' => '✔ '); 489 490 echo "Creating ..."; 491 $this->create($languageInformation); 492 echo "DONE\n"; 493 494 echo "Deploying ..."; 495 $this->deploy($languageInformation); 496 echo "DONE.\n"; 497 } 498 } 499 500 class Vtiger_Tools_Console_ImportController extends Vtiger_Tools_Console_Controller { 501 502 public function handle() { 503 if ($this->interactive) { 504 echo ">>> IMPORT MODULE <<<\n"; 505 do { 506 $path = $this->prompt("Enter package path: ", self::PROMPT_PATH); 507 if (file_exists($path)) { 508 break; 509 } 510 echo "ERROR: " . $path . " - file not found, try another.\n"; 511 } while (true); 512 } else { 513 $path = array_shift($this->arguments); 514 } 515 516 if (file_exists($path)) { 517 $package = new Vtiger_Package(); 518 $module = $package->getModuleNameFromZip($path); 519 520 $moduleInstance = Vtiger_Module::getInstance($module); 521 if ($moduleInstance) { 522 echo "ERROR: Module $module already exists!\n"; 523 } else { 524 echo "Importing ..."; 525 $package->import($path); 526 echo "DONE.\n"; 527 } 528 529 } else { 530 throw new Exception("Package file $path not found."); 531 } 532 533 } 534 } 535 536 class Vtiger_Tools_Console_UpdateController extends Vtiger_Tools_Console_Controller { 537 538 public function handle() { 539 if ($this->interactive) { 540 echo ">>> UPDATE MODULE <<<\n"; 541 do { 542 $path = $this->prompt("Enter package path: ", self::PROMPT_PATH); 543 if (file_exists($path)) { 544 break; 545 } 546 echo "ERROR: " . $path . " - file not found, try another.\n"; 547 } while (true); 548 } else { 549 $path = array_shift($this->arguments); 550 } 551 552 if (file_exists($path)) { 553 $package = new Vtiger_Package(); 554 $module = $package->getModuleNameFromZip($path); 555 556 $moduleInstance = Vtiger_Module::getInstance($module); 557 if (!$moduleInstance) { 558 echo "ERROR: Module $module not found!\n"; 559 } else { 560 echo "Updating ..."; 561 $package->update($moduleInstance, $path); 562 echo "DONE.\n"; 563 } 564 565 } else { 566 throw new Exception("Package file $path not found."); 567 } 568 569 } 570 } 571 572 class Vtiger_Tools_Console_RemoveController extends Vtiger_Tools_Console_Controller { 573 574 public function handle() { 575 if ($this->interactive) { 576 echo ">>> REMOVE MODULE <<<\n"; 577 do { 578 $module = $this->prompt("Enter module name: ", self::PROMPT_NAME); 579 $moduleInstance = Vtiger_Module::getInstance($module); 580 if (!$moduleInstance) { 581 echo "ERROR: Module $module not found, try another.\n"; 582 } else { 583 echo "Removing ..."; 584 $moduleInstance->delete(); 585 echo "DONE.\n"; 586 } 587 } while (true); 588 } else { 589 $module = array_shift($this->arguments); 590 $moduleInstance = Vtiger_Module::getInstance($module); 591 if (!$moduleInstance) { 592 echo "ERROR: Module $module not found!\n"; 593 } else { 594 echo "Removing ..."; 595 $moduleInstance->delete(); 596 echo "DONE.\n"; 597 } 598 } 599 } 600 } 601 602 if (php_sapi_name() == 'cli') { 603 Vtiger_Tools_Console_Controller::run(); 604 } else { 605 echo "Usage: php -f vtlib/tools/creator.php"; 606 }
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 |