Fix ai prompt function for extrafields to match step 2 todo (#34032)

* Fix ai prompt function to match step 2 todo

* add  doc comment

* fix CI
This commit is contained in:
Lucas Marcouiller 2025-05-04 10:50:01 +02:00 committed by GitHub
parent 58562f84a6
commit 0ea9108fdd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 149 additions and 37 deletions

View file

@ -238,7 +238,8 @@ if ($action == 'add') {
'1',
(GETPOST('totalizable', 'alpha') ? 1 : 0),
GETPOSTINT('printable'),
array('css' => $css, 'cssview' => $cssview, 'csslist' => $csslist)
array('css' => $css, 'cssview' => $cssview, 'csslist' => $csslist),
GETPOST("ai_prompt")
);
if ($result > 0) {
setEventMessages($langs->trans('SetupSaved'), null, 'mesgs');
@ -422,7 +423,8 @@ if ($action == 'update') {
GETPOST('enabled', 'nohtml'),
(GETPOST('totalizable', 'alpha') ? 1 : 0),
GETPOSTINT('printable'),
array('css' => $css, 'cssview' => $cssview, 'csslist' => $csslist)
array('css' => $css, 'cssview' => $cssview, 'csslist' => $csslist),
GETPOST("ai_prompt")
);
if ($result > 0) {
setEventMessages($langs->trans('SetupSaved'), null, 'mesgs');

View file

@ -47,7 +47,7 @@ class ExtraFields
public $db;
/**
* @var array<string,array{label:array<string,string>,type:array<string,string>,size:array<string,string>,default:array<string,string>,computed:array<string,string>,unique:array<string,int>,required:array<string,int>,param:array<string,mixed>,perms:array<string,mixed>,list:array<string,int|string>,pos:array<string,int>,totalizable:array<string,int>,help:array<string,string>,printable:array<string,int>,enabled:array<string,int>,langfile:array<string,string>,css:array<string,string>,csslist:array<string,string>,cssview:array<string,string>,hidden:array<string,int>,mandatoryfieldsofotherentities:array<string,string>,alwayseditable:array<string,int<0,1>>,loaded?:int,count:int}> New array to store extrafields definition Note: count set as present to avoid static analysis notices
* @var array<string,array{label:array<string,string>,type:array<string,string>,size:array<string,string>,default:array<string,string>,computed:array<string,string>,unique:array<string,int>,required:array<string,int>,param:array<string,mixed>,perms:array<string,mixed>,list:array<string,int|string>,pos:array<string,int>,totalizable:array<string,int>,help:array<string,string>,printable:array<string,int>,enabled:array<string,int>,langfile:array<string,string>,css:array<string,string>,csslist:array<string,string>,cssview:array<string,string>,hidden:array<string,int>,mandatoryfieldsofotherentities:array<string,string>,alwayseditable:array<string,int<0,1>>,loaded?:int,count:int,aiprompt:array<string,string>}> New array to store extrafields definition Note: count set as present to avoid static analysis notices
*/
public $attributes = array();
@ -141,9 +141,10 @@ class ExtraFields
* @param int<0,1> $totalizable Is a measure. Must show a total on lists
* @param int<0,1> $printable Is extrafield displayed on PDF
* @param array<string,mixed> $moreparams More parameters. Example: array('css'=>, 'csslist'=>Css on list, 'cssview'=>...)
* @param string $aiprompt Ai prompt value
* @return int Return integer <=0 if KO, >0 if OK
*/
public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
public function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique = 0, $required = 0, $default_value = '', $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array(), $aiprompt = "")
{
if (empty($attrname)) {
return -1;
@ -179,7 +180,7 @@ class ExtraFields
$err1 = $this->errno;
if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate') {
// Add declaration of field into table
$result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
$result2 = $this->create_label($attrname, $label, $type, $pos, $size, $elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $help, $default_value, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams, $aiprompt);
$err2 = $this->errno;
if ($result2 > 0
|| ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS')
@ -405,10 +406,11 @@ class ExtraFields
* @param int<0,1> $totalizable Is a measure. Must show a total on lists
* @param int<0,1> $printable Is extrafield displayed on PDF
* @param array<string,mixed> $moreparams More parameters. Example: array('css'=>, 'csslist'=>, 'cssview'=>...)
* @param string $aiprompt Ai prompt value
* @return int Return integer <=0 if KO, >0 if OK
* @throws Exception
*/
private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = '', $elementtype = '', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
private function create_label($attrname, $label = '', $type = '', $pos = 0, $size = '', $elementtype = '', $unique = 0, $required = 0, $param = '', $alwayseditable = 0, $perms = '', $list = '-1', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array(), $aiprompt = "")
{
// phpcs:enable
global $conf, $user;
@ -491,7 +493,8 @@ class ExtraFields
$sql .= " totalizable,";
$sql .= " css,";
$sql .= " csslist,";
$sql .= " cssview";
$sql .= " cssview,";
$sql .= " aiprompt";
$sql .= " )";
$sql .= " VALUES('".$this->db->escape($attrname)."',";
$sql .= " '".$this->db->escape($label)."',";
@ -518,7 +521,8 @@ class ExtraFields
$sql .= " ".($totalizable ? 'TRUE' : 'FALSE').",";
$sql .= " ".($css ? "'".$this->db->escape($css)."'" : "null").",";
$sql .= " ".($csslist ? "'".$this->db->escape($csslist)."'" : "null").",";
$sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null");
$sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null").",";
$sql .= " '".$this->db->escape($aiprompt)."'";
$sql .= ')';
if ($this->db->query($sql)) {
@ -663,10 +667,11 @@ class ExtraFields
* @param int<0,1> $totalizable Is extrafield totalizable on list
* @param int<0,1> $printable Is extrafield displayed on PDF
* @param array<string,mixed> $moreparams More parameters. Example: array('css'=>, 'csslist'=>, 'cssview'=>...)
* @param string $aiprompt Ai prompt value
* @return int >0 if OK, <=0 if KO
* @throws Exception
*/
public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = array(), $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
public function update($attrname, $label, $type, $length, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = array(), $alwayseditable = 0, $perms = '', $list = '', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array(), $aiprompt = "")
{
global $action, $hookmanager;
@ -765,7 +770,7 @@ class ExtraFields
if ($result > 0 || $type == 'separate') {
if ($label) {
dol_syslog(get_class($this).'::update_label', LOG_DEBUG);
$result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams);
$result = $this->update_label($attrname, $label, $type, $length, $elementtype, $unique, $required, $pos, $param, $alwayseditable, $perms, $list, $help, $default, $computed, $entity, $langfile, $enabled, $totalizable, $printable, $moreparams, $aiprompt);
}
if ($result > 0) {
$sql = '';
@ -822,14 +827,15 @@ class ExtraFields
* @param int<0,1> $totalizable Is extrafield totalizable on list
* @param int<0,1> $printable Is extrafield displayed on PDF
* @param array<string,mixed> $moreparams More parameters. Example: array('css'=>, 'csslist'=>, 'cssview'=>...)
* @param string $aiprompt Ai prompt value
* @return int Return integer <=0 if KO, >0 if OK
* @throws Exception
*/
private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = array(), $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array())
private function update_label($attrname, $label, $type, $size, $elementtype, $unique = 0, $required = 0, $pos = 0, $param = array(), $alwayseditable = 0, $perms = '', $list = '0', $help = '', $default = '', $computed = '', $entity = '', $langfile = '', $enabled = '1', $totalizable = 0, $printable = 0, $moreparams = array(), $aiprompt = "")
{
// phpcs:enable
global $conf, $user;
dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$printable);
dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$default.", ".$computed.", ".$entity.", ".$langfile.", ".$enabled.", ".$totalizable.", ".$printable.", ".$aiprompt);
// Clean parameters
if ($elementtype == 'thirdparty') {
@ -925,7 +931,8 @@ class ExtraFields
$sql .= " help,";
$sql .= " css,";
$sql .= " csslist,";
$sql .= " cssview";
$sql .= " cssview,";
$sql .= " aiprompt";
$sql .= ") VALUES (";
$sql .= "'".$this->db->escape($attrname)."',";
$sql .= " ".($entity === '' ? $conf->entity : $entity).",";
@ -952,7 +959,8 @@ class ExtraFields
$sql .= " ".($help ? "'".$this->db->escape($help)."'" : "null").",";
$sql .= " ".($css ? "'".$this->db->escape($css)."'" : "null").",";
$sql .= " ".($csslist ? "'".$this->db->escape($csslist)."'" : "null").",";
$sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null");
$sql .= " ".($cssview ? "'".$this->db->escape($cssview)."'" : "null").",";
$sql .= " '".$this->db->escape($aiprompt)."'";
$sql .= ")";
$resql2 = $this->db->query($sql);
@ -1006,7 +1014,7 @@ class ExtraFields
$array_name_label = array();
// We should not have several time this request. If we have, there is some optimization to do by calling a simple $extrafields->fetch_optionals() in top of code and not into subcode
$sql = "SELECT rowid, name, label, type, size, elementtype, fieldunique, fieldrequired, param, pos, alwayseditable, perms, langs, list, printable, totalizable, fielddefault, fieldcomputed, entity, enabled, help,";
$sql = "SELECT rowid, name, label, type, size, elementtype, fieldunique, fieldrequired, param, pos, alwayseditable, perms, langs, list, printable, totalizable, fielddefault, fieldcomputed, entity, enabled, help, aiprompt,";
$sql .= " css, cssview, csslist";
$sql .= " FROM ".$this->db->prefix()."extrafields";
//$sql.= " WHERE entity IN (0,".$conf->entity.")"; // Filter is done later
@ -1056,6 +1064,7 @@ class ExtraFields
$this->attributes[$tab->elementtype]['entityid'][$tab->name] = $tab->entity;
$this->attributes[$tab->elementtype]['enabled'][$tab->name] = $tab->enabled;
$this->attributes[$tab->elementtype]['help'][$tab->name] = $tab->help;
$this->attributes[$tab->elementtype]['aiprompt'][$tab->name] = $tab->aiprompt;
$this->attributes[$tab->elementtype]['css'][$tab->name] = $tab->css;
$this->attributes[$tab->elementtype]['cssview'][$tab->name] = $tab->cssview;
$this->attributes[$tab->elementtype]['csslist'][$tab->name] = $tab->csslist;

View file

@ -97,9 +97,10 @@ class FormAI extends Form
* @param string $format Format for output ('', 'html', ...)
* @param string $htmlContent HTML name of WYSIWYG field
* @param string $onlyenhancements Show only this enhancement features (show all if '')
* @param string $aiprompt Ai prompt for textgenerationextrafield function
* @return string HTML code to ask AI instructions and autofill result
*/
public function getSectionForAIEnhancement($function = 'textgeneration', $format = '', $htmlContent = 'message', $onlyenhancements = '')
public function getSectionForAIEnhancement($function = 'textgeneration', $format = '', $htmlContent = 'message', $onlyenhancements = '', $aiprompt = "")
{
global $langs, $form;
require_once DOL_DOCUMENT_ROOT."/ai/lib/ai.lib.php";
@ -153,9 +154,7 @@ class FormAI extends Form
if (in_array($onlyenhancements, array('textgenerationextrafield'))) {
$out .= '<div id="ai_textgenerationextrafield'.$htmlContent.'" class="ai_textgenerationextrafield'.$htmlContent.' paddingtop paddingbottom ai_feature">';
//$out .= '<span>'.$langs->trans("FillMessageWithAIContent").'</span>';
$out .= '<textarea class="centpercent textarea-ai_feature" data-functionai="extrafieldfiller" id="ai_instructions'.$htmlContent.'" name="instruction" placeholder="'.$langs->trans("EnterYourAIPromptHere").'..." /></textarea>';
$out .= '<input id="generate_button'.$htmlContent.'" type="button" class="button smallpaddingimp" disabled data-functionai="'.$function.'" value="'.$langs->trans('Generate').'"/>';
$out .= '<input id="input_ai_textgenerationextrafield'.$htmlContent.'" type="hidden" class="button smallpaddingimp" data-functionai="textgenerationextrafield" value="'.$aiprompt.'"/>';
$out .= '</div>';
}
@ -220,6 +219,14 @@ class FormAI extends Form
prepareCallAIGenerator($(this));
}
});
$('#linkforaiprompt".$function."').on('click', function() {
//Get value aiprompt + prepare ai generator
elementforprompt = $('#input_ai_textgenerationextrafield".$htmlContent."');
aiprompt = elementforprompt.val();
if (aiprompt != null && aiprompt != '' && aiprompt != '-1'){
prepareCallAIGenerator(elementforprompt);
}
});
function prepareCallAIGenerator(element) {
console.log('We prepare ajax call to AI to url /ai/ajax/generate_content.php function=".dol_escape_js($function)." format=".dol_escape_js($format)."');
@ -284,6 +291,8 @@ class FormAI extends Form
} else if (functionai == 'textrephraser') {
style = $('#ai_rephraser'+htmlname+'_select').val();
instructions = 'Rephrase the following text in a '+style+' style: ' + texttomodify;
} else if (functionai == 'textgenerationextrafield'){
instructions = $(element).val();
} else {
instructions = userprompt;
}

View file

@ -59,6 +59,7 @@ $listofexamplesforlink = 'Societe:societe/class/societe.class.php<br>Contact:con
console.log("select a new type (add) = "+type);
var size = jQuery("#size");
var computed_value = jQuery("#computed_value");
var ai_prompt = jQuery("#ai_prompt");
var langfile = jQuery("#langfile");
var default_value = jQuery("#default_value");
var unique = jQuery("#unique");
@ -98,6 +99,13 @@ $listofexamplesforlink = 'Societe:societe/class/societe.class.php<br>Contact:con
jQuery("tr.extra_default_value, tr.extra_unique, tr.extra_required, tr.extra_alwayseditable, tr.extra_list").show();
}
// Case of ai prompt
if (type == 'text' || type == 'varchar' || type == 'int' || type == 'double' || type == 'price' || type == 'html') {
jQuery("tr.extra_ai_prompt").show();
} else {
jQuery(ai_prompt).val(''); jQuery("tr.extra_ai_prompt").hide();
}
if (type == 'date') { size.val('').prop('disabled', true); unique.removeAttr('disabled'); jQuery("#value_choice").hide();jQuery("#helpchkbxlst").hide(); }
else if (type == 'datetime') { size.val('').prop('disabled', true); unique.removeAttr('disabled'); jQuery("#value_choice").hide(); jQuery("#helpchkbxlst").hide();}
else if (type == 'double') { size.val('24,8').removeAttr('disabled'); unique.removeAttr('disabled'); jQuery("#value_choice").hide(); jQuery("#helpchkbxlst").hide();}
@ -218,6 +226,34 @@ print $formadmin->selectTypeOfFields('type', GETPOST('type', 'alpha'));
<?php } ?>
<td class="valeur"><textarea name="computed_value" id="computed_value" class="quatrevingtpercent" rows="<?php echo ROWS_4 ?>"><?php echo(GETPOSTISSET('computed_value') ? GETPOST('computed_value', 'restricthtml') : ''); ?></textarea></td>
</tr>
<!-- AI Prompt -->
<tr class="extra_ai_prompt">
<td><?php
if ($elementtype == "projet") {
$elementtype = "project";
}
$elementprop = getElementProperties($elementtype);
$object = fetchObjectByElement(0, $elementtype);
if ($elementprop["module"] == "adherent") {
$elementprop["module"] = "member";
}
if ($elementprop["module"] == "projet") {
$elementprop["module"] = "project";
}
if ($elementprop["module"] == "contrat") {
$elementprop["module"] = "contract";
$object->element = "contract";
}
if ($elementprop["module"] == "ficheinter") {
$elementprop["module"] = "intervention";
}
$substitutionarray = getCommonSubstitutionArray($langs, 1, null, $object, array("object", $elementprop["module"]));
$texthelp = $langs->trans("FollowingConstantsWillBeSubstituted").'<br>';
foreach ($substitutionarray as $key => $val) {
$texthelp .= $key.' -> '.$val.'<br>';
}
echo $form->textwithpicto($langs->trans("AIPromptExtrafield"), $texthelp, 1, 'help', 'valignmiddle', 0, 3, 'abc');?></td>
<td class="valeur"><textarea name="ai_prompt" id="ai_prompt" class="quatrevingtpercent" rows="<?php echo ROWS_4 ?>"><?php echo(GETPOSTISSET('ai_prompt') ? GETPOST('ai_prompt', 'restricthtml') : ''); ?></textarea></td></tr>
<!-- Default Value (at sql setup level) -->
<tr class="extra_default_value"><td><?php echo $langs->trans("DefaultValue").' ('.$langs->trans("Database").')'; ?></td><td class="valeur"><input id="default_value" type="text" name="default_value" class="minwidth200" value="<?php echo(GETPOST('default_value', 'alpha') ? GETPOST('default_value', 'alpha') : ''); ?>"></td></tr>
<!-- Unique -->

View file

@ -99,6 +99,13 @@ $listofexamplesforlink = 'Societe:societe/class/societe.class.php<br>Contact:con
jQuery("tr.extra_default_value, tr.extra_unique, tr.extra_required, tr.extra_alwayseditable, tr.extra_list").show();
}
// Case of ai prompt
if (type == 'text' || type == 'varchar' || type == 'int' || type == 'double' || type == 'price' || type == 'html') {
jQuery("tr.extra_ai_prompt").show();
} else {
jQuery(ai_prompt).val(''); jQuery("tr.extra_ai_prompt").hide();
}
if (type == 'date') { size.val('').prop('disabled', true); unique.removeAttr('disabled'); jQuery("#value_choice").hide();jQuery("#helpchkbxlst").hide(); }
else if (type == 'datetime') { size.val('').prop('disabled', true); unique.removeAttr('disabled'); jQuery("#value_choice").hide(); jQuery("#helpchkbxlst").hide();}
else if (type == 'double') { size.removeAttr('disabled'); unique.removeAttr('disabled'); jQuery("#value_choice").hide(); jQuery("#helpchkbxlst").hide();}
@ -168,6 +175,7 @@ $label = $extrafields->attributes[$elementtype]['label'][$attrname];
$type = $extrafields->attributes[$elementtype]['type'][$attrname];
$size = $extrafields->attributes[$elementtype]['size'][$attrname];
$computed = $extrafields->attributes[$elementtype]['computed'][$attrname];
$aiprompt = $extrafields->attributes[$elementtype]['aiprompt'][$attrname];
$default = $extrafields->attributes[$elementtype]['default'][$attrname];
$unique = $extrafields->attributes[$elementtype]['unique'][$attrname];
$required = $extrafields->attributes[$elementtype]['required'][$attrname];
@ -284,6 +292,35 @@ if (in_array($type, array_keys($typewecanchangeinto))) {
<td class="valeur"><textarea name="computed_value" id="computed_value" class="quatrevingtpercent" rows="<?php echo ROWS_4 ?>"><?php echo dol_htmlcleanlastbr($computed); ?></textarea></td>
</tr>
<!-- AI Prompt -->
<tr class="extra_ai_prompt">
<td><?php
if ($elementtype == "projet") {
$elementtype = "project";
}
$elementprop = getElementProperties($elementtype);
$object = fetchObjectByElement(0, $elementtype);
if ($elementprop["module"] == "adherent") {
$elementprop["module"] = "member";
}
if ($elementprop["module"] == "projet") {
$elementprop["module"] = "project";
}
if ($elementprop["module"] == "contrat") {
$elementprop["module"] = "contract";
$object->element = "contract";
}
if ($elementprop["module"] == "ficheinter") {
$elementprop["module"] = "intervention";
}
$substitutionarray = getCommonSubstitutionArray($langs, 1, null, $object, array("object", $elementprop["module"]));
$texthelp = $langs->trans("FollowingConstantsWillBeSubstituted").'<br>';
foreach ($substitutionarray as $key => $val) {
$texthelp .= $key.' -> '.$val.'<br>';
}
echo $form->textwithpicto($langs->trans("AIPromptExtrafield"), $texthelp, 1, 'help', 'valignmiddle', 0, 3, 'abc');?></td>
<td class="valeur"><textarea name="ai_prompt" id="ai_prompt" class="quatrevingtpercent" rows="<?php echo ROWS_4 ?>"><?php echo($aiprompt); ?></textarea></td></tr>
<!-- Default Value (at sql setup level) -->
<tr class="extra_default_value"><td><?php echo $langs->trans("DefaultValue").' ('.$langs->trans("Database").')'; ?></td><td class="valeur"><input id="default_value" type="text" name="default_value" class="minwidth200" value="<?php echo dol_escape_htmltag($default); ?>"></td></tr>

View file

@ -231,23 +231,21 @@ if (empty($reshook) && !empty($object->table_element) && isset($extrafields->att
print '<td class="right"><a class="reposition editfielda" href="'.$_SERVER['PHP_SELF'].'?'.$fieldid.'='.$valueid.'&action=edit_extras&token='.newToken().'&attribute='.$tmpkeyextra.'&ignorecollapsesetup=1">'.img_edit().'</a></td>';
}
if (isModEnabled("ai") && $action == 'edit_extras' && GETPOST('attribute') == $tmpkeyextra && !empty($extrafields->attributes[$object->table_element]["type"][$tmpkeyextra])) {
if (in_array($extrafields->attributes[$object->table_element]["type"][$tmpkeyextra], array("varchar", "text", "html", "int", 'double', 'price'))) {
$showlinktoai = "extrafieldfiller"; // 'textgenerationemail', 'textgenerationwebpage', 'imagegeneration', ...
$showlinktoailabel = $langs->trans("FillExtrafieldWithAi");
$htmlname = "options_".$tmpkeyextra;
$onlyenhancements = "textgenerationextrafield";
$morecss = "editfielda";
$out = "";
if (isModEnabled("ai") && $action == 'edit_extras' && GETPOST('attribute') == $tmpkeyextra && !empty($extrafields->attributes[$object->table_element]["aiprompt"][$tmpkeyextra])) {
$showlinktoai = "extrafieldfiller";
$showlinktoailabel = $langs->trans("FillExtrafieldWithAi");
$htmlname = "options_".$tmpkeyextra;
$onlyenhancements = "textgenerationextrafield";
$morecss = "editfielda";
$aiprompt = $extrafields->attributes[$object->table_element]["aiprompt"][$tmpkeyextra];
$out = "";
// Fill $out
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
print '<td class="right">';
print '<!-- TODO Step 2 Have code that will make the AI call and update input field without the popup-->';
print '<!-- TODO Step 3 Then a next step will be to use the ajax call core/aja/updateextrafield.php to update field in database directly with no need to pass by edit_extras step -->';
print $out;
print '</td>';
}
// Fill $out
include DOL_DOCUMENT_ROOT.'/core/tpl/formlayoutai.tpl.php';
print '<td class="right">';
print '<!-- TODO Step 3 Then a next step will be to use the ajax call core/aja/updateextrafield.php to update field in database directly with no need to pass by edit_extras step -->';
print $out;
print '</td>';
}
print '</tr></table>';
print '</td>';

View file

@ -20,6 +20,8 @@
/**
* @var Conf $conf
* @var DoliDB $db
* @var CommonObject $object
* @var Translate $langs
* @var ?FormMail $formmail
* @var ?FormWebsite $formwebsite
* @var ?FormAI $formai
@ -30,6 +32,7 @@
* @var string $showlinktoailabel '...'
* @var string $htmlname
* @var ?string $out
* @var ?string $aiprompt
*/
//Protection to avoid direct call of template
@ -38,6 +41,15 @@ if (empty($conf) || !is_object($conf)) {
exit(1);
}
if (empty($langs)) {
print 'Parameter langs not defined.';
exit(1);
}
if (empty($object)) {
print 'Parameter object not defined.';
exit(1);
}
if (empty($htmlname)) {
print 'Parameter htmlname not defined.';
exit(1);
@ -57,6 +69,7 @@ if (empty($htmlname)) {
@phan-var-force string $showlinktoailabel
@phan-var-force ?string $out
@phan-var-force ?string $morecss
@phan-var-force string $aiprompt
';
if (!isset($out)) { // Init to empty string if not defined
@ -65,7 +78,9 @@ if (!isset($out)) { // Init to empty string if not defined
if (!isset($morecss)) { // Init to empty string if not defined
$morecss = '';
}
if (!isset($aiprompt)) { // Init to empty string if not defined
$aiprompt = '';
}
// Add link to add layout
if ($showlinktolayout) { // May be set only if MAIN_EMAIL_USE_LAYOUT is set
$out .= '<a href="#" id="linkforlayouttemplates" class="notasortlink inline-block alink marginrightonly">';
@ -148,7 +163,11 @@ if ($showlinktoai) {
if (empty($onlyenhancements)) {
$onlyenhancements = '';
}
$out .= $formai->getSectionForAIEnhancement($showlinktoai, $formmail->withaiprompt, $htmlname, $onlyenhancements);
if (!empty($aiprompt)) {
$formai->setSubstitFromObject($object, $langs);
$aiprompt = make_substitutions($aiprompt, $formai->substit);
}
$out .= $formai->getSectionForAIEnhancement($showlinktoai, $formmail->withaiprompt, $htmlname, $onlyenhancements, $aiprompt);
} else {
$out .= '<!-- No link to the AI feature, $formmail->withaiprompt must be set to the ai feature and module ai must be enabled -->';
}

View file

@ -193,3 +193,5 @@ PageLinkedByAMenuEntry=Page linked by at least one menu entry
FieldsEdit=Fields edit
FieldsInsert=Fields insert
FieldsView=Fields view
AIPromptExtrafield=AI Prompt
AIPromptExtrafieldDesc=The constants used in this field will be replaced with the corresponding value.