diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php
index df99b6cdbbb..cbf8cbd37ba 100644
--- a/htdocs/core/class/html.formsetup.class.php
+++ b/htdocs/core/class/html.formsetup.class.php
@@ -30,6 +30,9 @@ class formSetup
/** @var formSetupItem[] */
public $params = array();
+ /**
+ * @var int
+ */
public $setupNotEmpty = 0;
/** @var Translate */
@@ -38,6 +41,9 @@ class formSetup
/** @var Form */
public $form;
+ /** @var int */
+ protected $maxItemRank;
+
/**
* Constructor
*
@@ -63,29 +69,81 @@ class formSetup
*/
public function generateOutput($editMode = false)
{
+ global $hookmanager, $action;
require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
- $out = '';
- if ($editMode) {
- $out .= '';
+ $parameters = array(
+ 'editMode' => $editMode
+ );
+ $reshook = $hookmanager->executeHooks('formSetupBeforeGenerateOutput', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
+ if ($reshook < 0) {
+ setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
}
- $out.= '
';
- $out.= '';
- $out.= '';
- $out.= ' | '.$this->langs->trans("Parameter").' | ';
- $out.= ' '.$this->langs->trans("Value").' | ';
- $out.= '
';
- $out.= '';
+ if ($reshook > 0) {
+ return $hookmanager->resPrint;
+ } else {
+ $out = '';
+ if ($editMode) {
+ $out .= '';
+ }
- $out.= '';
+ $out .= '';
+ $out .= '';
+ $out .= '';
+ $out .= ' | ' . $this->langs->trans("Parameter") . ' | ';
+ $out .= ' ' . $this->langs->trans("Value") . ' | ';
+ $out .= '
';
+ $out .= '';
+
+ // Sort items before render
+ $this->sortingItems();
+
+ $out .= '';
+ foreach ($this->params as $item) {
+ $out .= $this->generateLineOutput($item, $editMode);
+ }
+ $out .= '';
+
+ $out .= '
';
+ return $out;
+ }
+ }
+
+ /**
+ * @param bool $noMessageInUpdate display event message on errors and success
+ * @return void|null
+ */
+ public function saveConfFromPost($noMessageInUpdate = false)
+ {
+
+ if (empty($this->params)) {
+ return null;
+ }
+
+ $this->db->begin();
+ $error = 0;
foreach ($this->params as $item) {
- $out.= $this->generateLineOutput($item, $editMode);
+ $res = $item->setValueFromPost();
+ if ($res > 0) {
+ $item->saveConfValue();
+ } elseif ($res < 0) {
+ $error++;
+ break;
+ }
}
- $out.= '';
- $out.= '
';
- return $out;
+ if (!$error) {
+ $this->db->commit();
+ if (empty($noMessageInUpdate)) {
+ setEventMessages($this->langs->trans("SetupSaved"), null);
+ }
+ } else {
+ $this->db->rollback();
+ if (empty($noMessageInUpdate)) {
+ setEventMessages($this->langs->trans("SetupNotSaved"), null, 'errors');
+ }
+ }
}
/**
@@ -209,25 +267,133 @@ class formSetup
if (!array($this->params)) { return false; }
foreach ($this->params as $item) {
- $item->reloadConf();
+ $item->reloadValueFromConf();
}
return true;
}
-
/**
* Create a new item
+ * the tagret is useful with hooks : that allow externals modules to add setup items on good place
* @param $confKey the conf key used in database
+ * @param string $targetItemKey target item used to place the new item beside
+ * @param bool $insertAfterTarget insert before or after target item ?
* @return formSetupItem the new setup item created
*/
- public function newItem($confKey)
+ public function newItem($confKey, $targetItemKey = false, $insertAfterTarget = false)
{
$item = new formSetupItem($confKey);
+
+ // set item rank if not defined as last item
+ if (empty($item->rank)) {
+ $item->rank = $this->getCurentItemMaxRank() + 1;
+ $this->setItemMaxRank($item->rank); // set new max rank if needed
+ }
+
+ // try to get rank from target column, this will override item->rank
+ if (!empty($targetItemKey)) {
+ if (isset($this->params[$targetItemKey])) {
+ $targetItem = $this->params[$targetItemKey];
+ $item->rank = $targetItem->rank; // $targetItem->rank will be increase after
+ if ($targetItem->rank >= 0 && $insertAfterTarget) {
+ $item->rank++;
+ }
+ }
+
+ // calc new rank for each item to make place for new item
+ foreach ($this->params as $fItem) {
+ if ($item->rank <= $fItem->rank) {
+ $fItem->rank = $fItem->rank + 1;
+ $this->setItemMaxRank($fItem->rank); // set new max rank if needed
+ }
+ }
+ }
+
$this->params[$item->confKey] = $item;
return $this->params[$item->confKey];
}
+
+ /**
+ * Sort items according to rank
+ * @return bool
+ */
+ public function sortingItems()
+ {
+ // Sorting
+ return uasort($this->params, array($this, 'itemSort'));
+ }
+
+ /**
+ * @param bool $cache To use cache or not
+ * @return int
+ */
+ public function getCurentItemMaxRank($cache = true)
+ {
+ if (empty($this->params)) {
+ return 0;
+ }
+
+ if ($cache && $this->maxItemRank > 0) {
+ return $this->maxItemRank;
+ }
+
+ $this->maxItemRank = 0;
+ foreach ($this->params as $item) {
+ $this->maxItemRank = max($this->maxItemRank, $item->rank);
+ }
+
+ return $this->maxItemRank;
+ }
+
+
+ /**
+ * set new max rank if needed
+ * @param int $rank the item rank
+ * @return int|void
+ */
+ public function setItemMaxRank($rank)
+ {
+ $this->maxItemRank = max($this->maxItemRank, $rank);
+ }
+
+
+ /**
+ * get item position rank from item key
+ *
+ * @param string $itemKey the item key
+ * @return int rank on success and -1 on error
+ */
+ public function getLineRank($itemKey)
+ {
+ if (!isset($this->params[$itemKey]->rank)) {
+ return -1;
+ }
+ return $this->params[$itemKey]->rank;
+ }
+
+
+ /**
+ * uasort callback function to Sort params items
+ *
+ * @param formSetupItem $a formSetup item
+ * @param formSetupItem $b formSetup item
+ * @return int Return compare result
+ */
+ public function itemSort(formSetupItem $a, formSetupItem $b)
+ {
+ if (empty($a->rank)) {
+ $a->rank = 0;
+ }
+ if (empty($b->rank)) {
+ $b->rank = 0;
+ }
+ if ($a->rank == $b->rank) {
+ return 0;
+ }
+ return ($a->rank < $b->rank) ? -1 : 1;
+ }
}
/**
@@ -243,6 +409,9 @@ class formSetupItem
/** @var Translate */
public $langs;
+ /** @var int */
+ public $entity;
+
/** @var Form */
public $form;
@@ -267,6 +436,9 @@ class formSetupItem
/** @var bool|string set this var to override field output */
public $fieldOutputOverride = false;
+ /** @var int $rank */
+ public $rank = 0;
+
/**
* @var string $errors
*/
@@ -294,6 +466,7 @@ class formSetupItem
$this->db = $db;
$this->form = new Form($this->db);
$this->langs = $langs;
+ $this->entity = $conf->entity;
$this->confKey = $confKey;
$this->fieldValue = $conf->global->{$this->confKey};
@@ -303,12 +476,58 @@ class formSetupItem
* reload conf value from databases
* @return null
*/
- public function reloadConf()
+ public function reloadValueFromConf()
{
global $conf;
$this->fieldValue = $conf->global->{$this->confKey};
}
+
+ /**
+ * Save const value based on htdocs/core/actions_setmoduleoptions.inc.php
+ * @return int -1 if KO, 1 if OK
+ */
+ public function saveConfValue()
+ {
+ // Modify constant only if key was posted (avoid resetting key to the null value)
+ if ($this->type != 'title') {
+ $result = dolibarr_set_const($this->db, $this->confKey, $this->fieldValue, 'chaine', 0, '', $this->entity);
+ if ($result < 0) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ }
+
+
+ /**
+ * Save const value based on htdocs/core/actions_setmoduleoptions.inc.php
+ * @return int -1 if KO, 0 nothing to do , 1 if OK
+ */
+ public function setValueFromPost()
+ {
+ // Modify constant only if key was posted (avoid resetting key to the null value)
+ if ($this->type != 'title') {
+ if (preg_match('/category:/', $this->type)) {
+ if (GETPOST($this->confKey, 'int') == '-1') {
+ $val_const = '';
+ } else {
+ $val_const = GETPOST($this->confKey, 'int');
+ }
+ } else {
+ $val_const = GETPOST($this->confKey, 'alpha');
+ }
+
+ // TODO add value check with class validate
+ $this->fieldValue = $val_const;
+
+ return 1;
+ }
+
+ return 0;
+ }
+
/**
* Get help text or generate it
* @return int|string
@@ -596,6 +815,7 @@ class formSetupItem
return $out;
}
+
/*
* METHODS FOR SETTING DISPLAY TYPE
*/
diff --git a/htdocs/modulebuilder/template/admin/setup.php b/htdocs/modulebuilder/template/admin/setup.php
index 007e9d84b12..527ea8eb32d 100644
--- a/htdocs/modulebuilder/template/admin/setup.php
+++ b/htdocs/modulebuilder/template/admin/setup.php
@@ -60,6 +60,9 @@ require_once '../lib/mymodule.lib.php';
// Translations
$langs->loadLangs(array("admin", "mymodule@mymodule"));
+// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
+$hookmanager->initHooks(array('mymodulesetup', 'globalsetup'));
+
// Access control
if (!$user->admin) {
accessforbidden();
@@ -74,22 +77,10 @@ $label = GETPOST('label', 'alpha');
$scandir = GETPOST('scan_dir', 'alpha');
$type = 'myobject';
-$arrayofparameters = array(
- 'MYMODULE_MYPARAM1'=>array('type'=>'string', 'css'=>'minwidth500' ,'enabled'=>1),
- 'MYMODULE_MYPARAM2'=>array('type'=>'textarea','enabled'=>1),
- //'MYMODULE_MYPARAM3'=>array('type'=>'category:'.Categorie::TYPE_CUSTOMER, 'enabled'=>1),
- //'MYMODULE_MYPARAM4'=>array('type'=>'emailtemplate:thirdparty', 'enabled'=>1),
- //'MYMODULE_MYPARAM5'=>array('type'=>'yesno', 'enabled'=>1),
- //'MYMODULE_MYPARAM5'=>array('type'=>'thirdparty_type', 'enabled'=>1),
- //'MYMODULE_MYPARAM6'=>array('type'=>'securekey', 'enabled'=>1),
- //'MYMODULE_MYPARAM7'=>array('type'=>'product', 'enabled'=>1),
-);
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formsetup.class.php';
$formSetup = new formSetup($db);
-$formSetup->addItemsFromParamsArray($arrayofparameters);
-
// Hôte
$item = $formSetup->newItem('NO_PARAM_JUST_TEXT');
@@ -131,11 +122,10 @@ $dirmodels = array_merge(array('/'), (array) $conf->modules_parts['models']);
* Actions
*/
-if ((float) DOL_VERSION >= 6) {
- // TODO Add save setup by formSetup
- $arrayofparameters = $formSetup->exportItemsAsParamsArray();
- include DOL_DOCUMENT_ROOT.'/core/actions_setmoduleoptions.inc.php';
- $formSetup->reloadConfs();
+if ((float) DOL_VERSION >= 15) {
+ if ($action == 'update') {
+ $formSetup->saveConfFromPost();
+ }
}
if ($action == 'updateMask') {
@@ -275,8 +265,9 @@ if ($action == 'edit') {
print '';
print '
';
} else {
- if (!empty($arrayofparameters)) {
+ if (!empty($formSetup->params)) {
print $formSetup->generateOutput();
+ $setupnotempty++;
print '