[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/vtlib/tools/ -> console.php (source)

   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  }


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1