From f711144428020480ba742089b4f5a9d8e7e64a5f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Jan 2024 14:52:12 +0100 Subject: [PATCH] Try to move tmp dir --- {build/phpstan => .github}/tmp/.gitkeep | 0 .github/workflows/phpstan.yml | 4 +- build/phpstan/bootstrap.php | 1 + build/phpstan/bootstrap_action.php | 2 + .../modules/mailings/modules_mailings.php | 129 ++++++++++++++++++ htdocs/langs/en_US/modulebuilder.lang | 4 + htdocs/modulebuilder/index.php | 58 ++++++++ phpstan_action.neon | 2 +- 8 files changed, 197 insertions(+), 3 deletions(-) rename {build/phpstan => .github}/tmp/.gitkeep (100%) diff --git a/build/phpstan/tmp/.gitkeep b/.github/tmp/.gitkeep similarity index 100% rename from build/phpstan/tmp/.gitkeep rename to .github/tmp/.gitkeep diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index e8e3b0430ba..4b52bb51c45 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -44,7 +44,7 @@ jobs: - name: Restore phpstan cache uses: actions/cache/restore@v3 with: - path: ./tmp + path: ./github/tmp key: "phpstan-cache-PR-${{ matrix.php-version }}-${{ github.run_id }}" restore-keys: | phpstan-cache-PR-${{ matrix.php-version }}- @@ -57,5 +57,5 @@ jobs: uses: actions/cache/save@v3 if: always() with: - path: ./tmp + path: ./github/tmp key: "phpstan-cache-PR-${{ matrix.php-version }}-${{ github.run_id }}" diff --git a/build/phpstan/bootstrap.php b/build/phpstan/bootstrap.php index 2a3131b6f5a..b0cb9f90ef0 100644 --- a/build/phpstan/bootstrap.php +++ b/build/phpstan/bootstrap.php @@ -15,5 +15,6 @@ if (!defined("NOSESSION")) { if (!defined("NOHTTPSREDIRECT")) { define("NOHTTPSREDIRECT", '1'); } + global $conf, $langs, $user, $db; include_once __DIR__ . '/../../htdocs/main.inc.php'; diff --git a/build/phpstan/bootstrap_action.php b/build/phpstan/bootstrap_action.php index f56067d66d8..e40a132ead3 100644 --- a/build/phpstan/bootstrap_action.php +++ b/build/phpstan/bootstrap_action.php @@ -1,4 +1,5 @@ update_nb($mailing_id); } + + + /** + * Return list of widget. Function used by admin page htdoc/admin/widget. + * List is sorted by widget filename so by priority to run. + * + * @param array $forcedir null=All default directories. This parameter is used by modulebuilder module only. + * @return array Array list of widget + */ + public static function getEmailingSelectorsList($forcedir = null) + { + global $langs, $db; + + $files = array(); + $fullpath = array(); + $relpath = array(); + $iscoreorexternal = array(); + $modules = array(); + $orders = array(); + $i = 0; + + $dirwidget = array('/core/emailings/'); // $conf->modules_parts['emailings'] is not required + if (is_array($forcedir)) { + $dirwidget = $forcedir; + } + + foreach ($dirwidget as $reldir) { + $dir = dol_buildpath($reldir, 0); + $newdir = dol_osencode($dir); + + // Check if directory exists (we do not use dol_is_dir to avoid loading files.lib.php at each call) + if (!is_dir($newdir)) { + continue; + } + + $handle = opendir($newdir); + if (is_resource($handle)) { + while (($file = readdir($handle)) !== false) { + $reg = array(); + if (is_readable($newdir.'/'.$file) && preg_match('/^(.+)\.php/', $file, $reg)) { + if (preg_match('/\.back$/', $file) || preg_match('/^(.+)\.disabled\.php/', $file)) { + continue; + } + + $part1 = $reg[1]; + + $modName = ucfirst($reg[1]); + //print "file=$file"; print "modName=$modName"; exit; + if (in_array($modName, $modules)) { + $langs->load("errors"); + print '
'.$langs->trans("Error").' : '.$langs->trans("ErrorDuplicateWidget", $modName, "").'
'; + } else { + try { + include_once $newdir.'/'.$file; + } catch (Exception $e) { + print $e->getMessage(); + } + } + + $files[$i] = $file; + $fullpath[$i] = $dir.'/'.$file; + $relpath[$i] = preg_replace('/^\//', '', $reldir).'/'.$file; + $iscoreorexternal[$i] = ($reldir == '/core/boxes/' ? 'internal' : 'external'); + $modules[$i] = $modName; + $orders[$i] = $part1; // Set sort criteria value + + $i++; + } + } + closedir($handle); + } + } + //echo "
";print_r($modules);echo "
"; + + asort($orders); + + $widget = array(); + $j = 0; + + // Loop on each widget + foreach ($orders as $key => $value) { + $modName = $modules[$key]; + if (empty($modName)) { + continue; + } + + if (!class_exists($modName)) { + print 'Error: A widget file was found but its class "'.$modName.'" was not found.'."
\n"; + continue; + } + + $objMod = new $modName($db); + if (is_object($objMod)) { + // Define disabledbyname and disabledbymodule + $disabledbyname = 0; + $disabledbymodule = 0; // TODO Set to 2 if module is not enabled + $module = ''; + + // Check if widget file is disabled by name + if (preg_match('/NORUN$/i', $files[$key])) { + $disabledbyname = 1; + } + + // We set info of modules + $widget[$j]['picto'] = (empty($objMod->picto) ? (empty($objMod->boximg) ? img_object('', 'generic') : $objMod->boximg) : img_object('', $objMod->picto)); + $widget[$j]['file'] = $files[$key]; + $widget[$j]['fullpath'] = $fullpath[$key]; + $widget[$j]['relpath'] = $relpath[$key]; + $widget[$j]['iscoreorexternal'] = $iscoreorexternal[$key]; + $widget[$j]['version'] = empty($objMod->version) ? '' : $objMod->version; + $widget[$j]['status'] = img_picto($langs->trans("Active"), 'tick'); + if ($disabledbyname > 0 || $disabledbymodule > 1) { + $widget[$j]['status'] = ''; + } + + $text = ''.$langs->trans("Description").':
'; + $text .= $objMod->boxlabel.'
'; + $text .= '
'.$langs->trans("Status").':
'; + if ($disabledbymodule == 2) { + $text .= $langs->trans("WidgetDisabledAsModuleDisabled", $module).'
'; + } + + $widget[$j]['info'] = $text; + } + $j++; + } + + return $widget; + } } diff --git a/htdocs/langs/en_US/modulebuilder.lang b/htdocs/langs/en_US/modulebuilder.lang index 291cbd93837..193032ec900 100644 --- a/htdocs/langs/en_US/modulebuilder.lang +++ b/htdocs/langs/en_US/modulebuilder.lang @@ -183,3 +183,7 @@ DictionaryDeleted=Dictionary %s removed successfully PropertyModuleUpdated=Property %s has been update successfully InfoForApiFile=* When you generate file for the first time then all methods will be created for each object.
* When you click in remove you just remove all methods for the selected object. SetupFile=Page for module setup +EmailingSelectors=Emailings selectors +EmailingSelectorDesc=You can generate and edit here the class files to provide new email target selectors for the mass emailing module +EmailingSelectorFile=Emails selector file +NoEmailingSelector=No emails selector file \ No newline at end of file diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php index a51210c3b66..85c5f27a81a 100644 --- a/htdocs/modulebuilder/index.php +++ b/htdocs/modulebuilder/index.php @@ -3299,6 +3299,7 @@ if ($module == 'initmodule') { $countMenus = count($moduleobj->menu); $countTriggers = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/triggers"); $countWidgets = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/boxes"); + $countEmailingSelectors = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/core/emailings"); $countCss = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/css"); $countJs = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/js"); $countCLI = countItemsInDirectory(dol_buildpath($modulelowercase, 0)."/scripts"); @@ -3357,6 +3358,11 @@ if ($module == 'initmodule') { $head2[$h][2] = 'widgets'; $h++; + $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=emailings&module='.$module.($forceddirread ? '@'.$dirread : ''); + $head2[$h][1] = ($countEmailingSelectors <= 0 ? $langs->trans("EmailingSelectors") : $langs->trans("EmailingSelectors").''.$countEmailingSelectors.""); + $head2[$h][2] = 'emailings'; + $h++; + $head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=exportimport&module='.$module.($forceddirread ? '@'.$dirread : ''); $head2[$h][1] = $langs->trans("Export").'-'.$langs->trans("Import"); $head2[$h][2] = 'exportimport'; @@ -5937,6 +5943,58 @@ if ($module == 'initmodule') { } } + if ($tab == 'emailings') { + print ''."\n"; + require_once DOL_DOCUMENT_ROOT.'/core/modules/mailings/modules_mailings.php'; + + $emailingselectors = MailingTargets::getEmailingSelectorsList(array('/'.strtolower($module).'/core/mailings')); + + if ($action != 'editfile' || empty($file)) { + print ''.$langs->trans("EmailingSelectorDesc").'
'; + print '
'; + + print ''; + if (!empty($emailingselectors)) { + foreach ($emailingselectors as $emailingselector) { + $pathtofile = $emailingselector['relpath']; + + print ''; + print ''; + } + } else { + print ''; + } + print '
'.$langs->trans("EmailingSelectorFile").' : '.$pathtofile.''; + print ''.img_picto($langs->trans("Edit"), 'edit').''; + print ''.img_picto($langs->trans("Delete"), 'delete').'
'.$langs->trans("EmailingSelectorFile").' : '.$langs->trans("NoEmailingSelector").''; + print ''.img_picto('Generate', 'generate', 'class="paddingleft"').''; + print '
'; + } else { + $fullpathoffile = dol_buildpath($file, 0); + + $content = file_get_contents($fullpathoffile); + + // New module + print '
'; + print ''; + print ''; + print ''; + print ''; + print ''; + + $doleditor = new DolEditor('editfilecontent', $content, '', '300', 'Full', 'In', true, false, 'ace', 0, '99%'); + print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format', 'aZ09') ? GETPOST('format', 'aZ09') : 'html')); + print '
'; + print '
'; + print ''; + print '   '; + print ''; + print '
'; + + print '
'; + } + } + if ($tab == 'exportimport') { print ''."\n"; $pathtofile = $listofmodules[strtolower($module)]['moduledescriptorrelpath']; diff --git a/phpstan_action.neon b/phpstan_action.neon index 82ea3e4a0a0..1f1e6c6309f 100644 --- a/phpstan_action.neon +++ b/phpstan_action.neon @@ -1,7 +1,7 @@ parameters: bootstrapFiles: - build/phpstan/bootstrap_action.php - tmpDir: ./build/phpstan/tmp + tmpDir: ./github/tmp parallel: jobSize: 20 processTimeout: 600.0