]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/ModuleBuilder/MB/MBPackage.php
Release 6.4.1
[Github/sugarcrm.git] / modules / ModuleBuilder / MB / MBPackage.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2012 SugarCRM Inc.
5  * 
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.
12  * 
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
16  * details.
17  * 
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
21  * 02110-1301 USA.
22  * 
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.
25  * 
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.
29  * 
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  ********************************************************************************/
36
37 require_once('modules/ModuleBuilder/MB/MBModule.php');
38
39 class MBPackage{
40     var $name;
41     var $is_uninstallable = true;
42     var $description = '';
43     var $has_images = true;
44     var $modules = array();
45     var $date_modified = '';
46     var $author = '';
47     var $key = '';
48     var $readme='';
49     function MBPackage($name){
50         $this->name = $name;
51         $this->load();
52         
53     }
54     function loadModules($force=false){
55         if(!file_exists(MB_PACKAGE_PATH . '/' . $this->name .'/modules'))return;
56         $d = dir(MB_PACKAGE_PATH . '/' . $this->name .'/modules');
57         while($e = $d->read()){
58             if(substr($e, 0, 1) != '.' && is_dir(MB_PACKAGE_PATH . '/'. $this->name. '/modules/' . $e)){
59                 $this->getModule($e, $force);
60             }
61         }
62     }
63     
64     /**
65      * Loads the translated module titles from the selected language into.
66      * Will override currently loaded string to reflect undeployed label changes.
67      * $app_list_strings
68      * @return 
69      * @param $languge String language identifyer
70      */
71     function loadModuleTitles($languge = '') 
72     {
73         if (empty($language))
74         {
75             $language = $GLOBALS['current_language'];
76         }
77         global $app_list_strings;
78         $packLangFilePath = $this->getPackageDir() . "/language/application/" . $language . ".lang.php";
79         if (file_exists($packLangFilePath))
80         {
81             
82             require($packLangFilePath);
83         }
84     }
85     
86     function getModule($name, $force=true){
87         if(!$force && !empty($this->modules[$name]))return;
88         $path = $this->getPackageDir();
89         
90         $this->modules[$name] = new MBModule($name, $path, $this->name, $this->key);
91     }
92     
93     function deleteModule($name){
94         $this->modules[$name]->delete();
95         unset($this->modules[$name]);
96     }
97     
98 function getManifest($version_specific = false, $for_export = false){
99     //If we are exporting the package, we must ensure a different install key
100     $pre = $for_export ? MB_EXPORTPREPEND : "";
101     $date = TimeDate::getInstance()->nowDb();
102     $time = time();
103     $this->description = to_html($this->description);
104     $is_uninstallable = ($this->is_uninstallable ? true : false);
105     if($GLOBALS['sugar_flavor'] == 'CE') {
106         $flavors = array('CE','PRO','ENT');
107     } else {
108         $flavors = array($GLOBALS['sugar_flavor']);
109     }
110     $version = (!empty($version_specific))?$GLOBALS['sugar_version']:'';
111
112     // Build an array and use var_export to build this file
113     $manifest = array(
114         array('acceptable_sugar_versions' => array($version)),
115         array('acceptable_sugar_flavors' => $flavors),
116         'readme' => $this->readme,
117         'key' => $this->key,
118         'author' => $this->author,
119         'description' => $this->description,
120         'icon' => '',
121         'is_uninstallable' => $is_uninstallable,
122         'name' => $pre.$this->name,
123         'published_date' => $date,
124         'type' => 'module',
125         'version' => $time,
126         'remove_tables' => 'prompt',
127     );
128         
129               
130
131     $header = file_get_contents('modules/ModuleBuilder/MB/header.php');
132     
133     return $header."\n// THIS CONTENT IS GENERATED BY MBPackage.php\n".'$manifest = '.var_export_helper($manifest).";\n\n";
134 /*
135     return  <<<EOQ
136     $header
137     \$manifest = array (
138          'acceptable_sugar_versions' => 
139           array (
140             $version
141           ),
142           'acceptable_sugar_flavors' =>
143           array(
144             $flavor
145           ),
146           'readme'=>'$this->readme',
147           'key'=>'$this->key',
148           'author' => '$this->author',
149           'description' => '$this->description',
150           'icon' => '',
151           'is_uninstallable' => $is_uninstallable,
152           'name' => '$pre$this->name',
153           'published_date' => '$date',
154           'type' => 'module',
155           'version' => '$time',
156           'remove_tables' => 'prompt',
157           );
158 EOQ;
159 */
160 }
161     
162 function buildInstall($path){
163     $installdefs = array ('id' => $this->name,
164         'beans'=>array(),
165         'layoutdefs'=>array(),
166         'relationships'=>array(),
167     );
168     if($this->has_images){
169         $installdefs['image_dir'] = '<basepath>/icons'; 
170     }
171     foreach(array_keys($this->modules) as $module){
172         $this->modules[$module]->build($path);
173         $this->modules[$module]->addInstallDefs($installdefs);
174     }
175     $this->path = $this->getPackageDir(); 
176     if(file_exists($this->path . '/language')){
177         $d= dir($this->path . '/language');
178         while($e = $d->read()){
179             $lang_path = $this->path .'/language/' . $e;
180             if(substr($e, 0, 1) != '.' && is_dir($lang_path)){
181                 $f = dir($lang_path);
182                 while($g = $f->read()){
183                     if(substr($g, 0, 1) != '.' && is_file($lang_path.'/'. $g)){
184                         $lang = substr($g, 0, strpos($g, '.'));
185                         $installdefs['language'][] = array(
186                         'from'=> '<basepath>/SugarModules/language/'.$e . '/'. $g,
187                         'to_module'=> $e,
188                         'language'=> $lang  
189                         );
190                     }
191                 }
192             }
193         }
194             
195         copy_recursive( $this->path . '/language/', $path . '/language/');
196         $icon_path = $path . '/../icons/default/images/';
197         mkdir_recursive($icon_path);
198         copy_recursive($this->path . '/icons/', $icon_path);
199     }
200     return "\n".'$installdefs = ' . var_export_helper($installdefs). ';';
201
202 }
203     
204     function getPackageDir(){
205         return MB_PACKAGE_PATH . '/' . $this->name;
206     }
207     
208     function getBuildDir(){
209         return MB_PACKAGE_BUILD . '/' . $this->name;
210     }
211     
212     function getZipDir(){
213         return $this->getPackageDir() . '/zips';
214     }
215     
216     
217     function load(){
218         $path = $this->getPackageDir();
219         if(file_exists($path .'/manifest.php')){
220             require($path . '/manifest.php');
221             if(!empty($manifest)){
222                 $this->date_modified = $manifest['published_date'];
223                 $this->is_uninstallable = $manifest['is_uninstallable'];
224                 $this->author = $manifest['author'];
225                 $this->key = $manifest['key'];
226                 $this->description = $manifest['description'];
227                 if(!empty($manifest['readme']))
228                     $this->readme = $manifest['readme'];
229             }
230         }
231         $this->loadModules(true);
232     }
233
234     function save(){
235         $path = $this->getPackageDir();
236         if(mkdir_recursive($path)){
237             $fp = sugar_fopen($path .'/manifest.php', 'w');
238             
239             
240             //Save all the modules when we save a package
241             $this->updateModulesMetaData(true);
242             fwrite($fp, $this->getManifest() );
243             fclose($fp);
244         }
245         
246         
247         
248         
249     }
250     
251     function build($export=true, $clean = false){
252         $this->loadModules();
253         require_once('include/utils/zip_utils.php');
254         $package_path = $this->getPackageDir();
255         $path = $this->getBuildDir() . '/SugarModules';
256         if($clean && file_exists($path))rmdir_recursive($path);
257         if(mkdir_recursive($path)){
258             
259             $manifest = $this->getManifest().$this->buildInstall($path);
260             $fp = sugar_fopen($this->getBuildDir() .'/manifest.php', 'w');
261             fwrite($fp, $manifest);
262             fclose($fp);
263             
264         }
265         if(file_exists('modules/ModuleBuilder/MB/LICENSE.txt')){
266             copy('modules/ModuleBuilder/MB/LICENSE.txt', $this->getBuildDir() . '/LICENSE.txt');
267         }else if(file_exists('LICENSE.txt')){
268             copy('LICENSE.txt', $this->getBuildDir() . '/LICENSE.txt');
269         }
270         $package_dir = $this->getPackageDir();
271         $date = date('Y_m_d_His');
272         $zipDir = $this->getZipDir();
273         if(!file_exists($zipDir))mkdir_recursive($zipDir);
274         $cwd = getcwd();
275         chdir($this->getBuildDir());
276         zip_dir('.',$cwd . '/'. $zipDir. '/'. $this->name. $date. '.zip');
277         chdir($cwd);
278         if($export){
279             header('Location:' . $zipDir. '/'. $this->name. $date. '.zip');
280         }
281         return array(
282             'zip'=>$zipDir. '/'. $this->name. $date. '.zip',
283             'manifest'=>$this->getBuildDir(). '/manifest.php',
284             'name'=>$this->name. $date,
285             );
286     }
287     
288     
289     function getNodes(){
290         $this->loadModules();
291         $node = array('name'=>$this->name, 'action'=>'module=ModuleBuilder&action=package&package=' . $this->name, 'children'=>array());
292         foreach(array_keys($this->modules) as $module){
293             $node['children'][] = $this->modules[$module]->getNodes();
294         }
295         return $node;
296     }
297     
298     function populateFromPost(){
299         $this->description = $_REQUEST['description'];
300         $this->author = $_REQUEST['author'];
301         $this->key = $_REQUEST['key'];
302         $this->readme = $_REQUEST['readme'];
303     }
304     
305     function rename($new_name){
306         $old= $this->getPackageDir();
307         $this->name = $new_name;
308         $new = $this->getPackageDir();
309         if(file_exists($new)){
310             return false;   
311         }
312         if(rename($old, $new)){
313             return true;
314         }
315             
316         return false;
317     }
318     
319     function updateModulesMetaData($save=false){
320             foreach(array_keys($this->modules) as $module){
321                 $old_name = $this->modules[$module]->key_name;
322                 $this->modules[$module]->key_name = $this->key . '_' . $this->modules[$module]->name;
323                 $this->modules[$module]->renameMetaData($this->modules[$module]->getModuleDir(), $old_name);
324                 $this->modules[$module]->renameLanguageFiles($this->modules[$module]->getModuleDir());
325                 if($save)$this->modules[$module]->save();
326             }
327         
328     }
329     
330     function copy($new_name){
331         $old= $this->getPackageDir();
332         
333         $count = 0;
334         $this->name = $new_name;
335         $new= $this->getPackageDir();
336         while(file_exists($new)){
337             $count++;
338             $this->name = $new_name . $count;
339             $new= $this->getPackageDir();
340         }
341         
342         $new = $this->getPackageDir();
343         if(copy_recursive($old, $new)){
344             $this->updateModulesMetaData();
345             return true;
346         }
347         return false;
348         
349     }
350     
351     function delete(){
352         return rmdir_recursive($this->getPackageDir());
353     }
354     
355     
356         //creation of the installdefs[] array for the manifest when exporting customizations
357     function customBuildInstall($modules, $path, $extensions = array()){
358         $columns=$this->getColumnsName();
359         $installdefs = array ('id' => $this->name);
360         $include_path="$path/SugarModules/include/language";
361         if(file_exists($include_path) && is_dir($include_path)){
362             $dd= dir($include_path);
363             while($gg = $dd->read()){
364                 if(substr($gg, 0, 1) != '.' && is_file($include_path . '/' . $gg)){
365                     $lang = substr($gg, 0, strpos($gg, '.'));
366                     $installdefs['language'][] = array(
367                     'from'=> '<basepath>/SugarModules/include/language/'. $gg,
368                     'to_module'=> 'application',
369                     'language'=>$lang    
370                     );
371                 }
372             }
373         }
374         
375         foreach($modules as $value){
376             $custom_module = $this->getCustomModules($value);
377             foreach($custom_module as $va){
378                 if ($va == 'language'){
379                     $this->getLanguageManifestForModule($value, $installdefs);
380                     $this->getCustomFieldsManifestForModule($value, $installdefs);
381                 }//fi
382                 if($va == 'metadata'){
383                     $this->getCustomMetadataManifestForModule($value, $installdefs);
384                 }//fi
385             }//foreach
386         }//foreach
387         if (is_dir("$path/Extension"))
388         {
389             $this->getExtensionsManifestForPackage($path, $installdefs);
390         }
391         return "\n".'$installdefs = ' . var_export_helper($installdefs). ';';
392     }
393     
394     private function getLanguageManifestForModule($module, &$installdefs)
395     {
396         $lang_path = 'custom/modules/' . $module . '/language';
397         foreach(scandir($lang_path) as $langFile)
398         {
399                 if(substr($langFile, 0, 1) != '.' && is_file($lang_path . '/' . $langFile)){
400                     $lang = substr($langFile, 0, strpos($langFile, '.'));
401                     $installdefs['language'][] = array(
402                         'from'=> '<basepath>/SugarModules/modules/' . $module . '/language/'. $langFile,
403                         'to_module'=> $module,
404                         'language'=>$lang
405                     );
406                 }
407         }  
408     }
409     
410     private function getCustomFieldsManifestForModule($module, &$installdefs)
411     {
412         $db = DBManagerFactory::getInstance();
413         $result=$db->query("SELECT *  FROM fields_meta_data where custom_module='$module'");
414         while($row = $db->fetchByAssoc($result)){
415                 $name = $row['id'];
416                 foreach($row as $col=>$res){
417                         switch ($col) {
418                                 case 'custom_module':
419                                         $installdefs['custom_fields'][$name]['module'] = $res;
420                                         break;
421                                 case 'required':
422                                         $installdefs['custom_fields'][$name]['require_option'] = $res;
423                                         break;
424                                 case 'vname':
425                                         $installdefs['custom_fields'][$name]['label'] = $res;
426                                         break;
427                                 case 'required':
428                                         $installdefs['custom_fields'][$name]['require_option'] = $res;
429                                         break;
430                                 case 'massupdate':
431                                         $installdefs['custom_fields'][$name]['mass_update'] = $res;
432                                         break;
433                                 case 'comments':
434                                         $installdefs['custom_fields'][$name]['comments'] = $res;
435                                         break;
436                                 case 'help':
437                                         $installdefs['custom_fields'][$name]['help'] = $res;
438                                         break;
439                                 case 'len':
440                                         $installdefs['custom_fields'][$name]['max_size'] = $res;
441                                         break;
442                                 default:
443                                         $installdefs['custom_fields'][$name][$col] = $res;
444                         }//switch
445                 }//foreach
446         }//while
447     }
448     
449     private function getCustomMetadataManifestForModule($module, &$installdefs)
450     {
451         $meta_path = 'custom/modules/' . $module . '/metadata';
452         foreach(scandir($meta_path) as $meta_file)
453         {
454                 if(substr($meta_file, 0, 1) != '.' && is_file($meta_path . '/' . $meta_file)){
455                         if($meta_file == 'listviewdefs.php'){
456                                 $installdefs['copy'][] = array(
457                                 'from'=> '<basepath>/SugarModules/modules/'. $module . '/metadata/'. $meta_file,
458                                 'to'=> 'custom/modules/'. $module . '/metadata/' . $meta_file,   
459                                 );
460                         }
461                         else{
462                                 $installdefs['copy'][] = array(
463                                 'from'=> '<basepath>/SugarModules/modules/'. $module . '/metadata/'. $meta_file,
464                                 'to'=> 'custom/modules/'. $module . '/metadata/' . $meta_file,   
465                                 );
466                                 $installdefs['copy'][] = array(
467                                 'from'=> '<basepath>/SugarModules/modules/'. $module . '/metadata/'. $meta_file,
468                                 'to'=> 'custom/working/modules/'. $module . '/metadata/' . $meta_file,   
469                                 );
470                         }
471                 }
472         }
473     }
474     
475     private function getExtensionsManifestForPackage($path, &$installdefs)
476     {
477         $extPath = "$path/Extension/modules";
478         foreach(scandir($extPath) as $moduleDir)
479         {
480                 if(substr($moduleDir, 0, 1) != '.' && is_dir("$extPath/$moduleDir/Ext")){
481                         foreach(scandir("$extPath/$moduleDir/Ext") as $type)
482                         {
483                                 if(substr($type, 0, 1) != '.' && is_dir("$extPath/$moduleDir/Ext/$type")){
484                                         foreach(scandir("$extPath/$moduleDir/Ext/$type") as $file)
485                                         {
486                                                 if(substr($file, 0, 1) != '.' && strtolower(substr($file, -4)) == ".php")
487                                                 {
488                                                         $installdefs['copy'][] = array(
489                                                 'from'=> "<basepath>/Extension/modules/$moduleDir/Ext/$type/$file",
490                                                 'to'=> "custom/Extension/modules/$moduleDir/Ext/$type/$file",   
491                                             );
492                                                 }
493                                         }
494                                 }
495                         }
496             }
497         }
498     }
499
500     
501     //return an array which contain the name of fields_meta_data table's columns 
502     function getColumnsName(){
503          
504         $meta = new FieldsMetaData();
505         $arr = array(); 
506          foreach($meta->getFieldDefinitions() as $key=>$value) {
507             $arr[] = $key;
508         }
509         return $arr;
510     }
511
512
513     //creation of the custom fields ZIP file (use getmanifest() and customBuildInstall() )  
514     function exportCustom($modules, $export=true, $clean = true){
515         $path=$this->getBuildDir();
516         if($clean && file_exists($path))rmdir_recursive($path);
517         //Copy the custom files to the build dir
518         foreach($modules as $mod){
519                 $extensions = $this->getExtensionsList($mod);
520             $pathmod="$path/SugarModules/modules/$mod";
521             if(mkdir_recursive($pathmod)){
522                 if(file_exists("custom/modules/$mod")){
523                     copy_recursive("custom/modules/$mod", "$pathmod");
524                     //Don't include cached extension files
525                     if (is_dir("$pathmod/Ext"))
526                         rmdir_recursive("$pathmod/Ext");
527                 }
528                 //Convert modstring files to extension compatible arrays
529                     $this->convertLangFilesToExtensions("$pathmod/language");
530             }
531             $pathext="$path/Extension/modules/$mod/Ext";
532             if (!empty($extensions) && mkdir_recursive($pathext))
533             {
534                 foreach($extensions as $type => $files)
535                 {
536                     sugar_mkdir("$pathext/$type");
537                         foreach($files as $file => $filePath)
538                     {
539                         copy  ($filePath, "$pathext/$type/$file");
540                     }
541                 }
542             }
543         }
544         
545         $this->copyCustomDropdownValuesForModules($modules,$path);
546         if(file_exists($path)){
547             $manifest = $this->getManifest(true).$this->customBuildInstall($modules,$path);
548             sugar_file_put_contents($path .'/manifest.php', $manifest);;
549         }
550         if(file_exists('modules/ModuleBuilder/MB/LICENSE.txt')){
551             copy('modules/ModuleBuilder/MB/LICENSE.txt', $path . '/LICENSE.txt');
552         }
553         else if(file_exists('LICENSE.txt')){
554             copy('LICENSE.txt', $path . '/LICENSE.txt');
555         }
556         require_once('include/utils/zip_utils.php');
557         $date = date('Y_m_d_His');
558         $zipDir = $this->getZipDir();
559         if(!file_exists($zipDir))mkdir_recursive($zipDir);
560         $cwd = getcwd();
561         chdir($this->getBuildDir());
562         zip_dir('.',$cwd . '/'. $zipDir. '/'. $this->name. $date. '.zip');
563         chdir($cwd);
564         if($clean && file_exists($this->getBuildDir()))rmdir_recursive($this->getBuildDir());
565         if($export){
566             header('Location:' . $zipDir. '/'. $this->name. $date. '.zip');
567         }
568         return $zipDir. '/'. $this->name. $date. '.zip';
569     }
570     
571     private function convertLangFilesToExtensions($langDir)
572     {
573         if (is_dir($langDir))
574         {
575             foreach(scandir($langDir) as $langFile)
576             {
577                 $mod_strings = array();
578                 if (strcasecmp(substr($langFile, -4), ".php") != 0)
579                     continue;
580                 include("$langDir/$langFile");
581                 $out = "<?php \n // created: " . date('Y-m-d H:i:s') . "\n";
582                 foreach($mod_strings as $lbl_key => $lbl_val ) 
583                 {
584                     $out .= override_value_to_string("mod_strings", $lbl_key, $lbl_val) . "\n";
585                 }
586                 $out .= "\n?>\n";
587                 sugar_file_put_contents("$langDir/$langFile", $out);
588             }
589         }
590     }
591     private function copyCustomDropdownValuesForModules($modules, $path)
592     {
593         if(file_exists("custom/include/language")){
594             if(mkdir_recursive("$path/SugarModules/include")){
595                 global $app_list_strings;
596                 $backStrings = $app_list_strings;
597                 foreach(scandir("custom/include/language") as $langFile)
598                 {
599                     $app_list_strings = array();
600                     if (strcasecmp(substr($langFile, -4), ".php") != 0)
601                        continue;
602                     include("custom/include/language/$langFile");
603                     $out = "<?php \n";
604                     $lang = substr($langFile, 0, -9);
605                     $options = $this->getCustomDropDownStringsForModules($modules, $app_list_strings); 
606                     foreach($options as $name => $arr) {
607                         $out .= override_value_to_string('app_list_strings', $name, $arr);
608                     }
609                     mkdir_recursive("$path/SugarModules/include/language/");
610                     sugar_file_put_contents("$path/SugarModules/include/language/$lang.$this->name.php", $out);
611                 }
612                 $app_list_strings = $backStrings;
613             }
614         }
615     }
616     
617     function getCustomDropDownStringsForModules($modules, $list_strings) {
618         global $beanList, $beanFiles;
619         $options = array();
620         foreach($modules as $module)
621         {
622             if (!empty($beanList[$module]))
623             {
624                 require_once($beanFiles[$beanList[$module]]);
625                 $bean = new $beanList[$module]();
626                 foreach($bean->field_defs as $field => $def) 
627                 {
628                     if (isset($def['options']) && isset($list_strings[$def['options']]))
629                     {
630                         $options[$def['options']] = $list_strings[$def['options']];
631                     }
632                 }
633             }
634         }
635         return $options;
636     }
637
638
639
640     //if $module=false : return an array with custom module and there customizations.
641     //if $module=!false : return an array with the directories of custom/module/$module.
642     function getCustomModules($module=false){
643         global $mod_strings;
644         $path='custom/modules/';
645                 $extPath = 'custom/Extension/modules/';
646         if(!file_exists($path) || !is_dir($path)){
647             return array($mod_strings['LBL_EC_NOCUSTOM'] => "");
648         }
649         else{
650             if ($module != false ){
651                 $path=$path . $module . '/';
652             }
653             $scanlisting = scandir($path);
654             $dirlisting = array();
655             foreach ($scanlisting as $value){
656                 if(is_dir($path . $value) == true && $value != '.' && $value != '..') {
657                     $dirlisting[] = $value;
658                 }
659             }
660                         if(empty($dirlisting)){
661                 return array($mod_strings['LBL_EC_NOCUSTOM'] => "");
662             }
663             if ($module == false ){
664                 foreach ($dirlisting as $value){
665                         if(!file_exists('modules/' . $value . '/metadata/studio.php'))
666                                 continue;
667                     $custommodules[$value]=$this->getCustomModules($value);
668                     foreach ($custommodules[$value] as $va){
669                         switch ($va) {
670                         case 'language':
671                                 $return[$value][$va] = $mod_strings['LBL_EC_CUSTOMFIELD'];
672                             break;
673                         case 'metadata':
674                             $return[$value][$va] = $mod_strings['LBL_EC_CUSTOMLAYOUT'];
675                             break;
676                         case 'Ext':
677                             
678                                                         $return[$value][$va] = $mod_strings['LBL_EC_CUSTOMFIELD'];
679                             break;
680                         case '':
681                             $return[$value . " " . $mod_strings['LBL_EC_EMPTYCUSTOM']] = "";
682                             break;
683                         default:
684                             $return[$value][$va] = $mod_strings['LBL_UNDEFINED'];
685                         }
686                     }
687                 }
688                 return $return;
689             }
690             else{
691                 return $dirlisting;
692             }
693         }
694     }
695         
696         private function getExtensionsList($module, $excludeRelationships = true)
697         {
698                 require_once 'modules/ModuleBuilder/parsers/relationships/DeployedRelationships.php' ;
699                 $extPath = 'custom/Extension/modules/';
700                 $modExtPath = $extPath . $module . '/Ext';
701                 $rels = new DeployedRelationships($module);
702                 $relList = $rels->getRelationshipList ();
703                 
704                 $ret = array();
705                 if (is_dir($modExtPath))
706                 {
707             $extFolders = scandir($modExtPath);
708                         foreach($extFolders as $extFolder)
709                         {
710                 if (!is_dir("$modExtPath/$extFolder") || substr($extFolder, 0, 1) == ".")
711                                     continue;
712                 
713                                 foreach( scandir("$modExtPath/$extFolder") as $extFile)
714                                 {
715                                         
716                                         if (substr($extFile, 0, 1) == "." || strtolower(substr($extFile, -4)) != ".php")
717                         continue;
718                                         //Exclude relattionship extension files
719                     if ($excludeRelationships && (
720                         (substr($extFile, 0, 6) == "custom" && isset($relList[substr($extFile, 6, strlen($extFile) - 10)])) ||
721                         (substr($extFile, 6, 6) == "custom" && isset($relList[substr($extFile, 12, strlen($extFile) - 16)]))
722                     )) {
723                        continue;
724                     }
725                                         
726                                         if (!isset($ret[$extFolder]))
727                                            $ret[$extFolder] = array();
728                                            
729                                         $ret[$extFolder][$extFile  ] =  "$modExtPath/$extFolder/$extFile";
730                                 }
731                         }
732                 }
733                 return $ret;
734         }
735     
736     /**
737      * Returns a set of field defs for fields that will exist when this package is deployed
738      * based on the relationships in all of its modules.
739      * 
740      * @param $moduleName (module must be from whithin this package)
741      * @return array Field defs
742      */
743     function getRelationshipsForModule($moduleName) {
744         $ret = array();
745         if (isset($this->modules[$moduleName])) {
746                 $keyName = $this->modules[$moduleName]->key_name;
747                 foreach($this->modules as $mName => $module) {
748                         $rels = $module->getRelationships();
749                         $relList = $rels->getRelationshipList();
750                         foreach($relList as $rName ) {
751                             $rel = $rels->get ( $rName ) ;
752                              if ($rel->lhs_module == $keyName || $rel->rhs_module == $keyName) {
753                         $ret[$rName] =  $rel;
754                              }
755                         }
756                 }
757         }
758         return $ret; 
759     }
760     
761
762     
763     function exportProjectInstall($package, $for_export){
764         $pre = $for_export ? MB_EXPORTPREPEND : "";
765         $installdefs = array ('id' => $pre . $this->name);
766         $installdefs['copy'][] = array(
767             'from'=> '<basepath>/' . $this->name,
768             'to'=> 'custom/modulebuilder/packages/'. $this->name,   
769         );
770         return "\n".'$installdefs = ' . var_export_helper($installdefs). ';';
771
772     }
773     
774     
775     
776     function exportProject($package, $export=true, $clean = true){
777         $tmppath="custom/modulebuilder/projectTMP/";
778         if(file_exists($this->getPackageDir())){
779             if(mkdir_recursive($tmppath)){
780                 copy_recursive($this->getPackageDir(), $tmppath ."/". $this->name);
781                 $manifest = $this->getManifest(true, $export).$this->exportProjectInstall($package, $export);
782                 $fp = sugar_fopen($tmppath .'/manifest.php', 'w');
783                 fwrite($fp, $manifest);
784                 fclose($fp);
785                 if(file_exists('modules/ModuleBuilder/MB/LICENSE.txt')){
786                     copy('modules/ModuleBuilder/MB/LICENSE.txt', $tmppath . '/LICENSE.txt');
787                 }
788                 else if(file_exists('LICENSE.txt')){
789                     copy('LICENSE.txt', $tmppath . '/LICENSE.txt');
790                 }
791                 $readme_contents = $this->readme;
792                 $readmefp = sugar_fopen($tmppath.'/README.txt','w');
793                 fwrite($readmefp, $readme_contents);
794                 fclose($readmefp);
795             }
796         }
797         require_once('include/utils/zip_utils.php');
798         $date = date('Y_m_d_His');
799         $zipDir = "custom/modulebuilder/packages/ExportProjectZips";
800         if(!file_exists($zipDir))mkdir_recursive($zipDir);
801         $cwd = getcwd();
802         chdir($tmppath);
803         zip_dir('.',$cwd . '/'. $zipDir. '/project_'. $this->name. $date. '.zip');
804         chdir($cwd);
805         if($clean && file_exists($tmppath))rmdir_recursive($tmppath);
806         if($export){
807             header('Location:' . $zipDir. '/project_'. $this->name. $date. '.zip');
808         }
809         return $zipDir. '/project_'. $this->name. $date. '.zip';
810     }
811     
812     
813 }
814 ?>