2 /*********************************************************************************
3 * SugarCRM Community Edition is a customer relationship management program developed by
4 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6 * This program is free software; you can redistribute it and/or modify it under
7 * the terms of the GNU Affero General Public License version 3 as published by the
8 * Free Software Foundation with the addition of the following permission added
9 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
18 * You should have received a copy of the GNU Affero General Public License along with
19 * this program; if not, see http://www.gnu.org/licenses or write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26 * The interactive user interfaces in modified source and object code versions
27 * of this program must display Appropriate Legal Notices, as required under
28 * Section 5 of the GNU Affero General Public License version 3.
30 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31 * these Appropriate Legal Notices must retain the display of the "Powered by
32 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33 * technical reasons, the Appropriate Legal Notices must display the words
34 * "Powered by SugarCRM".
35 ********************************************************************************/
37 define ( 'MB_TEMPLATES', 'include/SugarObjects/templates' ) ;
38 define ( 'MB_IMPLEMENTS', 'include/SugarObjects/implements' ) ;
39 require_once ('modules/ModuleBuilder/MB/MBVardefs.php') ;
40 require_once ('modules/ModuleBuilder/MB/MBRelationship.php') ;
41 require_once ('modules/ModuleBuilder/MB/MBLanguage.php') ;
46 public $config = array (
47 'assignable' => 1 , 'acl' => 1 , 'has_tab' => 1 , 'studio' => 1 , 'audit' => 1 ) ;
48 public $mbpublicdefs ;
49 public $errors = array ( ) ;
51 public $implementable = array (
52 'has_tab' => 'Navigation Tab' ) ;
53 public $always_implement = array ( 'assignable' => 'Assignable' , 'acl' => 'Access Controls' , 'studio' => 'Studio Support' , 'audit' => 'Audit Table' ) ;
54 public $iTemplate = array (
57 public $config_md5 = null ;
59 function __construct ($name , $path , $package , $package_key)
62 $this->config [ 'templates' ] = array ( 'basic' => 1 ) ;
64 $this->name = MBModule::getDBName ( $name ) ;
65 $this->key_name = $package_key . '_' . $name ;
66 $this->package = $package ;
67 $this->package_key = $package_key ;
68 $this->package_path = $path ;
70 $this->implementable = array (
71 'has_tab' => !empty($mod_strings[ 'LBL_NAV_TAB' ]) ? $mod_strings[ 'LBL_NAV_TAB' ] : false) ;
72 $this->path = $this->getModuleDir () ;
73 // $this->mbrelationship = new MBRelationship($this->name, $this->path, $this->key_name);
74 $this->relationships = new UndeployedRelationships ( $this->path ) ;
75 $this->mbvardefs = new MBVardefs ( $this->name, $this->path, $this->key_name ) ;
80 function getDBName ($name)
82 return preg_replace ( "/[^\w]+/", "_", $name ) ;
85 function getModuleName()
90 function getPackageName()
92 return $this->package;
95 function getRelationships()
97 return $this->relationships;
101 * Loads the module based on the module name
106 if (file_exists ( $this->path . '/config.php' ))
108 include ($this->path . '/config.php') ;
109 $this->config = $config ;
111 $label = (! empty ( $this->config [ 'label' ] )) ? $this->config [ 'label' ] : $this->name ;
112 $this->mblanguage = new MBLanguage ( $this->name, $this->path, $label, $this->key_name ) ;
113 foreach ( $this->iTemplate as $temp )
115 if (! empty ( $this->config [ $temp ] ))
117 $this->mbvardefs->iTemplates [ $temp ] = 1 ;
118 $this->mblanguage->iTemplates [ $temp ] = $temp ;
121 $this->mbvardefs->templates = $this->config [ 'templates' ] ;
122 $this->mblanguage->templates = $this->config [ 'templates' ] ;
123 $this->mbvardefs->load () ;
124 $this->mblanguage->load () ;
128 function addTemplate ($template)
130 $this->config [ 'templates' ] [ $template ] = 1 ;
133 function getModuleDir ()
135 return $this->package_path . '/modules/' . $this->name ;
138 function removeTemplate ($template)
140 unset ( $this->config [ 'templates' ] [ $template ] ) ;
143 function getVardefs ($by_group = false)
145 $this->mbvardefs->updateVardefs ( $by_group ) ;
146 return $this->mbvardefs->getVardefs () ;
149 function addField ($vardef)
151 $this->mbvardefs->addFieldVardef ( $vardef ) ;
154 function addFieldObject ($field)
156 $vardef = $field->get_field_def () ;
157 $this->mbvardefs->mergeVardefs();
158 $existingVardefs = $this->mbvardefs->getVardefs () ;
159 //Merge with the existing vardef if it already exists
160 if(!empty($existingVardefs['fields'][$vardef['name']])){
161 $vardef = array_merge( $existingVardefs['fields'][$vardef['name']], $vardef);
163 if (! empty ( $vardef [ 'source' ] ) && $vardef [ 'source' ] == 'custom_fields')
164 unset ( $vardef [ 'source' ] ) ;
166 $this->mbvardefs->load();
167 $this->addField ( $vardef ) ;
168 $this->mbvardefs->save();
171 function deleteField ($name)
173 $this->mbvardefs->deleteField ( $name ) ;
176 function fieldExists ($name = '' , $type = '')
178 $vardefs = $this->mbvardefs->getVardef () ;
179 if (! empty ( $vardefs ))
181 if (empty ( $type ) && empty ( $name ))
182 return false ; else if (empty ( $type ))
183 return ! empty ( $vardefs [ 'fields' ] [ $name ] ) ; else if (empty ( $name ))
185 foreach ( $vardefs [ 'fields' ] as $def )
187 if ($def [ 'type' ] == $type)
192 return (! empty ( $vardefs [ 'fields' ] [ $name ] ) && ($vardefs [ 'fields' ] [ $name ] [ 'type' ] == $type)) ;
199 function getModStrings ($language = 'en_us')
201 return $this->mblanguage->getModStrings ( $language ) ;
204 function setModStrings ($language = 'en_us' , $mod_strings)
206 $language .= '.lang.php' ;
207 $this->mblanguage->strings [ $language ] = $mod_strings ;
210 function setLabel ($language = 'en_us' , $key , $value)
212 $language .= '.lang.php' ;
213 $this->mblanguage->strings [ $language ] [ $key ] = $value ;
214 //Ensure this key exists in all languages
215 foreach ($this->mblanguage->strings as $lang => $values) {
216 if (empty($values[$key])) {
217 $this->mblanguage->strings[$lang][$key] = $value;
222 function deleteLabel ($language = 'en_us' , $key)
224 foreach ($this->mblanguage->strings as $lang => $values) {
225 if (!empty($values[$key])) {
226 unset($this->mblanguage->strings[$lang][$key]);
232 * Required for an MB module to work with Dynamic fields
234 function addLabel ( $displayLabel)
236 $this->setLabel('en_us', $this->getDBName($displayLabel, false), translate($displayLabel));
240 function getLabel ($language = 'en_us' , $key)
242 $language .= '.lang.php' ;
243 if (empty ( $this->mblanguage->strings [ $language ] [ $key ] ))
248 return $this->mblanguage->strings [ $language ] [ $key ] ;
252 function getAppListStrings ($language = 'en_us')
254 return $this->mblanguage->getAppListStrings ( $language ) ;
257 function setAppListStrings ($language = 'en_us' , $app_list_strings)
259 $language .= '.lang.php' ;
260 $this->mblanguage->appListStrings [ $language ] = $app_list_strings ;
263 function setDropDown ($language = 'en_us' , $key , $value)
265 $language .= '.lang.php' ;
266 $this->mblanguage->appListStrings [ $language ] [ $key ] = $value ;
269 function deleteDropDown ($language = 'en_us' , $key)
271 $language .= '.lang.php' ;
272 unset ( $this->mblanguage->appListStrings [ $language ] [ $key ] ) ;
277 $this->path = $this->getModuleDir () ;
278 if (mkdir_recursive ( $this->path ))
281 $this->setConfigMD5 () ;
282 $old_config_md5 = $this->config_md5 ;
283 $this->saveConfig () ;
284 $this->getVardefs () ;
285 $this->mbvardefs->save ( $this->key_name ) ;
286 // $this->mbrelationship->save ( $this->key_name ) ;
287 $this->relationships->save () ;
288 $this->copyMetaData () ;
289 $this->copyDashlet () ;
291 if (0 != strcmp ( $old_config_md5, $this->config_md5 ))
293 $this->mblanguage->reload () ;
295 $this->mblanguage->label = $this->config [ 'label' ] ;
296 //pass in the key_name incase it has changed mblanguage will check if it is different and handle it accordingly
297 $this->mblanguage->save ( $this->key_name ) ;
299 if (! file_exists ( $this->package_path . "/icons/icon_" . ucfirst ( $this->key_name ) . ".gif" ))
301 $this->createIcon () ;
303 $this->errors = array_merge ( $this->errors, $this->mbvardefs->errors ) ;
308 function copyDashlet() {
309 $templates = array_reverse ( $this->config [ 'templates' ], true ) ;
310 foreach ( $templates as $template => $a )
312 if (file_exists ( MB_TEMPLATES . '/' . $template . '/Dashlets/Dashlet' ))
315 $this->copyMetaRecursive ( MB_TEMPLATES . '/' . $template . '/Dashlets/Dashlet', $this->path . '/Dashlets/' . $this->key_name . 'Dashlet/' ) ;
321 function copyViews() {
322 $templates = array_reverse ( $this->config [ 'templates' ], true ) ;
323 foreach ( $templates as $template => $a )
325 if (file_exists ( MB_TEMPLATES . '/' . $template . '/views' ))
327 $this->copyMetaRecursive ( MB_TEMPLATES . '/' . $template . '/views', $this->path . '/views/' ) ;
332 function copyCustomFiles ( $from , $to )
335 while ( $filename = $d->read () )
337 if (substr ( $filename, 0, 1 ) == '.')
339 if ( $filename != 'metadata' && $filename != 'Dashlets' && $filename != 'relationships' && $filename != 'language' && $filename != 'config.php' && $filename != 'relationships.php' && $filename != 'vardefs.php' )
340 copy_recursive ( "$from/$filename" , "$to/$filename" ) ;
344 function copyMetaData ()
346 $templates = array_reverse ( $this->config [ 'templates' ], true ) ;
347 foreach ( $templates as $template => $a )
349 if (file_exists ( MB_TEMPLATES . '/' . $template . '/metadata' ))
351 $this->copyMetaRecursive ( MB_TEMPLATES . '/' . $template . '/metadata', $this->path . '/metadata/' ) ;
357 function copyMetaRecursive ($from , $to , $overwrite = false)
359 if (! file_exists ( $from ))
361 if (is_dir ( $from ))
363 $findArray = array ( '<module_name>' , '<_module_name>' , '<MODULE_NAME>' , '<object_name>' , '<_object_name>' , '<OBJECT_NAME>' );
364 $replaceArray = array ( $this->key_name , strtolower ( $this->key_name ) , strtoupper ( $this->key_name ) ,
365 $this->key_name , strtolower ( $this->key_name ) , strtoupper ( $this->key_name ) );
366 mkdir_recursive ( $to ) ;
368 while ( $e = $d->read () )
370 if (substr ( $e, 0, 1 ) == '.')
372 $nfrom = $from . '/' . $e ;
373 $nto = $to . '/' . str_replace ( 'm-n-', $this->key_name, $e ) ;
374 if (is_dir ( $nfrom ))
376 $this->copyMetaRecursive ( $nfrom, $nto, $overwrite ) ;
379 if ($overwrite || ! file_exists ( $nto ))
381 $contents = file_get_contents ( $nfrom ) ;
382 $contents = str_replace ( $findArray, $replaceArray, $contents ) ;
383 $fw = sugar_fopen ( $nto, 'w' ) ;
384 fwrite ( $fw, $contents ) ;
393 function saveConfig ()
395 $header = file_get_contents ( 'modules/ModuleBuilder/MB/header.php' ) ;
396 if (! write_array_to_file ( 'config', $this->config, $this->path . '/config.php', 'w', $header ))
398 $this->errors [] = 'Could not save config to ' . $this->path . '/config.php' ;
400 $this->setConfigMD5 () ;
403 function setConfigMD5 ()
405 if (file_exists ( $this->path . '/config.php' ))
406 $this->config_md5 = md5 ( base64_encode ( serialize ( $this->config ) ) ) ;
409 function build ($basepath)
411 $path = $basepath . '/modules/' . $this->key_name ;
412 if (mkdir_recursive ( $path ))
414 $this->createClasses ( $path ) ;
415 if( $this->config['importable'] || in_array ( 'person', array_keys($this->config[ 'templates' ]) ) )
416 $this->createMenu ( $path ) ;
417 $this->copyCustomFiles ( $this->path , $path ) ;
418 $this->copyMetaRecursive ( $this->path . '/metadata/', $path . '/metadata/', true ) ;
419 $this->copyMetaRecursive ( $this->path . '/Dashlets/' . $this->key_name . 'Dashlet/',
420 $path . '/Dashlets/' . $this->key_name . 'Dashlet/', true ) ;
421 $this->relationships->build ( $basepath ) ;
422 $this->mblanguage->build ( $path ) ;
426 function createClasses ($path)
429 $class [ 'name' ] = $this->key_name ;
430 $class [ 'table_name' ] = strtolower ( $class [ 'name' ] ) ;
431 $class [ 'extends' ] = 'Basic' ;
432 $class [ 'requires' ] [] = MB_TEMPLATES . '/basic/Basic.php' ;
433 $class [ 'requires' ] = array ( ) ;
434 $class [ 'audited' ] = (! empty ( $this->config [ 'audit' ] )) ? 'true' : 'false' ;
435 $class [ 'acl' ] = ! empty ( $this->config [ 'acl' ] ) ;
436 $class [ 'templates' ] = "'basic'" ;
437 foreach ( $this->iTemplate as $template )
439 if (! empty ( $this->config [ $template ] ))
441 $class [ 'templates' ] .= ",'$template'" ;
444 foreach ( $this->config [ 'templates' ] as $template => $a )
446 if ($template == 'basic')
448 $class [ 'templates' ] .= ",'$template'" ;
449 $class [ 'extends' ] = ucFirst ( $template ) ;
450 $class [ 'requires' ] [] = MB_TEMPLATES . '/' . $template . '/' . ucfirst ( $template ) . '.php' ;
452 $class [ 'importable' ] = $this->config [ 'importable' ] ;
453 $this->mbvardefs->updateVardefs () ;
454 $class [ 'fields' ] = $this->mbvardefs->vardefs [ 'fields' ] ;
455 $class [ 'fields_string' ] = var_export_helper ( $this->mbvardefs->vardef [ 'fields' ] ) ;
456 $relationship = array ( ) ;
457 $class [ 'relationships' ] = var_export_helper ( $this->mbvardefs->vardef [ 'relationships' ] ) ;
458 $smarty = new Sugar_Smarty ( ) ;
459 $smarty->left_delimiter = '{{' ;
460 $smarty->right_delimiter = '}}' ;
461 $smarty->assign ( 'class', $class ) ;
462 //write sugar generated class
463 $fp = sugar_fopen ( $path . '/' . $class [ 'name' ] . '_sugar.php', 'w' ) ;
464 fwrite ( $fp, $smarty->fetch ( 'modules/ModuleBuilder/tpls/MBModule/Class.tpl' ) ) ;
467 $fp = sugar_fopen ( $path . '/vardefs.php', 'w' ) ;
468 fwrite ( $fp, $smarty->fetch ( 'modules/ModuleBuilder/tpls/MBModule/vardef.tpl' ) ) ;
471 if (! file_exists ( $path . '/' . $class [ 'name' ] . '.php' ))
473 $fp = sugar_fopen ( $path . '/' . $class [ 'name' ] . '.php', 'w' ) ;
474 fwrite ( $fp, $smarty->fetch ( 'modules/ModuleBuilder/tpls/MBModule/DeveloperClass.tpl' ) ) ;
477 if (! file_exists ( $path . '/metadata' ))
478 mkdir_recursive ( $path . '/metadata' ) ;
479 if (! empty ( $this->config [ 'studio' ] ))
481 $fp = sugar_fopen ( $path . '/metadata/studio.php', 'w' ) ;
482 fwrite ( $fp, $smarty->fetch ( 'modules/ModuleBuilder/tpls/MBModule/Studio.tpl' ) ) ;
486 if (file_exists ( $path . '/metadata/studio.php' ))
487 unlink ( $path . '/metadata/studio.php' ) ;
491 function createMenu ($path)
493 $smarty = new Sugar_Smarty ( ) ;
494 $smarty->assign ( 'moduleName', $this->key_name ) ;
495 $smarty->assign ( 'showvCard', in_array ( 'person', array_keys($this->config[ 'templates' ]) ) ) ;
496 $smarty->assign ( 'showimport', $this->config['importable'] );
497 //write sugar generated class
498 $fp = sugar_fopen ( $path . '/' . 'Menu.php', 'w' ) ;
499 fwrite ( $fp, $smarty->fetch ( 'modules/ModuleBuilder/tpls/MBModule/Menu.tpl' ) ) ;
503 function addInstallDefs (&$installDefs)
505 $name = $this->key_name ;
506 $installDefs [ 'copy' ] [] = array ( 'from' => '<basepath>/SugarModules/modules/' . $name , 'to' => 'modules/' . $name ) ;
507 $installDefs [ 'beans' ] [] = array ( 'module' => $name , 'class' => $name , 'path' => 'modules/' . $name . '/' . $name . '.php' , 'tab' => $this->config [ 'has_tab' ] ) ;
508 $this->relationships->addInstallDefs ( $installDefs ) ;
515 $psubs = $this->getProvidedSubpanels () ;
516 foreach ( $psubs as $sub )
519 if ($subLabel == 'default')
521 $subLabel = $GLOBALS [ 'mod_strings' ] [ 'LBL_DEFAULT' ] ;
523 $lSubs [] = array ( 'name' => $subLabel , 'type' => 'list' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view=ListView&view_module=' . $this->name . '&view_package=' . $this->package . '&subpanel=' . $sub . '&subpanelLabel=' . $subLabel . '&local=1' ) ;
526 $searchSubs = array ( ) ;
527 $searchSubs [] = array ( 'name' => translate('LBL_BASIC_SEARCH') , 'type' => 'list' , 'action' => "module=ModuleBuilder&MB=true&action=editLayout&view=basic_search&view_module={$this->name}&view_package={$this->package}" ) ;
528 $searchSubs [] = array ( 'name' => translate('LBL_ADVANCED_SEARCH') , 'type' => 'list' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view=advanced_search&view_module=' . $this->name . '&view_package=' . $this->package ) ;
529 $dashlets = array( );
530 $dashlets [] = array('name' => translate('LBL_DASHLETLISTVIEW') , 'type' => 'dashlet' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view=dashlet&view_module=' . $this->name . '&view_package=' . $this->package );
531 $dashlets [] = array('name' => translate('LBL_DASHLETSEARCHVIEW') , 'type' => 'dashletsearch' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view=dashletsearch&view_module=' . $this->name . '&view_package=' . $this->package );
534 $popups [] = array('name' => translate('LBL_POPUPLISTVIEW') , 'type' => 'popuplistview' , 'action' => 'module=ModuleBuilder&action=editLayout&view=popuplist&view_module=' . $this->name . '&view_package=' . $this->package );
535 $popups [] = array('name' => translate('LBL_POPUPSEARCH') , 'type' => 'popupsearch' , 'action' => 'module=ModuleBuilder&action=editLayout&view=popupsearch&view_module=' . $this->name . '&view_package=' . $this->package );
538 array ( 'name' => translate('LBL_EDITVIEW') , 'type' => 'edit' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view='.MB_EDITVIEW.'&view_module=' . $this->name . '&view_package=' . $this->package ) ,
539 array ( 'name' => translate('LBL_DETAILVIEW') , 'type' => 'detail' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view='.MB_DETAILVIEW.'&view_module=' . $this->name . '&view_package=' . $this->package ) ,
540 array ( 'name' => translate('LBL_LISTVIEW') , 'type' => 'list' , 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view='.MB_LISTVIEW.'&view_module=' . $this->name . '&view_package=' . $this->package ) ,
541 array ( 'name' => translate('LBL_QUICKCREATE') , 'type' => MB_QUICKCREATE, 'action' => 'module=ModuleBuilder&MB=true&action=editLayout&view='.MB_QUICKCREATE.'&view_module=' . $this->name . '&view_package=' . $this->package ) ,
542 array ( 'name' => translate('LBL_DASHLET') , 'type' => 'Folder', 'children' => $dashlets, 'action' => 'module=ModuleBuilder&MB=true&action=wizard&view=dashlet&view_module=' . $this->name . '&view_package=' . $this->package ),
543 array ( 'name' => translate('LBL_POPUP') , 'type' => 'Folder', 'children' => $popups, 'action' => 'module=ModuleBuilder&MB=true&action=wizard&view=popup&view_module=' . $this->name . '&view_package=' . $this->package ),
544 array ( 'name' => translate('LBL_SEARCH_FORMS') , 'action' => 'module=ModuleBuilder&MB=true&action=wizard&view=search&view_module=' . $this->name . '&view_package=' . $this->package , 'type' => 'folder' , 'children' => $searchSubs )
548 array ( 'name' => translate('LBL_FIELDS') , 'action' => 'module=ModuleBuilder&action=modulefields&view_module=' . $this->name . '&view_package=' . $this->package ) ,
549 array ( 'name' => translate('LBL_LABELS') , 'action' => 'module=ModuleBuilder&action=modulelabels&view_module=' . $this->name . '&view_package=' . $this->package ) ,
550 array ( 'name' => translate('LBL_RELATIONSHIPS') , 'action' => 'module=ModuleBuilder&action=relationships&view_module=' . $this->name . '&view_package=' . $this->package ) ,
551 array ( 'name' => translate('LBL_LAYOUTS') , 'type' => 'Folder' , 'action' => "module=ModuleBuilder&action=wizard&view_module={$this->name}&view_package={$this->package}&MB=1" , 'children' => $layouts ) ,
554 if (count ( $lSubs ) > 0)
556 $children [] = array ( 'name' => translate('LBL_AVAILABLE_SUBPANELS') , 'type' => 'folder' , 'children' => $lSubs ) ;
559 $nodes = array ( 'name' => $this->name , 'children' => $children , 'action' => 'module=ModuleBuilder&action=module&view_module=' . $this->name . '&view_package=' . $this->package ) ;
565 function getProvidedSubpanels ()
567 $this->providedSubpanels = array () ;
569 $subpanelDir = $this->getModuleDir () . '/metadata/subpanels/' ;
570 if (file_exists ( $subpanelDir ))
572 $f = dir ( $subpanelDir ) ;
573 require_once 'modules/ModuleBuilder/parsers/relationships/AbstractRelationships.php' ;
575 while ( $g = $f->read () )
577 // sanity check to confirm that this is a usable subpanel...
578 if (substr ( $g, 0, 1 ) != '.' && AbstractRelationships::validSubpanel ( $subpanelDir . $g ))
580 $subname = str_replace ( '.php', '', $g ) ;
581 $this->providedSubpanels [ $subname ] = $subname ;
586 return $this->providedSubpanels;
592 $d = dir ( MB_TEMPLATES ) ;
593 while ( $e = $d->read () )
595 if (substr ( $e, 0, 1 ) != '.')
604 function rename ($new_name)
606 $old = $this->getModuleDir () ;
607 $old_name = $this->key_name;
608 $this->name = $new_name ;
609 $this->key_name = $this->package_key . '_' . $this->name ;
610 $new = $this->getModuleDir () ;
611 if (file_exists ( $new ))
615 $renamed = rename ( $old, $new ) ;
618 $this->renameMetaData ( $new , $old_name) ;
619 $this->renameLanguageFiles ( $new ) ;
625 function renameLanguageFiles ($new_dir , $duplicate = false)
628 $this->mblanguage->name = $this->name ;
629 $this->mblanguage->path = $new_dir ;
630 $this->mblanguage->generateAppStrings () ;
631 $this->mblanguage->save ( $this->key_name, $duplicate, true) ;
635 * Rename module name in metadata
636 * @param string $new_dir
637 * @param string $old_name
639 public function renameMetaData ($new_dir, $old_name)
641 $GLOBALS [ 'log' ]->debug ( 'MBModule.php->renameMetaData: new_dir=' . $new_dir ) ;
642 if (! file_exists ( $new_dir ))
644 $dir = dir ( $new_dir ) ;
645 while ( $e = $dir->read () )
647 if (substr ( $e, 0, 1 ) != '.')
649 if (is_dir ( $new_dir . '/' . $e ))
651 $this->renameMetaData ( $new_dir . '/' . $e, $old_name) ;
653 if (is_file ( $new_dir . '/' . $e ))
655 $contents = file_get_contents ( $new_dir . '/' . $e ) ;
656 $search_array = array(
657 '/(\$module_name[ ]*=[ ]*\').*(\'[ ]*;)/',
658 '/(\$_module_name[ ]*=[ ]*\').*(\'[ ]*;)/',
659 '/(\$MODULE_NAME[ ]*=[ ]*\').*(\'[ ]*;)/',
660 '/(\$object_name[ ]*=[ ]*\').*(\'[ ]*;)/',
661 '/(\$_object_name[ ]*=[ ]*\').*(\'[ ]*;)/',
662 '/(\$OBJECT_NAME[ ]*=[ ]*\').*(\'[ ]*;)/'
664 $replace_array = array(
665 '$1' . $this->key_name . '$2',
666 '$1' . strtolower ( $this->key_name ) . '$2',
667 '$1' . strtoupper ( $this->key_name ) . '$2',
668 '$1' . $this->key_name . '$2',
669 '$1' . strtolower ( $this->key_name ) . '$2',
670 '$1' . strtoupper ( $this->key_name ) . '$2',
672 $contents = preg_replace($search_array, $replace_array, $contents);
673 $search_array = array(
677 $replace_array = array(
678 $this->key_name . '_',
679 $this->key_name . 'Dashlet'
681 $contents = str_replace($search_array, $replace_array, $contents );
684 if ("relationships.php" == $e)
686 //bug 39598 Relationship Name Is Not Updated If Module Name Is Changed In Module Builder
687 $contents = str_replace ( "'{$old_name}'", "'{$this->key_name}'" , $contents ) ;
690 $fp = sugar_fopen ( $new_dir . '/' . $e, 'w' ) ;
691 fwrite ( $fp, $contents ) ;
698 function copy ($new_name)
700 $old = $this->getModuleDir () ;
703 $old_name = $this->key_name;
704 $this->name = $new_name ;
705 $this->key_name = $this->package_key . '_' . $this->name ;
706 $new = $this->getModuleDir () ;
707 while ( file_exists ( $new ) )
710 $this->name = $new_name . $count ;
711 $this->key_name = $this->package_key . '_' . $this->name ;
712 $new = $this->getModuleDir () ;
715 $new = $this->getModuleDir () ;
716 $copied = copy_recursive ( $old, $new ) ;
720 $this->renameMetaData ( $new , $old_name) ;
721 $this->renameLanguageFiles ( $new, true ) ;
729 return rmdir_recursive ( $this->getModuleDir () ) ;
732 function populateFromPost ()
734 foreach ( $this->implementable as $key => $value )
736 $this->config [ $key ] = ! empty ( $_REQUEST [ $key ] ) ;
738 foreach ( $this->always_implement as $key => $value )
740 $this->config [ $key ] = true ;
742 if (! empty ( $_REQUEST [ 'type' ] ))
744 $this->addTemplate ( $_REQUEST [ 'type' ] ) ;
747 if (! empty ( $_REQUEST [ 'label' ] ))
749 $this->config [ 'label' ] = $_REQUEST [ 'label' ] ;
752 $this->config [ 'importable' ] = ! empty( $_REQUEST[ 'importable' ] ) ;
756 function getAvailibleSubpanelDef ($panelName)
758 $filepath = $this->getModuleDir () . "/metadata/subpanels/{$panelName}.php" ;
759 if (file_exists ( $filepath ))
761 include ($filepath) ;
762 return $subpanel_layout ;
768 function saveAvailibleSubpanelDef ($panelName , $layout)
770 $dir = $this->getModuleDir () . "/metadata/subpanels" ;
771 $filepath = "$dir/{$panelName}.php" ;
772 if (mkdir_recursive ( $dir ))
774 // preserve any $module_name entry if one exists
775 if (file_exists ( $filepath ))
777 include ($filepath) ;
779 $module_name = (isset ( $module_name )) ? $module_name : $this->key_name ;
780 $layout = "<?php\n" . '$module_name=\'' . $module_name . "';\n" . '$subpanel_layout = ' . var_export_helper ( $layout ) . ";" ;
781 $GLOBALS [ 'log' ]->debug ( "About to save this file to $filepath" ) ;
782 $GLOBALS [ 'log' ]->debug ( $layout ) ;
783 $fw = sugar_fopen ( $filepath, 'w' ) ;
784 fwrite ( $fw, $layout ) ;
789 function getLocalSubpanelDef ($panelName)
794 function createIcon ()
796 $icondir = $this->package_path . "/icons" ;
797 mkdir_recursive ( $icondir ) ;
799 foreach ( $this->config [ 'templates' ] as $temp => $val )
801 copy ( "themes/default/images/icon_$template.gif", "$icondir/icon_" . ucfirst ( $this->key_name ) . ".gif" ) ;
802 copy ( "include/SugarObjects/templates/$template/icons/$template.gif", "$icondir/" . $this->key_name . ".gif" ) ;
803 if (file_exists("include/SugarObjects/templates/$template/icons/Create$template.gif"))
804 copy ( "include/SugarObjects/templates/$template/icons/Create$template.gif", "$icondir/Create" . $this->key_name . ".gif" ) ;
805 if (file_exists("include/SugarObjects/templates/$template/icons/{$template}_32.gif"))
806 copy ( "include/SugarObjects/templates/$template/icons/{$template}_32.gif", "$icondir/icon_" . $this->key_name . "_32.gif" ) ;
809 function removeFieldFromLayouts ( $fieldName )
811 // hardcoded list of types for now, as also hardcoded in a different form in getNodes
812 // TODO: replace by similar mechanism to StudioModule to determine the list of available views for this module
813 $views = array ( 'editview' , 'detailview' , 'listview' , 'basic_search' , 'advanced_search' , 'dashlet' , 'popuplist');
815 foreach ($views as $type )
817 $parser = ParserFactory::getParser( $type , $this->name , $this->package ) ;
818 if ($parser->removeField ( $fieldName ) )
819 $parser->handleSave(false) ; // don't populate from $_REQUEST, just save as is...
821 //Remove the fields in subpanel
822 $psubs = $this->getProvidedSubpanels() ;
823 foreach ( $psubs as $sub )
825 $parser = ParserFactory::getParser( MB_LISTVIEW , $this->name, $this->package , $sub) ;
826 if ($parser->removeField ( $fieldName ) )
827 $parser->handleSave(false) ;