dolibarr  9.0.0
modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2003 Jean-Louis Bergamo <jlb@j1b.org>
4  * Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
5  * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
6  * Copyright (C) 2005-2017 Regis Houssin <regis.houssin@inodbox.com>
7  * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
8  * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
9  * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
10  * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
31 require '../main.inc.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/dolistore.class.php';
37 
38 // Load translation files required by the page
39 $langs->loadLangs(array("errors","admin","modulebuilder"));
40 
41 $mode=GETPOST('mode', 'alpha');
42 if (empty($mode)) $mode='common';
43 $action=GETPOST('action','alpha');
44 //var_dump($_POST);exit;
45 $value=GETPOST('value', 'alpha');
46 $page_y=GETPOST('page_y','int');
47 $search_keyword=GETPOST('search_keyword','alpha');
48 $search_status=GETPOST('search_status','alpha');
49 $search_nature=GETPOST('search_nature','alpha');
50 $search_version=GETPOST('search_version','alpha');
51 
52 
53 // For dolistore search
54 $options = array();
55 $options['per_page'] = 20;
56 $options['categorie'] = ((GETPOST('categorie', 'int')?GETPOST('categorie', 'int'):0) + 0);
57 $options['start'] = ((GETPOST('start', 'int')?GETPOST('start', 'int'):0) + 0);
58 $options['end'] = ((GETPOST('end', 'int')?GETPOST('end', 'int'):0) + 0);
59 $options['search'] = GETPOST('search_keyword', 'alpha');
60 $dolistore = new Dolistore(false);
61 
62 
63 if (! $user->admin)
65 
66 $specialtostring=array(0=>'common', 1=>'interfaces', 2=>'other', 3=>'functional', 4=>'marketplace');
67 
68 $familyinfo=array(
69  'hr'=>array('position'=>'001', 'label'=>$langs->trans("ModuleFamilyHr")),
70  'crm'=>array('position'=>'006', 'label'=>$langs->trans("ModuleFamilyCrm")),
71  'srm'=>array('position'=>'007', 'label'=>$langs->trans("ModuleFamilySrm")),
72  'financial'=>array('position'=>'009', 'label'=>$langs->trans("ModuleFamilyFinancial")),
73  'products'=>array('position'=>'012', 'label'=>$langs->trans("ModuleFamilyProducts")),
74  'projects'=>array('position'=>'015', 'label'=>$langs->trans("ModuleFamilyProjects")),
75  'ecm'=>array('position'=>'018', 'label'=>$langs->trans("ModuleFamilyECM")),
76  'technic'=>array('position'=>'021', 'label'=>$langs->trans("ModuleFamilyTechnic")),
77  'portal'=>array('position'=>'040', 'label'=>$langs->trans("ModuleFamilyPortal")),
78  'interface'=>array('position'=>'050', 'label'=>$langs->trans("ModuleFamilyInterface")),
79  'base'=>array('position'=>'060', 'label'=>$langs->trans("ModuleFamilyBase")),
80  'other'=>array('position'=>'100', 'label'=>$langs->trans("ModuleFamilyOther")),
81 );
82 
83 $param='';
84 if (! GETPOST('buttonreset','alpha'))
85 {
86  if ($search_keyword) $param.='&search_keyword='.urlencode($search_keyword);
87  if ($search_status && $search_status != '-1') $param.='&search_status='.urlencode($search_status);
88  if ($search_nature && $search_nature != '-1') $param.='&search_nature='.urlencode($search_nature);
89  if ($search_version && $search_version != '-1') $param.='&search_version='.urlencode($search_version);
90 }
91 
92 $dirins=DOL_DOCUMENT_ROOT.'/custom';
93 $urldolibarrmodules='https://www.dolistore.com/';
94 
95 // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
96 $hookmanager->initHooks(array('adminmodules','globaladmin'));
97 
98 
99 /*
100  * Actions
101  */
102 
103 $formconfirm = '';
104 
105 $parameters=array();
106 $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
107 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
108 
109 if (GETPOST('buttonreset','alpha'))
110 {
111  $search_keyword='';
112  $search_status='';
113  $search_nature='';
114  $search_version='';
115 }
116 
117 if ($action=='install')
118 {
119  $error=0;
120 
121  // $original_file should match format module_modulename-x.y[.z].zip
122  $original_file=basename($_FILES["fileinstall"]["name"]);
123  $newfile=$conf->admin->dir_temp.'/'.$original_file.'/'.$original_file;
124 
125  if (! $original_file)
126  {
127  $langs->load("Error");
128  setEventMessages($langs->trans("ErrorModuleFileRequired"), null, 'warnings');
129  $error++;
130  }
131  else
132  {
133  if (! preg_match('/\.zip$/i',$original_file))
134  {
135  $langs->load("errors");
136  setEventMessages($langs->trans("ErrorFileMustBeADolibarrPackage",$original_file), null, 'errors');
137  $error++;
138  }
139  if (! preg_match('/module_.*\-[\d]+\.[\d]+.*$/i',$original_file))
140  {
141  $langs->load("errors");
142  setEventMessages($langs->trans("ErrorFilenameDosNotMatchDolibarrPackageRules",$original_file, 'module_*-x.y*.zip'), null, 'errors');
143  $error++;
144  }
145  if (empty($_FILES['fileinstall']['tmp_name']))
146  {
147  $langs->load("errors");
148  setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors');
149  $error++;
150  }
151  }
152 
153  if (! $error)
154  {
155  if ($original_file)
156  {
157  @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$original_file);
158  dol_mkdir($conf->admin->dir_temp.'/'.$original_file);
159  }
160 
161  $tmpdir=preg_replace('/\.zip$/i','',$original_file).'.dir';
162  if ($tmpdir)
163  {
164  @dol_delete_dir_recursive($conf->admin->dir_temp.'/'.$tmpdir);
165  dol_mkdir($conf->admin->dir_temp.'/'.$tmpdir);
166  }
167 
168  $result=dol_move_uploaded_file($_FILES['fileinstall']['tmp_name'], $newfile, 1, 0, $_FILES['fileinstall']['error']);
169  if ($result > 0)
170  {
171  $result=dol_uncompress($newfile,$conf->admin->dir_temp.'/'.$tmpdir);
172 
173  if (! empty($result['error']))
174  {
175  $langs->load("errors");
176  setEventMessages($langs->trans($result['error'],$original_file), null, 'errors');
177  $error++;
178  }
179  else
180  {
181  // Now we move the dir of the module
182  $modulename=preg_replace('/module_/', '', $original_file);
183  $modulename=preg_replace('/\-[\d]+\.[\d]+.*$/', '', $modulename);
184  // Search dir $modulename
185  $modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename;
186  //var_dump($modulenamedir);
187  if (! dol_is_dir($modulenamedir))
188  {
189  $modulenamedir=$conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename;
190  //var_dump($modulenamedir);
191  if (! dol_is_dir($modulenamedir))
192  {
193  setEventMessages($langs->trans("ErrorModuleFileSeemsToHaveAWrongFormat").'<br>Dir not found: '.$conf->admin->dir_temp.'/'.$tmpdir.'/'.$modulename.'<br>'.$conf->admin->dir_temp.'/'.$tmpdir.'/htdocs/'.$modulename, null, 'errors');
194  $error++;
195  }
196  }
197 
198  if (! $error)
199  {
200  //var_dump($dirins);
201  @dol_delete_dir_recursive($dirins.'/'.$modulename);
202  dol_syslog("Uncompress of module file is a success. We copy it from ".$modulenamedir." into target dir ".$dirins.'/'.$modulename);
203  $result=dolCopyDir($modulenamedir, $dirins.'/'.$modulename, '0444', 1);
204  if ($result <= 0)
205  {
206  dol_syslog('Failed to call dolCopyDir result='.$result." with param ".$modulenamedir." and ".$dirins.'/'.$modulename, LOG_WARNING);
207  $langs->load("errors");
208  setEventMessages($langs->trans("ErrorFailToCopyDir", $modulenamedir, $dirins.'/'.$modulename), null, 'errors');
209  $error++;
210  }
211  }
212  }
213  }
214  else
215  {
216  setEventMessages($langs->trans("ErrorFailToRenameFile", $_FILES['fileinstall']['tmp_name'], $newfile), null, 'errors');
217  $error++;
218  }
219  }
220 
221  if (! $error)
222  {
223  setEventMessages($langs->trans("SetupIsReadyForUse", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Modules")), null, 'warnings');
224  }
225 }
226 
227 if ($action == 'set' && $user->admin)
228 {
229  $resarray = activateModule($value);
230  if (! empty($resarray['errors'])) setEventMessages('', $resarray['errors'], 'errors');
231  else
232  {
233  //var_dump($resarray);exit;
234  if ($resarray['nbperms'] > 0)
235  {
236  $tmpsql="SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."user WHERE admin <> 1";
237  $resqltmp=$db->query($tmpsql);
238  if ($resqltmp)
239  {
240  $obj=$db->fetch_object($resqltmp);
241  //var_dump($obj->nb);exit;
242  if ($obj && $obj->nb > 1)
243  {
244  $msg = $langs->trans('ModuleEnabledAdminMustCheckRights');
245  setEventMessages($msg, null, 'warnings');
246  }
247  }
248  else dol_print_error($db);
249  }
250  }
251  header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y?'&page_y='.$page_y:''));
252  exit;
253 }
254 else if ($action == 'reset' && $user->admin && GETPOST('confirm') == 'yes')
255 {
256  $result=unActivateModule($value);
257  if ($result) setEventMessages($result, null, 'errors');
258  header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y?'&page_y='.$page_y:''));
259  exit;
260 }
261 
262 
263 
264 /*
265  * View
266  */
267 
268 $form = new Form($db);
269 
270 //$morejs = array("/admin/dolistore/js/dolistore.js.php");
271 $morecss = array("/admin/dolistore/css/dolistore.css");
272 
273 // Set dir where external modules are installed
274 if (! dol_is_dir($dirins))
275 {
276  dol_mkdir($dirins);
277 }
278 $dirins_ok=(dol_is_dir($dirins));
279 
280 $help_url='EN:First_setup|FR:Premiers_paramétrages|ES:Primeras_configuraciones';
281 llxHeader('',$langs->trans("Setup"),$help_url, '', '', '', $morejs, $morecss, 0, 0);
282 
283 
284 // Search modules dirs
285 $modulesdir = dolGetModulesDirs();
286 
287 $arrayofnatures=array('core'=>$langs->transnoentitiesnoconv("Core"), 'external'=>$langs->transnoentitiesnoconv("External").' - ['.$langs->trans("AllPublishers").']');
288 $arrayofwarnings=array(); // Array of warning each module want to show when activated
289 $arrayofwarningsext=array(); // Array of warning each module want to show when we activate an external module
290 $filename = array();
291 $modules = array();
292 $orders = array();
293 $categ = array();
294 $dirmod = array();
295 $i = 0; // is a sequencer of modules found
296 $j = 0; // j is module number. Automatically affected if module number not defined.
297 $modNameLoaded=array();
298 
299 foreach ($modulesdir as $dir)
300 {
301  // Load modules attributes in arrays (name, numero, orders) from dir directory
302  //print $dir."\n<br>";
303  dol_syslog("Scan directory ".$dir." for module descriptor files (modXXX.class.php)");
304  $handle=@opendir($dir);
305  if (is_resource($handle))
306  {
307  while (($file = readdir($handle))!==false)
308  {
309  //print "$i ".$file."\n<br>";
310  if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php')
311  {
312  $modName = substr($file, 0, dol_strlen($file) - 10);
313 
314  if ($modName)
315  {
316  if (! empty($modNameLoaded[$modName])) // In cache of already loaded modules ?
317  {
318  $mesg="Error: Module ".$modName." was found twice: Into ".$modNameLoaded[$modName]." and ".$dir.". You probably have an old file on your disk.<br>";
319  setEventMessages($mesg, null, 'warnings');
320  dol_syslog($mesg, LOG_ERR);
321  continue;
322  }
323 
324  try
325  {
326  $res=include_once $dir.$file; // A class already exists in a different file will send a non catchable fatal error.
327  if (class_exists($modName))
328  {
329  try {
330  $objMod = new $modName($db);
331  $modNameLoaded[$modName]=$dir;
332  if (! $objMod->numero > 0 && $modName != 'modUser')
333  {
334  dol_syslog('The module descriptor '.$modName.' must have a numero property', LOG_ERR);
335  }
336  $j = $objMod->numero;
337 
338  $modulequalified=1;
339 
340  // We discard modules according to features level (PS: if module is activated we always show it)
341  $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
342  if ($objMod->version == 'development' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 2))) $modulequalified=0;
343  if ($objMod->version == 'experimental' && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL < 1))) $modulequalified=0;
344  if (preg_match('/deprecated/', $objMod->version) && (empty($conf->global->$const_name) && ($conf->global->MAIN_FEATURES_LEVEL >= 0))) $modulequalified=0;
345 
346  // We discard modules according to property ->hidden
347  if (! empty($objMod->hidden)) $modulequalified=0;
348 
349  if ($modulequalified > 0)
350  {
351  $publisher=dol_escape_htmltag($objMod->getPublisher());
352  $external=($objMod->isCoreOrExternalModule() == 'external');
353  if ($external)
354  {
355  if ($publisher)
356  {
357  $arrayofnatures['external_'.$publisher]=$langs->trans("External").' - '.$publisher;
358  }
359  else
360  {
361  $arrayofnatures['external_']=$langs->trans("External").' - '.$langs->trans("UnknownPublishers");
362  }
363  }
364  ksort($arrayofnatures);
365  }
366 
367  // Define array $categ with categ with at least one qualified module
368  if ($modulequalified > 0)
369  {
370  $filename[$i]= $modName;
371  $modules[$modName] = $objMod;
372 
373  // Gives the possibility to the module, to provide his own family info and position of this family
374  if (is_array($objMod->familyinfo) && !empty($objMod->familyinfo)) {
375  $familyinfo = array_merge($familyinfo, $objMod->familyinfo);
376  $familykey = key($objMod->familyinfo);
377  } else {
378  $familykey = $objMod->family;
379  }
380 
381  $moduleposition = ($objMod->module_position?$objMod->module_position:'50');
382  if ($moduleposition == '50' && ($objMod->isCoreOrExternalModule() == 'external'))
383  {
384  $moduleposition = '80'; // External modules at end by default
385  }
386 
387  // Add list of warnings to show into arrayofwarnings and arrayofwarningsext
388  if (! empty($objMod->warnings_activation))
389  {
390  $arrayofwarnings[$modName]=$objMod->warnings_activation;
391  }
392  if (! empty($objMod->warnings_activation_ext))
393  {
394  $arrayofwarningsext[$modName]=$objMod->warnings_activation_ext;
395  }
396 
397  $orders[$i] = $familyinfo[$familykey]['position']."_".$familykey."_".$moduleposition."_".$j; // Sort by family, then by module position then number
398  $dirmod[$i] = $dir;
399  //print $i.'-'.$dirmod[$i].'<br>';
400  // Set categ[$i]
401  $specialstring = 'unknown';
402  if ($objMod->version == 'development' || $objMod->version == 'experimental') $specialstring='expdev';
403  if (isset($categ[$specialstring])) $categ[$specialstring]++; // Array of all different modules categories
404  else $categ[$specialstring]=1;
405  $j++;
406  $i++;
407  }
408  else dol_syslog("Module ".get_class($objMod)." not qualified");
409  }
410  catch(Exception $e)
411  {
412  dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
413  }
414  }
415  else
416  {
417  print "Warning bad descriptor file : ".$dir.$file." (Class ".$modName." not found into file)<br>";
418  }
419  }
420  catch(Exception $e)
421  {
422  dol_syslog("Failed to load ".$dir.$file." ".$e->getMessage(), LOG_ERR);
423  }
424  }
425  }
426  }
427  closedir($handle);
428  }
429  else
430  {
431  dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING);
432  }
433 }
434 
435 if ($action == 'reset_confirm' && $user->admin)
436 {
437  if(!empty($modules[$value])) {
438  $objMod = $modules[$value];
439 
440  if(!empty($objMod->langfiles)) $langs->loadLangs($objMod->langfiles);
441 
442  $form = new Form($db);
443  $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?value='.$value.'&mode='.$mode.$param, $langs->trans('ConfirmUnactivation'), $langs->trans(GETPOST('confirm_message_code')), 'reset', '', 'no', 1);
444  }
445 }
446 
447 print $formconfirm;
448 
449 asort($orders);
450 //var_dump($orders);
451 //var_dump($categ);
452 //var_dump($modules);
453 
454 $nbofactivatedmodules=count($conf->modules);
455 $moreinfo=$langs->trans("TotalNumberOfActivatedModules",($nbofactivatedmodules-1), count($modules));
456 if ($nbofactivatedmodules <= 1) $moreinfo .= ' '.img_warning($langs->trans("YouMustEnableOneModule"));
457 print load_fiche_titre($langs->trans("ModulesSetup"),$moreinfo,'title_setup');
458 
459 // Start to show page
460 if ($mode=='common') print '<span class="opacitymedium">'.$langs->trans("ModulesDesc")."</span><br>\n";
461 if ($mode=='marketplace') print '<span class="opacitymedium">'.$langs->trans("ModulesMarketPlaceDesc")."</span><br>\n";
462 if ($mode=='deploy') print '<span class="opacitymedium">'.$langs->trans("ModulesDeployDesc", $langs->transnoentitiesnoconv("AvailableModules"))."</span><br>\n";
463 if ($mode=='develop') print '<span class="opacitymedium">'.$langs->trans("ModulesDevelopDesc")."</span><br>\n";
464 
465 $head = modules_prepare_head();
466 
467 
468 print "<br>\n";
469 
470 
471 if ($mode == 'common')
472 {
473  dol_set_focus('#search_keyword');
474 
475  print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
476  if ($optioncss != '') print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
477  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
478  print '<input type="hidden" name="sortfield" value="'.$sortfield.'">';
479  print '<input type="hidden" name="sortorder" value="'.$sortorder.'">';
480  print '<input type="hidden" name="page" value="'.$page.'">';
481 
482  dol_fiche_head($head, $mode, '', -1);
483 
484  $moreforfilter = '';
485  $moreforfilter.='<div class="divsearchfield">';
486  $moreforfilter.= $langs->trans('Keyword') . ': <input type="text" id="search_keyword" name="search_keyword" value="'.dol_escape_htmltag($search_keyword).'">';
487  $moreforfilter.= '</div>';
488  $moreforfilter.='<div class="divsearchfield">';
489  $moreforfilter.= $langs->trans('Origin') . ': '.$form->selectarray('search_nature', $arrayofnatures, dol_escape_htmltag($search_nature), 1);
490  $moreforfilter.= '</div>';
491  if (! empty($conf->global->MAIN_FEATURES_LEVEL))
492  {
493  $array_version = array('stable'=>$langs->transnoentitiesnoconv("Stable"));
494  if ($conf->global->MAIN_FEATURES_LEVEL < 0) $array_version['deprecated']=$langs->trans("Deprecated");
495  if ($conf->global->MAIN_FEATURES_LEVEL > 0) $array_version['experimental']=$langs->trans("Experimental");
496  if ($conf->global->MAIN_FEATURES_LEVEL > 1) $array_version['development']=$langs->trans("Development");
497  $moreforfilter.='<div class="divsearchfield">';
498  $moreforfilter.= $langs->trans('Version') . ': '.$form->selectarray('search_version', $array_version, $search_version, 1);
499  $moreforfilter.= '</div>';
500  }
501  $moreforfilter.='<div class="divsearchfield">';
502  $moreforfilter.= $langs->trans('Status') . ': '.$form->selectarray('search_status', array('active'=>$langs->transnoentitiesnoconv("Enabled"), 'disabled'=>$langs->transnoentitiesnoconv("Disabled")), $search_status, 1);
503  $moreforfilter.= '</div>';
504  $moreforfilter.=' ';
505  $moreforfilter.='<div class="divsearchfield">';
506  $moreforfilter.='<input type="submit" name="buttonsubmit" class="button" value="'.dol_escape_htmltag($langs->trans("Refresh")).'">';
507  $moreforfilter.=' ';
508  $moreforfilter.='<input type="submit" name="buttonreset" class="button" value="'.dol_escape_htmltag($langs->trans("Reset")).'">';
509  $moreforfilter.= '</div>';
510 
511  if (! empty($moreforfilter))
512  {
513  print $moreforfilter;
514  $parameters=array();
515  $reshook=$hookmanager->executeHooks('printFieldPreListTitle',$parameters); // Note that $action and $object may have been modified by hook
516  print $hookmanager->resPrint;
517  }
518 
519  $moreforfilter='';
520 
521  print '<div class="clearboth"></div><br>';
522 
523  $parameters=array();
524  $reshook=$hookmanager->executeHooks('insertExtraHeader',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
525  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
526 
527  // Show list of modules
528 
529  $oldfamily='';
530 
531  foreach ($orders as $key => $value)
532  {
533  $tab=explode('_',$value);
534  $familyposition=$tab[0]; $familykey=$tab[1]; $module_position=$tab[2]; $numero=$tab[3];
535 
536  $modName = $filename[$key];
537  $objMod = $modules[$modName];
538  $dirofmodule = $dirmod[$key];
539 
540  //print $objMod->name." - ".$key." - ".$objMod->version."<br>";
541  //if (($mode != (isset($specialtostring[$special])?$specialtostring[$special]:'unknown') && $mode != 'expdev')
542  if ($mode == 'expdev' && $objMod->version != 'development' && $objMod->version != 'experimental') continue; // Discard if not for current tab
543 
544  if (! $objMod->getName())
545  {
546  dol_syslog("Error for module ".$key." - Property name of module looks empty", LOG_WARNING);
547  continue;
548  }
549 
550  $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod)));
551 
552  // Check filters
553  $modulename=$objMod->getName();
554  $moduletechnicalname=$objMod->name;
555  $moduledesc=$objMod->getDesc();
556  $moduledesclong=$objMod->getDescLong();
557  $moduleauthor=$objMod->getPublisher();
558 
559  // We discard showing according to filters
560  if ($search_keyword)
561  {
562  $qualified=0;
563  if (preg_match('/'.preg_quote($search_keyword).'/i', $modulename)
564  || preg_match('/'.preg_quote($search_keyword).'/i', $moduletechnicalname)
565  || preg_match('/'.preg_quote($search_keyword).'/i', $moduledesc)
566  || preg_match('/'.preg_quote($search_keyword).'/i', $moduledesclong)
567  || preg_match('/'.preg_quote($search_keyword).'/i', $moduleauthor)
568  ) $qualified=1;
569  if (! $qualified) continue;
570  }
571  if ($search_status)
572  {
573  if ($search_status == 'active' && empty($conf->global->$const_name)) continue;
574  if ($search_status == 'disabled' && ! empty($conf->global->$const_name)) continue;
575  }
576  if ($search_nature)
577  {
578  if (preg_match('/^external/',$search_nature) && $objMod->isCoreOrExternalModule() != 'external') continue;
579  if (preg_match('/^external_(.*)$/',$search_nature, $reg))
580  {
581  //print $reg[1].'-'.dol_escape_htmltag($objMod->getPublisher());
582  $publisher=dol_escape_htmltag($objMod->getPublisher());
583  if ($reg[1] && dol_escape_htmltag($reg[1]) != $publisher) continue;
584  if (! $reg[1] && ! empty($publisher)) continue;
585  }
586  if ($search_nature == 'core' && $objMod->isCoreOrExternalModule() == 'external') continue;
587  }
588  if ($search_version)
589  {
590  if (($objMod->version == 'development' || $objMod->version == 'experimental' || preg_match('/deprecated/', $objMod->version)) && $search_version == 'stable') continue;
591  if ($objMod->version != 'development' && ($search_version == 'development')) continue;
592  if ($objMod->version != 'experimental' && ($search_version == 'experimental')) continue;
593  if (! preg_match('/deprecated/', $objMod->version) && ($search_version == 'deprecated')) continue;
594  }
595 
596  // Load all lang files of module
597  if (isset($objMod->langfiles) && is_array($objMod->langfiles))
598  {
599  foreach($objMod->langfiles as $domain)
600  {
601  $langs->load($domain);
602  }
603  }
604 
605  // Print a separator if we change family
606  if ($familykey != $oldfamily) {
607  if ($oldfamily) {
608  print '</table></div><br>';
609  }
610 
611  $familytext = empty($familyinfo[$familykey]['label'])?$familykey:$familyinfo[$familykey]['label'];
612  print load_fiche_titre($familytext, '', '');
613 
614  print '<div class="div-table-responsive">';
615  print '<table class="tagtable liste" summary="list_of_modules">'."\n";
616 
617  $atleastoneforfamily=0;
618  }
619 
620  $atleastoneforfamily++;
621 
622  if ($familykey!=$oldfamily)
623  {
624  $familytext=empty($familyinfo[$familykey]['label'])?$familykey:$familyinfo[$familykey]['label'];
625  $oldfamily=$familykey;
626  }
627 
628 
629 
630 
631  // Version (with picto warning or not)
632  $version=$objMod->getVersion(0);
633  $versiontrans='';
634  if (preg_match('/development/i', $version)) $versiontrans.=img_warning($langs->trans("Development"), 'style="float: left"');
635  if (preg_match('/experimental/i', $version)) $versiontrans.=img_warning($langs->trans("Experimental"), 'style="float: left"');
636  if (preg_match('/deprecated/i', $version)) $versiontrans.=img_warning($langs->trans("Deprecated"), 'style="float: left"');
637  $versiontrans.=$objMod->getVersion(1);
638 
639  // Define imginfo
640  $imginfo="info";
641  if ($objMod->isCoreOrExternalModule() == 'external')
642  {
643  $imginfo="info_black";
644  }
645 
646  print '<tr class="oddeven">'."\n";
647  if (!empty($conf->global->MAIN_MODULES_SHOW_LINENUMBERS)) print '<td width="20px">'.++$linenum.'</td>';
648 
649  // Picto + Name of module
650  print ' <td width="200px">';
651  $alttext='';
652  //if (is_array($objMod->need_dolibarr_version)) $alttext.=($alttext?' - ':'').'Dolibarr >= '.join('.',$objMod->need_dolibarr_version);
653  //if (is_array($objMod->phpmin)) $alttext.=($alttext?' - ':'').'PHP >= '.join('.',$objMod->phpmin);
654  if (! empty($objMod->picto))
655  {
656  if (preg_match('/^\//i',$objMod->picto)) print img_picto($alttext,$objMod->picto,' width="14px"',1);
657  else print img_object($alttext, $objMod->picto, 'class="valignmiddle" width="14px"');
658  }
659  else
660  {
661  print img_object($alttext, 'generic', 'class="valignmiddle"');
662  }
663  print ' <span class="valignmiddle">'.$objMod->getName().'</span>';
664  print "</td>\n";
665 
666  // Desc
667  print '<td class="valignmiddle tdoverflowmax300">';
668  print nl2br($objMod->getDesc());
669  print "</td>\n";
670 
671  // Help
672  print '<td class="center nowrap" style="width: 82px;">';
673  //print $form->textwithpicto('', $text, 1, $imginfo, 'minheight20', 0, 2, 1);
674  print '<a href="javascript:document_preview(\''.DOL_URL_ROOT.'/admin/modulehelp.php?id='.$objMod->numero.'\',\'text/html\',\''.dol_escape_js($langs->trans("Module")).'\')">'.img_picto($langs->trans("ClickToShowDescription"), $imginfo).'</a>';
675  print '</td>';
676 
677  // Version
678  print '<td class="center nowrap" width="120px">';
679  print $versiontrans;
680  if(!empty($conf->global->CHECKLASTVERSION_EXTERNALMODULE)){
681  require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php';
682  if (!empty($objMod->url_last_version)) {
683  $newversion = getURLContent($objMod->url_last_version);
684  if(isset($newversion['content'])){
685  if (version_compare($newversion['content'], $versiontrans) > 0) {
686  print "&nbsp;<span class='butAction' title='" . $langs->trans('LastStableVersion') . "'>".$newversion['content']."</span>";
687  }
688  }
689  }
690  }
691  print "</td>\n";
692 
693  // Activate/Disable and Setup (2 columns)
694  if (! empty($conf->global->$const_name)) // If module is already activated
695  {
696  $disableSetup = 0;
697 
698  // Link enable/disabme
699  print '<td class="center valignmiddle" width="60px">';
700  if (! empty($arrayofwarnings[$modName]))
701  {
702  print '<!-- This module has a warning to show when we activate it (note: your country is '.$mysoc->country_code.') -->'."\n";
703  }
704  if (! empty($objMod->disabled))
705  {
706  print $langs->trans("Disabled");
707  }
708  else if (! empty($objMod->always_enabled) || ((! empty($conf->multicompany->enabled) && $objMod->core_enabled) && ($user->entity || $conf->entity!=1)))
709  {
710  if (method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) print $langs->trans("Used");
711  else {
712  print img_picto($langs->trans("Required"),'switch_on');
713  print $langs->trans("Required");
714  }
715  if (! empty($conf->multicompany->enabled) && $user->entity) $disableSetup++;
716  }
717  else
718  {
719  if(!empty($objMod->warnings_unactivation[$mysoc->country_code]) && method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) {
720  print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=reset_confirm&amp;confirm_message_code='.$objMod->warnings_unactivation[$mysoc->country_code].'&amp;value=' . $modName . '&amp;mode=' . $mode . $param . '">';
721  print img_picto($langs->trans("Activated"),'switch_on');
722  print '</a>';
723  }
724  else {
725 
726  print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=reset&amp;value=' . $modName . '&amp;mode=' . $mode .'&amp;confirm=yes' . $param . '">';
727  print img_picto($langs->trans("Activated"),'switch_on');
728  print '</a>';
729  }
730  }
731  print '</td>'."\n";
732 
733  // Link config
734  if (! empty($objMod->config_page_url) && !$disableSetup)
735  {
736  $backtourlparam='';
737  if ($search_keyword != '') $backtourlparam.=($backtourlparam?'&':'?').'search_keyword='.$search_keyword; // No urlencode here, done later
738  if ($search_nature > -1) $backtourlparam.=($backtourlparam?'&':'?').'search_nature='.$search_nature;
739  if ($search_version > -1) $backtourlparam.=($backtourlparam?'&':'?').'search_version='.$search_version;
740  if ($search_status > -1) $backtourlparam.=($backtourlparam?'&':'?').'search_status='.$search_status;
741  $backtourl=$_SERVER["PHP_SELF"].$backtourlparam;
742 
743  if (is_array($objMod->config_page_url))
744  {
745  print '<td class="tdsetuppicto right" width="60px">';
746  $i=0;
747  foreach ($objMod->config_page_url as $page)
748  {
749  $urlpage=$page;
750  if ($i++)
751  {
752  print '<a href="'.$urlpage.'" title="'.$langs->trans($page).'">'.img_picto(ucfirst($page),"setup").'</a>';
753  // print '<a href="'.$page.'">'.ucfirst($page).'</a>&nbsp;';
754  }
755  else
756  {
757  if (preg_match('/^([^@]+)@([^@]+)$/i',$urlpage,$regs))
758  {
759  $urltouse=dol_buildpath('/'.$regs[2].'/admin/'.$regs[1],1);
760  print '<a href="'.$urltouse.(preg_match('/\?/',$urltouse)?'&':'?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a>';
761  }
762  else
763  {
764  $urltouse=$urlpage;
765  print '<a href="'.$urltouse.(preg_match('/\?/',$urltouse)?'&':'?').'save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a>';
766  }
767  }
768  }
769  print "</td>\n";
770  }
771  else if (preg_match('/^([^@]+)@([^@]+)$/i',$objMod->config_page_url,$regs))
772  {
773  print '<td class="tdsetuppicto right valignmiddle" width="60px"><a href="'.dol_buildpath('/'.$regs[2].'/admin/'.$regs[1],1).'?save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a></td>';
774  }
775  else
776  {
777  print '<td class="tdsetuppicto right valignmiddle" width="60px"><a href="'.$objMod->config_page_url.'?save_lastsearch_values=1&backtopage='.urlencode($backtourl).'" title="'.$langs->trans("Setup").'">'.img_picto($langs->trans("Setup"),"setup",'style="padding-right: 6px"').'</a></td>';
778  }
779  }
780  else
781  {
782  print '<td class="tdsetuppicto right valignmiddle" width="60px">'.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').'</td>';
783  }
784  }
785  else // Module not yet activated
786  {
787  // Link enable/disable
788  print '<td class="center valignmiddle" width="60px">';
789  if (! empty($objMod->always_enabled))
790  {
791  // Should never happened
792  }
793  else if (! empty($objMod->disabled))
794  {
795  print $langs->trans("Disabled");
796  }
797  else
798  {
799  // Module qualified for activation
800  $warningmessage='';
801  if (! empty($arrayofwarnings[$modName]))
802  {
803  print '<!-- This module has a warning to show when we activate it (note: your country is '.$mysoc->country_code.') -->'."\n";
804  foreach ($arrayofwarnings[$modName] as $keycountry => $cursorwarningmessage)
805  {
806  $warningmessage .= ($warningmessage?"\n":"").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code);
807  }
808  }
809  if ($objMod->isCoreOrExternalModule() == 'external' && ! empty($arrayofwarningsext))
810  {
811  print '<!-- This module is an external module and it may have a warning to show (note: your country is '.$mysoc->country_code.') -->'."\n";
812  foreach ($arrayofwarningsext as $keymodule => $arrayofwarningsextbycountry)
813  {
814  $keymodulelowercase=strtolower(preg_replace('/^mod/','',$keymodule));
815  if (in_array($keymodulelowercase, $conf->modules)) // If module that request warning is on
816  {
817  foreach ($arrayofwarningsextbycountry as $keycountry => $cursorwarningmessage)
818  {
819  if (preg_match('/^always/', $keycountry) || ($mysoc->country_code && preg_match('/^'.$mysoc->country_code.'/', $keycountry)))
820  {
821  $warningmessage .= ($warningmessage?"\n":"").$langs->trans($cursorwarningmessage, $objMod->getName(), $mysoc->country_code, $modules[$keymodule]->getName());
822  $warningmessage .= ($warningmessage?"\n":"").($warningmessage?"\n":"").$langs->trans("Module").' : '.$objMod->getName();
823  if (! empty($objMod->editor_name)) $warningmessage .= ($warningmessage?"\n":"").$langs->trans("Publisher").' : '.$objMod->editor_name;
824  if (! empty($objMod->editor_name)) $warningmessage .= ($warningmessage?"\n":"").$langs->trans("ModuleTriggeringThisWarning").' : '.$modules[$keymodule]->getName();
825  }
826  }
827  }
828  }
829  }
830  print '<!-- Message to show: '.$warningmessage.' -->'."\n";
831  print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&amp;module_position='.$module_position.'&amp;action=set&amp;value=' . $modName . '&amp;mode=' . $mode . $param . '"';
832  if ($warningmessage) print ' onclick="return confirm(\''.dol_escape_js($warningmessage).'\');"';
833  print '>';
834  print img_picto($langs->trans("Disabled"),'switch_off');
835  print "</a>\n";
836  }
837  print "</td>\n";
838 
839  // Link config
840  print '<td class="tdsetuppicto right valignmiddle" width="60px">'.img_picto($langs->trans("NothingToSetup"),"setup",'class="opacitytransp" style="padding-right: 6px"').'</td>';
841  }
842 
843  print "</tr>\n";
844  }
845 
846  if ($oldfamily)
847  {
848  print "</table>\n";
849  print '</div>';
850  }
851 
852  dol_fiche_end();
853 
854  print '<br>';
855 
856  // Show warning about external users
857  print info_admin(showModulesExludedForExternal($modules))."\n";
858 
859  print '</form>';
860 }
861 
862 if ($mode == 'marketplace')
863 {
864  dol_fiche_head($head, $mode, '', -1);
865 
866  // Marketplace
867  print "<table summary=\"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
868  print "<tr class=\"liste_titre\">\n";
869  //print '<td>'.$langs->trans("Logo").'</td>';
870  print '<td colspan="2">'.$langs->trans("WebSiteDesc").'</td>';
871  print '<td>'.$langs->trans("URL").'</td>';
872  print '</tr>';
873 
874  print "<tr class=\"oddeven\">\n";
875  $url='https://www.dolistore.com';
876  print '<td align="left"><a href="'.$url.'" target="_blank" rel="external"><img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolistore_logo.png"></a></td>';
877  print '<td>'.$langs->trans("DoliStoreDesc").'</td>';
878  print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';
879  print '</tr>';
880 
881  print "</table>\n";
882 
883  dol_fiche_end();
884 
885  print '<br>';
886 
887  if (empty($conf->global->MAIN_DISABLE_DOLISTORE_SEARCH) && $conf->global->MAIN_FEATURES_LEVEL >= 1)
888  {
889  // $options is array with filter criterias
890  //var_dump($options);
891  $dolistore->getRemoteData($options);
892 
893  print '<span class="opacitymedium">'.$langs->trans('DOLISTOREdescriptionLong').'</span><br><br>';
894 
895  $previouslink = $dolistore->get_previous_link();
896  $nextlink = $dolistore->get_next_link();
897 
898  print '<div class="liste_titre liste_titre_bydiv centpercent"><div class="divsearchfield">'
899 
900  ?>
901  <form method="POST" class="centpercent" id="searchFormList" action="<?php echo $dolistore->url ?>">
902  <input type="hidden" name="mode" value="marketplace" />
903  <div class="divsearchfield"><?php echo $langs->trans('Keyword') ?>:
904  <input name="search_keyword" placeholder="<?php echo $langs->trans('Chercher un module') ?>" id="search_keyword" type="text" size="50" value="<?php echo $options['search'] ?>"><br>
905  </div>
906  <div class="divsearchfield">
907  <input class="button" value="<?php echo $langs->trans('Rechercher') ?>" type="submit">
908  <a class="button" href="<?php echo $dolistore->url ?>"><?php echo $langs->trans('Reset') ?></a>
909 
910  &nbsp;
911  </div>
912  <div class="divsearchfield right">
913  <?php
914  print $previouslink;
915  print $nextlink;
916  ?>
917  </div>
918  </form>
919 
920  <?php
921 
922  print '</div></div>';
923  print '<div class="clearboth"></div>';
924 
925  ?>
926 
927  <div id="category-tree-left">
928  <ul class="tree">
929  <?php echo $dolistore->get_categories(); ?>
930  </ul>
931  </div>
932  <div id="listing-content">
933  <table summary="list_of_modules" id="list_of_modules" class="productlist centpercent">
934  <tbody id="listOfModules">
935  <?php echo $dolistore->get_products($categorie); ?>
936  </tbody>
937  </table>
938  </div>
939 
940  <?php
941  }
942 }
943 
944 
945 // Install external module
946 
947 if ($mode == 'deploy')
948 {
949  dol_fiche_head($head, $mode, '', -1);
950 
951  $dolibarrdataroot=preg_replace('/([\\/]+)$/i','',DOL_DATA_ROOT);
952  $allowonlineinstall=true;
953  $allowfromweb=1;
954  if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) $allowonlineinstall=false;
955 
956  $fullurl='<a href="'.$urldolibarrmodules.'" target="_blank">'.$urldolibarrmodules.'</a>';
957  $message='';
958  if (! empty($allowonlineinstall))
959  {
960  if (! in_array('/custom',explode(',',$dolibarr_main_url_root_alt)))
961  {
962  $message=info_admin($langs->trans("ConfFileMustContainCustom", DOL_DOCUMENT_ROOT.'/custom', DOL_DOCUMENT_ROOT));
963  $allowfromweb=-1;
964  }
965  else
966  {
967  if ($dirins_ok)
968  {
969  if (! is_writable(dol_osencode($dirins)))
970  {
971  $langs->load("errors");
972  $message=info_admin($langs->trans("ErrorFailedToWriteInDir",$dirins));
973  $allowfromweb=0;
974  }
975  }
976  else
977  {
978  $message=info_admin($langs->trans("NotExistsDirect",$dirins).$langs->trans("InfDirAlt").$langs->trans("InfDirExample"));
979  $allowfromweb=0;
980  }
981  }
982  }
983  else
984  {
985  $message=info_admin($langs->trans("InstallModuleFromWebHasBeenDisabledByFile",$dolibarrdataroot.'/installmodules.lock'));
986  $allowfromweb=0;
987  }
988 
989  if ($allowfromweb < 1)
990  {
991  print $langs->trans("SomethingMakeInstallFromWebNotPossible");
992  print $message;
993  //print $langs->trans("SomethingMakeInstallFromWebNotPossible2");
994  print '<br>';
995  }
996 
997  print '<br>';
998 
999  if ($allowfromweb >= 0)
1000  {
1001  if ($allowfromweb == 1)
1002  {
1003  //print $langs->trans("ThisIsProcessToFollow").'<br>';
1004  }
1005  else
1006  {
1007  print $langs->trans("ThisIsAlternativeProcessToFollow").'<br>';
1008  print '<b>'.$langs->trans("StepNb",1).'</b>: ';
1009  print $langs->trans("FindPackageFromWebSite",$fullurl).'<br>';
1010  print '<b>'.$langs->trans("StepNb",2).'</b>: ';
1011  print $langs->trans("DownloadPackageFromWebSite",$fullurl).'<br>';
1012  print '<b>'.$langs->trans("StepNb",3).'</b>: ';
1013  }
1014 
1015  if ($allowfromweb == 1)
1016  {
1017  print $langs->trans("UnpackPackageInModulesRoot",$dirins).'<br>';
1018 
1019  print '<br>';
1020 
1021  print '<form enctype="multipart/form-data" method="POST" class="noborder" action="'.$_SERVER["PHP_SELF"].'" name="forminstall">';
1022  print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
1023  print '<input type="hidden" name="action" value="install">';
1024  print '<input type="hidden" name="mode" value="deploy">';
1025 
1026  print $langs->trans("YouCanSubmitFile");
1027 
1028  $max=$conf->global->MAIN_UPLOAD_DOC; // En Kb
1029  $maxphp=@ini_get('upload_max_filesize'); // En inconnu
1030  if (preg_match('/k$/i',$maxphp)) $maxphp=$maxphp*1;
1031  if (preg_match('/m$/i',$maxphp)) $maxphp=$maxphp*1024;
1032  if (preg_match('/g$/i',$maxphp)) $maxphp=$maxphp*1024*1024;
1033  if (preg_match('/t$/i',$maxphp)) $maxphp=$maxphp*1024*1024*1024;
1034  // Now $max and $maxphp are in Kb
1035  $maxmin = $max;
1036  if ($maxphp > 0) $maxmin=min($max,$maxphp);
1037 
1038  if ($maxmin > 0)
1039  {
1040  print '<script type="text/javascript">
1041  $(document).ready(function() {
1042  jQuery("#fileinstall").on("change", function() {
1043  if(this.files[0].size > '.($maxmin*1024).'){
1044  alert("'.dol_escape_js($langs->trans("ErrorFileSizeTooLarge")).'");
1045  this.value = "";
1046  };
1047  });
1048  });
1049  </script>'."\n";
1050  // MAX_FILE_SIZE doit précéder le champ input de type file
1051  print '<input type="hidden" name="max_file_size" value="'.($maxmin*1024).'">';
1052  }
1053 
1054  print '<input class="flat minwidth400" type="file" name="fileinstall" id="fileinstall"> ';
1055 
1056  print '<input type="submit" name="send" value="'.dol_escape_htmltag($langs->trans("Send")).'" class="button">';
1057 
1058  if (! empty($conf->global->MAIN_UPLOAD_DOC))
1059  {
1060  if ($user->admin)
1061  {
1062  $langs->load('other');
1063  print ' ';
1064  print info_admin($langs->trans("ThisLimitIsDefinedInSetup",$max,$maxphp),1);
1065  }
1066  }
1067  else
1068  {
1069  print ' ('.$langs->trans("UploadDisabled").')';
1070  }
1071 
1072  print '</form>';
1073 
1074  print '<br>';
1075  print '<br>';
1076 
1077  print '<div class="center"><div class="logo_setup"></div></div>';
1078  }
1079  else
1080  {
1081  print $langs->trans("UnpackPackageInModulesRoot",$dirins).'<br>';
1082  print '<b>'.$langs->trans("StepNb",4).'</b>: ';
1083  print $langs->trans("SetupIsReadyForUse").'<br>';
1084  }
1085  }
1086 
1087  if (! empty($result['return']))
1088  {
1089  print '<br>';
1090 
1091  foreach($result['return'] as $value)
1092  {
1093  echo $value.'<br>';
1094  }
1095  }
1096 
1097  dol_fiche_end();
1098 }
1099 
1100 if ($mode == 'develop')
1101 {
1102  dol_fiche_head($head, $mode, '', -1);
1103 
1104  // Marketplace
1105  print "<table summary=\"list_of_modules\" class=\"noborder\" width=\"100%\">\n";
1106  print "<tr class=\"liste_titre\">\n";
1107  //print '<td>'.$langs->trans("Logo").'</td>';
1108  print '<td colspan="2">'.$langs->trans("DevelopYourModuleDesc").'</td>';
1109  print '<td>'.$langs->trans("URL").'</td>';
1110  print '</tr>';
1111 
1112  print '<tr class="oddeven" height="80">'."\n";
1113  print '<td align="left">';
1114  //span class="fa fa-bug"></span>
1115  //print '<img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolibarr_preferred_partner_int.png">';
1116  print '<div class="imgmaxheight50 logo_setup"></div>';
1117  print '</td>';
1118  print '<td>'.$langs->trans("TryToUseTheModuleBuilder", $langs->transnoentitiesnoconv("ModuleBuilder")).'</td>';
1119  print '<td>'.$langs->trans("SeeTopRightMenu").'</td>';
1120  print '</tr>';
1121 
1122  print '<tr class="oddeven" height="80">'."\n";
1123  $url='https://partners.dolibarr.org';
1124  print '<td align="left">';
1125  print'<a href="'.$url.'" target="_blank" rel="external"><img border="0" class="imgautosize imgmaxwidth180" src="'.DOL_URL_ROOT.'/theme/dolibarr_preferred_partner_int.png"></a>';
1126  print '</td>';
1127  print '<td>'.$langs->trans("DoliPartnersDesc").'</td>';
1128  print '<td><a href="'.$url.'" target="_blank" rel="external">'.$url.'</a></td>';
1129  print '</tr>';
1130 
1131  print "</table>\n";
1132 
1133  dol_fiche_end();
1134 }
1135 
1136 // End of page
1137 llxFooter();
1138 $db->close();
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
img_warning($titlealt='default', $moreatt='')
Show warning logo.
llxFooter()
Empty footer.
Definition: wrapper.php:56
load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
GETPOST($paramname, $check='none', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
print
Draft customers invoices.
Definition: index.php:91
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile')
Make control on an uploaded file from an GUI page and move it to final destination.
Definition: files.lib.php:996
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
unActivateModule($value, $requiredby=1)
Disable a module.
Definition: admin.lib.php:1011
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dolGetModulesDirs($subdir='')
Return list of modules directories.
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
dol_is_dir($folder)
Test if filename is a directory.
Definition: files.lib.php:438
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:103
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0)
Returns text escaped for inclusion in HTML alt or title tags, or into values of HTML input fields...
dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null)
Copy a dir to another dir.
Definition: files.lib.php:722
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Class to manage generation of HTML components Only common components must be here.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
type
Definition: viewcat.php:284
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='')
Show information for admin users or standard users.
dol_fiche_end($notab=0)
Show tab footer of a card.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories) ...
Definition: files.lib.php:1273
llxHeader()
Empty header.
Definition: wrapper.php:44
if(GETPOST('cancel', 'alpha')) if(! GETPOST( 'confirmmassaction', 'alpha') &&$massaction !='presend' &&$massaction !='confirm_presend')
Draft customers invoices.
Definition: list.php:156
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:451
dol_uncompress($inputfile, $outputdir)
Uncompress a file.
Definition: files.lib.php:1930
Class Dolistore.
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
activateModule($value, $withdeps=1)
Enable a module.
Definition: admin.lib.php:867
modules_prepare_head()
Prepare array with list of tabs.
Definition: admin.lib.php:571
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it&#39;s its name (generic function)
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_set_focus($selector)
Set focus onto field with selector (similar behaviour of &#39;autofocus&#39; HTML5 tag)
dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='')
Show tab header of a card.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)