Merge branch 'develop' of https://github.com/Dolibarr/dolibarr.git into develop_ldap

This commit is contained in:
Regis Houssin 2017-09-24 16:10:55 +02:00
commit 06ee9f4775
30 changed files with 1023 additions and 370 deletions

View File

@ -64,4 +64,5 @@ try {
if ($trace[0]['args'][0] == 404) die('Bad ID');
else if ($trace[0]['args'][0] == 401) die('Bad auth key');
else die('Can not access to '.$conf->global->MAIN_MODULE_DOLISTORE_API_SRV);
}
}

View File

@ -230,14 +230,14 @@ if ($action == 'edit') // Edit
print '</tr>';
// Default language
print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>';
print '<tr><td class="titlefield">'.$langs->trans("DefaultLanguage").'</td><td>';
print $formadmin->select_language($conf->global->MAIN_LANG_DEFAULT, 'MAIN_LANG_DEFAULT', 1, 0, 0, 0, 0, 'minwidth300');
print '</td>';
print '<td width="20">&nbsp;</td>';
print '</tr>';
// Multilingual GUI
print '<tr class="oddeven"><td class="titlefield">'.$langs->trans("EnableMultilangInterface").'</td><td>';
print '<tr><td class="titlefield">'.$langs->trans("EnableMultilangInterface").'</td><td>';
print $form->selectyesno('MAIN_MULTILANGS',$conf->global->MAIN_MULTILANGS,1);
print '</td>';
print '<td width="20">&nbsp;</td>';
@ -349,9 +349,8 @@ if ($action == 'edit') // Edit
print '</tr>';
// Message of the day on home page
$substitutionarray=getCommonSubstitutionArray($langs, 0, array('object'));
$substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount'));
complete_substitutions_array($substitutionarray, $langs);
$substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey');
print '<tr><td class="titlefield">';
$texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'<br>';
@ -359,7 +358,7 @@ if ($action == 'edit') // Edit
{
$texthelp.=$key.'<br>';
}
print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, '');
print $form->textwithpicto($langs->trans("MessageOfDay"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessageofday');
print '</td><td colspan="2">';
@ -379,16 +378,15 @@ if ($action == 'edit') // Edit
print '</tr>';
// Message on login page
$substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','user'));
$substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount','user'));
complete_substitutions_array($substitutionarray, $langs);
$substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey');
print '<tr><td>';
$texthelp=$langs->trans("FollowingConstantsWillBeSubstituted").'<br>';
foreach($substitutionarray as $key => $val)
{
$texthelp.=$key.'<br>';
}
print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, '');
print $form->textwithpicto($langs->trans("MessageLogin"), $texthelp, 1, 'help', '', 0, 2, 'tooltipmessagelogin');
print '</td><td colspan="2">';
$doleditor = new DolEditor('main_home', (isset($conf->global->MAIN_HOME)?$conf->global->MAIN_HOME:''), '', 142, 'dolibarr_notes', 'In', false, true, true, ROWS_4, '90%');
$doleditor->Create();

View File

@ -77,6 +77,8 @@ if ($action == 'setproductionmode')
}
}
dol_mkdir(DOL_DATA_ROOT.'/api/temp'); // May have been deleted by a purge
/*
* View

View File

@ -743,7 +743,7 @@ if ($resql)
// Title
$bankcateg=new BankCateg($db);
$morehtml='<div data-role="fieldcontain">';
$morehtml='<div>';
$morehtml.= '<label for="pageplusone">'.$langs->trans("Page")."</label> "; // ' Page ';
$morehtml.='<input type="text" name="pageplusone" id="pageplusone" size="1" class="flat" value="'.($page+1).'">';
$morehtml.='/'.$nbtotalofpages.' ';

View File

@ -2550,8 +2550,8 @@ if ($action == 'create')
print $desc;
print '<div id="credit_note_options" class="clearboth">';
print '&nbsp;&nbsp;&nbsp; <input data-role="none" type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
print '<br>&nbsp;&nbsp;&nbsp; <input data-role="none" type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
print '</div>';
print '</div></div>';

View File

@ -32,7 +32,7 @@ if ($action == 'setnote_public' && ! empty($permissionnote) && ! GETPOST('cancel
{
if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before');
if (empty($object->id)) $object->fetch($id); // Fetch may not be already done
$result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public');
$result=$object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES),'_public');
if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
}
// Set public note
@ -40,6 +40,6 @@ else if ($action == 'setnote_private' && ! empty($permissionnote) && ! GETPOST('
{
if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before');
if (empty($object->id)) $object->fetch($id); // Fetch may not be already done
$result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private');
$result=$object->update_note(dol_html_entity_decode(GETPOST('note_private', 'none'), ENT_QUOTES),'_private');
if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
}

View File

@ -435,7 +435,7 @@ class box_activity extends ModeleBoxes
}
// Add the sum in the bottom of the boxes
$this->info_box_contents[$line][0] = array('tr' => 'class="liste_total"');
$this->info_box_contents[$line][0] = array('tr' => 'class="liste_total_wrap"');
$this->info_box_contents[$line][1] = array('td' => 'align="left" class="liste_total" ', 'text' => $langs->trans("Total")."&nbsp;".$textHead);
$this->info_box_contents[$line][2] = array('td' => 'align="right" class="liste_total" ', 'text' => $totalnb);
$this->info_box_contents[$line][3] = array('td' => 'align="right" class="liste_total" ', 'text' => '');

View File

@ -286,7 +286,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty"
if (isset($contents[$i]))
{
// TR
if (isset($contents[$i][0]['tr'])) $out.= '<tr class="tdtop" '.$contents[$i][0]['tr'].'>';
if (isset($contents[$i][0]['tr'])) $out.= '<tr '.$contents[$i][0]['tr'].'>';
else $out.= '<tr class="oddeven">';
// Loop on each TD

View File

@ -544,7 +544,7 @@ class Form
$disabled=0;
$ret='<div class="centpercent center">';
$ret.='<select data-role="none" class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>';
$ret.='<select class="flat'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionselect" name="massaction"'.($disabled?' disabled="disabled"':'').'>';
// Complete list with data from external modules. THe module can use $_SERVER['PHP_SELF'] to know on which page we are, or use the $parameters['currentcontext'] completed by executeHooks.
$parameters=array();
@ -561,7 +561,7 @@ class Form
$ret.='</select>';
// Warning: if you set submit button to disabled, post using 'Enter' will no more work.
$ret.='<input type="submit" data-role="none" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">';
$ret.='<input type="submit" name="confirmmassaction" class="button'.(empty($conf->use_javascript_ajax)?'':' hideobject').' massaction massactionconfirmed" value="'.dol_escape_htmltag($langs->trans("Confirm")).'">';
$ret.='</div>';
if (! empty($conf->use_javascript_ajax))
@ -5551,8 +5551,8 @@ class Form
{
$nbofdifferenttypes = count($object->linkedObjects);
print '<br><!-- showLinkedObjectBlock -->';
print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '');
print '<!-- showLinkedObjectBlock -->';
print load_fiche_titre($langs->trans('RelatedObjects'), $morehtmlright, '', 0, 0, 'showlinkedobjectblock');
print '<div class="div-table-responsive-no-min">';

View File

@ -187,20 +187,22 @@ class FormActions
elseif ($typeelement == 'project') $title=$langs->trans('LatestLinkedEvents', $max?$max:'');
elseif ($typeelement == 'task') $title=$langs->trans('LatestLinkedEvents', $max?$max:'');
elseif ($typeelement == 'member') $title=$langs->trans('LatestLinkedEvents', $max?$max:'');
else $title=$langs->trans("Actions");
else $title=$langs->trans("LatestLinkedEvents", $max?$max:'');
$urlbacktopage=$_SERVER['PHP_SELF'].'?id='.$object->id.($moreparambacktopage?'&'.$moreparambacktopage:'');
$buttontoaddnewevent = '<a href="'.DOL_URL_ROOT.'/comm/action/card.php?action=create&datep='.dol_print_date(dol_now(),'dayhourlog').'&origin='.$typeelement.'&originid='.$object->id.'&socid='.$object->socid.'&projectid='.$object->fk_project.'&backtopage='.urlencode($urlbacktopage).'">';
$buttontoaddnewevent.= $langs->trans("AddEvent");
$buttontoaddnewevent.= '</a>';
print '<!-- formactions->showactions -->'."\n";
print load_fiche_titre($title, $buttontoaddnewevent, '');
$page=0; $param='';
$total = 0;
print '<div class="div-table-responsive">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder'.($morecss?' '.$morecss:'').'" width="100%">';
print '<tr class="liste_titre">';
print getTitleFieldOfList('Ref', 0, $_SERVER["PHP_SELF"], '', $page, $param, '', $sortfield, $sortorder, '', 1);
@ -214,63 +216,70 @@ class FormActions
$userstatic = new User($this->db);
$cursorevent = 0;
foreach($listofactions as $action)
if (count($listofactions))
{
if ($max && $cursorevent >= $max) break;
$cursorevent = 0;
foreach($listofactions as $action)
{
if ($max && $cursorevent >= $max) break;
$ref=$action->getNomUrl(1,-1);
$label=$action->getNomUrl(0,38);
$ref=$action->getNomUrl(1,-1);
$label=$action->getNomUrl(0,38);
print '<tr class="oddeven">';
print '<td>'.$ref.'</td>';
print '<td>'.$label.'</td>';
print '<td>';
if (! empty($conf->global->AGENDA_USE_EVENT_TYPE))
{
if ($action->type_picto) print img_picto('', $action->type_picto);
else {
if ($action->type_code == 'AC_RDV') print img_picto('', 'object_group').' ';
if ($action->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' ';
if ($action->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' ';
if ($action->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' ';
}
}
print $action->type;
print '</td>';
print '<td align="center">'.dol_print_date($action->datep,'dayhour');
if ($action->datef)
{
$tmpa=dol_getdate($action->datep);
$tmpb=dol_getdate($action->datef);
if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year'])
print '<tr class="oddeven">';
print '<td>'.$ref.'</td>';
print '<td>'.$label.'</td>';
print '<td>';
if (! empty($conf->global->AGENDA_USE_EVENT_TYPE))
{
if ($tmpa['hours'] != $tmpb['hours'] || $tmpa['minutes'] != $tmpb['minutes'] && $tmpa['seconds'] != $tmpb['seconds']) print '-'.dol_print_date($action->datef,'hour');
if ($action->type_picto) print img_picto('', $action->type_picto);
else {
if ($action->type_code == 'AC_RDV') print img_picto('', 'object_group').' ';
if ($action->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' ';
if ($action->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' ';
if ($action->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' ';
}
}
else print '-'.dol_print_date($action->datef,'dayhour');
}
print '</td>';
print '<td>';
if (! empty($action->userownerid))
{
$userstatic->fetch($action->userownerid); // TODO Introduce a cache on users fetched
print $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, '', '');
}
print '</td>';
print '<td align="right">';
if (! empty($action->author->id))
{
print $action->getLibStatut(3);
}
print '</td>';
print '</tr>';
print $action->type;
print '</td>';
print '<td align="center">'.dol_print_date($action->datep,'dayhour');
if ($action->datef)
{
$tmpa=dol_getdate($action->datep);
$tmpb=dol_getdate($action->datef);
if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year'])
{
if ($tmpa['hours'] != $tmpb['hours'] || $tmpa['minutes'] != $tmpb['minutes'] && $tmpa['seconds'] != $tmpb['seconds']) print '-'.dol_print_date($action->datef,'hour');
}
else print '-'.dol_print_date($action->datef,'dayhour');
}
print '</td>';
print '<td>';
if (! empty($action->userownerid))
{
$userstatic->fetch($action->userownerid); // TODO Introduce a cache on users fetched
print $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, '', '');
}
print '</td>';
print '<td align="right">';
if (! empty($action->author->id))
{
print $action->getLibStatut(3);
}
print '</td>';
print '</tr>';
$cursorevent++;
$cursorevent++;
}
}
else
{
print '<tr class="oddeven"><td colspan="6" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
if ($max && $num > $max)
{
print '<tr class="oddeven"><td colspan="6">'.$langs->trans("More").'...</td></tr>';
print '<tr class="oddeven"><td colspan="6" class="opacitymedium">'.$langs->trans("More").'...</td></tr>';
}
print '</table>';

View File

@ -599,11 +599,12 @@ function dol_include_once($relpath, $classname='')
/**
* Return path of url or filesystem. Return alternate root if exists.
*
* @param string $path Relative path to file (if mode=0) or relative url (if mode=1). Ie: mydir/myfile, ../myfile
* @param int $type 0=Used for a Filesystem path, 1=Used for an URL path (output relative), 2=Used for an URL path (output full path using same host that current url), 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file)
* @return string Full filesystem path (if mode=0), Full url path (if mode=1)
* @param string $path Relative path to file (if mode=0) or relative url (if mode=1). Ie: mydir/myfile, ../myfile
* @param int $type 0=Used for a Filesystem path, 1=Used for an URL path (output relative), 2=Used for an URL path (output full path using same host that current url), 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file)
* @param int $returnemptyifnotfound If path==0 and if file was not found, do not return default path but an empty string
* @return string Full filesystem path (if path=0), Full url path (if mode=1)
*/
function dol_buildpath($path, $type=0)
function dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
{
global $conf;
@ -611,16 +612,20 @@ function dol_buildpath($path, $type=0)
if (empty($type)) // For a filesystem path
{
$res = DOL_DOCUMENT_ROOT.'/'.$path; // Standard value
$res = DOL_DOCUMENT_ROOT.'/'.$path; // Standard default path
foreach ($conf->file->dol_document_root as $key => $dirroot) // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...)
{
if ($key == 'main') continue;
if (file_exists($dirroot.'/'.$path))
{
$res=$dirroot.'/'.$path;
break;
return $res;
}
}
if ($returnemptyifnotfound) // Not found, we return empty string
{
return '';
}
}
else // For an url path
{
@ -1011,11 +1016,12 @@ function dol_syslog($message, $level = LOG_INFO, $ident = 0, $suffixinfilename='
* @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required.
* @param string $picto Add a picto on tab title
* @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
* @param string $morehtmlright Add more html content on right of tabs title
* @return void
*/
function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0)
function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='')
{
print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath);
print dol_get_fiche_head($links, $active, $title, $notab, $picto, $pictoisfullpath, $morehtmlright);
}
/**
@ -1027,14 +1033,17 @@ function dol_fiche_head($links=array(), $active='0', $title='', $notab=0, $picto
* @param int $notab -1 or 0=Add tab header, 1=no tab header. If you set this to 1, using dol_fiche_end() to close tab is not required.
* @param string $picto Add a picto on tab title
* @param int $pictoisfullpath If 1, image path is a full path. If you set this to 1, you can use url returned by dol_buildpath('/mymodyle/img/myimg.png',1) for $picto.
* @param string $morehtmlright Add more html content on right of tabs title
* @return string
*/
function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0)
function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='')
{
global $conf, $langs, $hookmanager;
$out="\n".'<div class="tabs" data-role="controlgroup" data-type="horizontal">'."\n";
if ($morehtmlright) $out.='<div class="inline-block floatright tabsElem">'.$morehtmlright.'</div>'; // Output right area first so when space is missing, text is in front of tabs and not under.
// Show title
$showtitle=1;
if (! empty($conf->dol_optimize_smallscreen)) $showtitle=0;
@ -1055,6 +1064,8 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi
if (count($keys)) $maxkey=max($keys);
}
//$conf->global->MAIN_MAXTABS_IN_CARD=3;
// Show tabs
$bactive=false;
// if =0 we don't use the feature
@ -1142,7 +1153,7 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi
{
$tabsname=str_replace("@", "", $picto);
$out.='<div id="moretabs'.$tabsname.'" class="inline-block tabsElem">';
$out.='<a href="#" data-role="button" class="tab moretab inline-block">'.$langs->trans("More").'... ('.$nbintab.')</a>';
$out.='<a href="#" data-role="button" class="tab moretab inline-block tabunactive">'.$langs->trans("More").'... ('.$nbintab.')</a>';
$out.='<div id="moretabsList'.$tabsname.'" style="position: absolute; left: -999em;text-align: left;margin:0px;padding:2px">'.$outmore.'</div>';
$out.="</div>\n";
@ -5208,9 +5219,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob
if (empty($exclude) || ! in_array('system', $exclude))
{
$substitutionarray=array_merge($substitutionarray, array(
'__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT
));
$substitutionarray['__(AnyTranslationKey)__']=$outputlangs->trans('TranslationKey');
$substitutionarray['__DOL_MAIN_URL_ROOT__']=DOL_MAIN_URL_ROOT;
}
if (empty($exclude) || ! in_array('mycompany', $exclude))
{

View File

@ -34,7 +34,7 @@
* @param string $readdir Directory source (use $destdir when not defined)
* @param string $addfieldentry Array of the field entry to add array('key'=>,'type'=>,''label'=>,'visible'=>,'enabled'=>,'position'=>,'notnull'=>','index'=>,'searchall'=>,'comment'=>,'help'=>,'isameasure')
* @param string $delfieldentry Id of field to remove
* @return int <=0 if KO, >0 if OK
* @return int|object <=0 if KO, Object if OK
*/
function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='', $addfieldentry=array() ,$delfieldentry='')
{
@ -43,13 +43,29 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
if (empty($objectname)) return -1;
if (empty($readdir)) $readdir=$destdir;
if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval']))
{
dol_print_error('', 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.');
return -1;
}
// Check parameters
if (count($addfieldentry) > 0)
{
if (empty($addfieldentry['name']))
{
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Name")), null, 'errors');
return -2;
}
if (empty($addfieldentry['label']))
{
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Label")), null, 'errors');
return -2;
}
if (! preg_match('/^(integer|date|timestamp|varchar|double)/', $addfieldentry['type']))
{
setEventMessages($langs->trans('FilesForObjectUpdated', $objectname), null, 'errors');
return -1;
setEventMessages($langs->trans('BadFormatForType', $objectname), null, 'errors');
return -2;
}
}
@ -59,7 +75,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
{
$langs->load("errors");
setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
return -1;
return -3;
}
//$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
@ -69,7 +85,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
{
include_once $pathoffiletoeditsrc;
if (class_exists($objectname)) $object=new $objectname($db);
else return -1;
else return -4;
// Backup old file
dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
@ -82,8 +98,9 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
{
if (is_array($addfieldentry) && count($addfieldentry))
{
$name=$addfieldentry['name'];
$name=$addfieldentry['name'];
unset($addfieldentry['name']);
$object->fields[$name]=$addfieldentry;
}
if (! empty($delfieldentry))
@ -104,6 +121,7 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
if (count($object->fields))
{
foreach($object->fields as $key => $val)
{
$i++;
@ -117,11 +135,24 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
if ($val['comment']) $texttoinsert.= " 'comment'=>'".$val['comment']."',";
if ($val['isameasure']) $texttoinsert.= " 'isameasure'=>'".$val['isameasure']."',";
if ($val['help']) $texttoinsert.= " 'help'=>'".$val['help']."',";
if ($val['arrayofkeyval'])
{
$texttoinsert.= " 'arrayofkeyval'=>array(";
$i=0;
foreach($val['arrayofkeyval'] as $key2 => $val2)
{
if ($i) $texttoinsert.=", ";
$texttoinsert.="'".$key2."'=>'".$val2."'";
$i++;
}
$texttoinsert.= ")";
}
$texttoinsert.= "),\n";
}
}
$texttoinsert.= "\t".');'."\n";
//print ($texttoinsert);exit;
if (count($object->fields))
{
@ -152,12 +183,12 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
@chmod($pathoffiletoedittarget, octdec($newmask));
return 1;
return $object;
}
catch(Exception $e)
{
print $e->getMessage();
return -1;
return -5;
}
}
@ -169,12 +200,15 @@ function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='
* @param string $objectname Name of object
* @param string $newmask New mask
* @param string $readdir Directory source (use $destdir when not defined)
* @param Object $object If object was already loaded/known, it is pass to avaoid another include and new.
* @return int <=0 if KO, >0 if OK
*/
function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='')
function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='', $object=null)
{
global $db, $langs;
$error = 0;
if (empty($objectname)) return -1;
if (empty($readdir)) $readdir=$destdir;
@ -190,11 +224,15 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='')
return -1;
}
// Load object from myobject.class.php
try
{
include_once $pathoffiletoclasssrc;
if (class_exists($objectname)) $object=new $objectname($db);
else return -1;
if (! is_object($object))
{
include_once $pathoffiletoclasssrc;
if (class_exists($objectname)) $object=new $objectname($db);
else return -1;
}
}
catch(Exception $e)
{
@ -225,9 +263,15 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='')
$contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
file_put_contents($pathoffiletoedittarget, $contentsql);
@chmod($pathoffiletoedittarget, octdec($newmask));
$result = file_put_contents($pathoffiletoedittarget, $contentsql);
if ($result)
{
@chmod($pathoffiletoedittarget, octdec($newmask));
}
else
{
$error++;
}
// Edit .key.sql file
$pathoffiletoeditsrc=$destdir.'/sql/llx_'.strtolower($objectname).'.key.sql';
@ -255,10 +299,17 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='')
dol_mkdir(dirname($pathoffiletoedittarget));
file_put_contents($pathoffiletoedittarget, $contentsql);
@chmod($pathoffiletoedittarget, octdec($newmask));
$result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
if ($result)
{
@chmod($pathoffiletoedittarget, octdec($newmask));
}
else
{
$error++;
}
return 1;
return $error ? -1 : 1;
}

View File

@ -73,6 +73,13 @@ function print_auguria_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$m
$showmode=dol_auguria_showmenu($type_user,$newTabMenu[$i],$listofmodulesforexternal);
if ($showmode == 1)
{
// $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM)
if (preg_match('/^\$conf->global->([^\?]+)/', $newTabMenu[$i]['url'], $reg))
{
$keyforsconst=$reg[1];
$newTabMenu[$i]['url'] = $conf->global->$keyforsconst;
}
$url = $shorturl = $newTabMenu[$i]['url'];
if (! preg_match("/^(http:\/\/|https:\/\/)/i",$newTabMenu[$i]['url']))

View File

@ -1598,6 +1598,13 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu
}
}
// $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM)
if (preg_match('/^\$conf->global->([^\?]+)/', $menu_array[$i]['url'], $reg))
{
$keyforsconst=$reg[1];
$menu_array[$i]['url'] = $conf->global->$keyforsconst;
}
$url = $shorturl = $menu_array[$i]['url'];
if (! preg_match("/^(http:\/\/|https:\/\/)/i",$menu_array[$i]['url']))

View File

@ -73,7 +73,7 @@ if ($conf->use_javascript_ajax && 1 == 2) // select2 is ko with jmobile
{
if (! is_object($form)) $form=new Form($db);
$selected=-1;
$searchform.='<br><br>'.$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, 'data-role="none"', '', 0, 1, 'minwidth300', 1, $langs->trans("Search"), 0);
$searchform.='<br><br>'.$form->selectArrayAjax('searchselectcombo', DOL_URL_ROOT.'/core/ajax/selectsearchbox.php', $selected, '', '', 0, 1, 'minwidth300', 1, $langs->trans("Search"), 0);
}
else
{

View File

@ -317,7 +317,7 @@ else {
<td align="right" class="nobottom margininfos linecolmargin">
<!-- For predef product -->
<?php if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) { ?>
<select id="fournprice_predef" name="fournprice_predef" class="flat" data-role="none" style="display: none;"></select>
<select id="fournprice_predef" name="fournprice_predef" class="flat" style="display: none;"></select>
<?php } ?>
<!-- For free product -->
<input type="text" size="5" id="buying_price" name="buying_price" class="flat right" value="<?php echo (isset($_POST["buying_price"])?GETPOST("buying_price",'alpha',2):''); ?>">

View File

@ -179,7 +179,7 @@ $coldisplay=-1; // We remove first td
<td align="right" class="margininfos"><?php $coldisplay++; ?>
<!-- For predef product -->
<?php if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) { ?>
<select id="fournprice_predef" name="fournprice_predef" class="flat right" data-role="none" style="display: none;"></select>
<select id="fournprice_predef" name="fournprice_predef" class="flat right" style="display: none;"></select>
<?php } ?>
<!-- For free product -->
<input class="flat right" type="text" size="5" id="buying_price" name="buying_price" class="hideobject" value="<?php echo price($line->pa_ht,0,'',0); ?>">
@ -266,21 +266,21 @@ jQuery(document).ready(function()
if (event.which != 9 && (event.which < 37 ||event.which > 40) && jQuery("#price_ht").val() != '') {
jQuery("#price_ttc").val('');
jQuery("#multicurrency_subprice").val('');
}
}
});
jQuery("#price_ttc").keyup(function(event) {
// console.log(event.which); // discard event tag and arrows
if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') {
jQuery("#price_ht").val('');
jQuery("#multicurrency_subprice").val('');
}
}
});
jQuery("#multicurrency_subprice").keyup(function(event) {
// console.log(event.which); // discard event tag and arrows
if (event.which != 9 && (event.which < 37 || event.which > 40) && jQuery("#price_ttc").val() != '') {
jQuery("#price_ht").val('');
jQuery("#price_ttc").val('');
}
}
});
<?php

View File

@ -1683,8 +1683,8 @@ if ($action == 'create')
print $desc;
print '<div id="credit_note_options" class="clearboth">';
print '&nbsp;&nbsp;&nbsp; <input data-role="none" type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
print '<br>&nbsp;&nbsp;&nbsp; <input data-role="none" type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
print '&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithLines" id="invoiceAvoirWithLines" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithPaymentRestAmount\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithLines','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithLines">'.$langs->trans('invoiceAvoirWithLines')."</label>";
print '<br>&nbsp;&nbsp;&nbsp; <input type="checkbox" name="invoiceAvoirWithPaymentRestAmount" id="invoiceAvoirWithPaymentRestAmount" value="1" onclick="if($(this).is(\':checked\') ) { $(\'#radio_creditnote\').prop(\'checked\', true); $(\'#invoiceAvoirWithLines\').removeAttr(\'checked\'); }" '.(GETPOST('invoiceAvoirWithPaymentRestAmount','int')>0 ? 'checked':'').' /> <label for="invoiceAvoirWithPaymentRestAmount">'.$langs->trans('invoiceAvoirWithPaymentRestAmount')."</label>";
print '</div>';
print '</div></div>';

View File

@ -3,7 +3,8 @@ ModuleBuilderDesc=This tools must be used by experienced users or developers. It
EnterNameOfModuleDesc=Enter name of the module/application to create with no spaces. Use uppercase to separate words (For example: MyModule, EcommerceForShop, SyncWithMySystem...)
EnterNameOfObjectDesc=Enter name of the object to create with no spaces. Use uppercase to separate words (For example: MyObject, Student, Teacher...). The CRUD class file, but also API file, pages to list/add/edit/delete object and SQL files will be generated.
ModuleBuilderDesc2=Path where modules are generated/edited (first alternative directory defined into %s): <strong>%s</strong>
ModuleBuilderDesc3=Generated/editable modules found: <strong>%s</strong> (they are detected as editable when the file <strong>%s</strong> exists in root of module directory).
ModuleBuilderDesc3=Generated/editable modules found: <strong>%s</strong>
ModuleBuilderDesc4=A module is detected as 'editable' when the file <strong>%s</strong> exists in root of module directory
NewModule=New module
NewObject=New object
ModuleKey=Module key
@ -51,6 +52,8 @@ DatabaseIndex=Database index
FileAlreadyExists=File %s already exists
TriggersFile=File for triggers code
HooksFile=File for hooks code
ArrayOfKeyValues=Array of key-val
ArrayOfKeyValuesDesc=Array of keys and values if field is a combo list with fixed values
WidgetFile=Widget file
ReadmeFile=Readme file
ChangeLog=ChangeLog file
@ -63,4 +66,16 @@ UseAsciiDocFormat=You can use Markdown format, but it is recommanded to use Asci
IsAMeasure=Is a measure
DirScanned=Directory scanned
NoTrigger=No trigger
NoWidget=No widget
NoWidget=No widget
GoToApiExplorer=Go to API explorer
ListOfPermissionsDefined=List of defined permissions
EnabledDesc=Condition to have this field active (Examples: 1 or $conf->global->MYMODULE_MYOPTION)
VisibleDesc=Is the field visible into list ? (Examples: 0=not visible, 1=visible by default on list, -1=not shown by default on list but can be added into list to be viewed)
IsAMeasureDesc=Can the value of field be cumulated to get a total into list ? (Examples: 1 or 0)
SearchAllDesc=Is the field used to make a search from the quick search tool ? (Examples: 1 or 0)
SpecDefDesc=Enter here all documentation you want to provide with your module that is not already defined by other tabs. You can use .md or better, the rich .asciidoc syntax.
LanguageDefDesc=Enter in this files, all the key and the translation for each language file.
MenusDefDesc=Define here the menus provided by your module (once defined, they are visible into the menu editor %s)
PermissionsDefDesc=Define here the new permissions provided by your module (once defined, they are visible into the default permissions setup %s)
HooksDefDesc=Define in the <b>module_parts['hooks']</b> property in the module descriptor the context of hooks you want to manage (list of contexts can be found by a search on '<b>initHooks(</b>' in core code).<br>Edit the hook file to add code of your hooked functions (hookable functions can be found by a search on '<b>executeHooks</b>' in core code).
TriggerDefDesc=Define in the trigger file the code you want to execute for each business event executed

View File

@ -23,7 +23,7 @@
* \brief Home page for module builder module
*/
if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti SQL+XSS injection attack test
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@ -337,13 +337,13 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
if (! $error)
{
// Edit the class file to write properties
$result=rebuildObjectClass($destdir, $module, $objectname, $newmask);
if ($result < 0) $error++;
$object=rebuildObjectClass($destdir, $module, $objectname, $newmask);
if (is_numeric($object) && $object < 0) $error++;
}
if (! $error)
{
// Edit sql with new properties
$result=rebuildObjectSql($destdir, $module, $objectname, $newmask);
$result=rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object);
if ($result < 0) $error++;
}
@ -362,22 +362,32 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj))
dol_mkdir($destdir);
$addfieldentry = array(
'name'=>GETPOST('propname','aZ09'),'type'=>GETPOST('proptype','aZ09'),'label'=>GETPOST('proplabel','aZ09'),'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'),
'name'=>GETPOST('propname','aZ09'),'label'=>GETPOST('proplabel','alpha'),'type'=>GETPOST('proptype','alpha'),
'arrayofkeyval'=>GETPOST('proparrayofkeyval','none'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}'
'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'),
'position'=>GETPOST('propposition','int'),'notnull'=>GETPOST('propnotnull','int'),'index'=>GETPOST('propindex','int'),'searchall'=>GETPOST('propsearchall','int'),
'isameasure'=>GETPOST('propisameasure','int'), 'comment'=>GETPOST('propcomment','alpha'),'help'=>GETPOST('prophelp'));
if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval']))
{
$addfieldentry['arrayofkeyval'] = dol_json_decode($addfieldentry['arrayofkeyval'], true);
}
// Edit the class file to write properties
if (! $error)
{
$result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry);
if ($result <= 0) $error++;
$object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry);
if (is_numeric($result) && $result <= 0) $error++;
}
// Edit sql with new properties
if (! $error)
{
$result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir);
if ($result <= 0) $error++;
$result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
if ($result <= 0)
{
$error++;
}
}
if (! $error)
@ -405,14 +415,14 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey)
// Edit the class file to write properties
if (! $error)
{
$result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
if ($result <= 0) $error++;
$object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
if (is_numeric($object) && $object <= 0) $error++;
}
// Edit sql with new properties
if (! $error)
{
$result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir);
$result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
if ($result <= 0) $error++;
}
@ -675,16 +685,26 @@ if ($action == 'savefile' && empty($cancel))
// Save old version
if (dol_is_file($pathoffile))
{
dol_move($pathoffile, $pathoffilebackup, 0, 1, 0, 0);
dol_copy($pathoffile, $pathoffilebackup, 0, 1);
}
$content = GETPOST('editfilecontent');
$content = GETPOST('editfilecontent','none');
// Save file on disk
file_put_contents($pathoffile, $content);
@chmod($pathoffile, octdec($newmask));
if ($content)
{
dol_delete_file($pathoffile);
file_put_contents($pathoffile, $content);
@chmod($pathoffile, octdec($newmask));
setEventMessages($langs->trans("FileSaved"), null);
setEventMessages($langs->trans("FileSaved"), null);
}
else
{
setEventMessages($langs->trans("ContentCantBeEmpty"), null, 'errors');
//$action='editfile';
$error++;
}
}
}
@ -831,7 +851,8 @@ if ($message)
print $message;
}
print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'<br>';
//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).'<br>';
$infomodulesfound = '<div style="padding: 12px 9px 12px">'.$form->textwithpicto($langs->trans("ModuleBuilderDesc3", count($listofmodules)), $langs->trans("ModuleBuilderDesc4", $FILEFLAG)).'</div>';
// Load module descriptor
@ -891,7 +912,7 @@ $head[$h][2] = 'deletemodule';
$h++;
dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic'); // Modules
dol_fiche_head($head, $module, $langs->trans("Modules"), -1, 'generic', 0, $infomodulesfound); // Modules
if ($module == 'initmodule')
{
@ -950,12 +971,14 @@ elseif (! empty($module))
$linktoenabledisable.=img_picto($langs->trans("Disabled"),'switch_off');
$linktoenabledisable.="</a>\n";
}
$modulestatusinfo=img_info('').' '.$langs->trans("ModuleIsNotActive", $urltomodulesetup);
if (! empty($conf->$module->enabled))
if (! empty($conf->$modulelowercase->enabled))
{
$modulestatusinfo=img_warning().' '.$langs->trans("ModuleIsLive");
}
else
{
$modulestatusinfo=img_info('').' '.$langs->trans("ModuleIsNotActive", $urltomodulesetup);
}
$head2[$h][0] = $_SERVER["PHP_SELF"].'?tab=description&module='.$module.($forceddirread?'@'.$dirread:'');
$head2[$h][1] = $langs->trans("Description");
@ -1134,9 +1157,12 @@ elseif (! empty($module))
}
else
{
$fullpathoffile=dol_buildpath($file, 0); // Description - level 2
$fullpathoffile=dol_buildpath($file, 0, 1); // Description - level 2
$content = file_get_contents($fullpathoffile);
if ($fullpathoffile)
{
$content = file_get_contents($fullpathoffile);
}
// New module
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
@ -1154,7 +1180,7 @@ elseif (! empty($module))
dol_fiche_end();
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1172,6 +1198,9 @@ elseif (! empty($module))
{
if ($action != 'editfile' || empty($file))
{
print $langs->trans("SpecDefDesc").'<br>';
print '<br>';
$specs=dol_dir_list(dol_buildpath($modulelowercase.'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$');
foreach ($specs as $spec)
@ -1206,7 +1235,7 @@ elseif (! empty($module))
print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html'));
print '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1219,6 +1248,9 @@ elseif (! empty($module))
{
if ($action != 'editfile' || empty($file))
{
print $langs->trans("LanguageDefDesc").'<br>';
print '<br>';
$langfiles=dol_dir_list(dol_buildpath($modulelowercase.'/langs', 0), 'files', 1, '\.lang$');
foreach ($langfiles as $langfile)
@ -1251,7 +1283,7 @@ elseif (! empty($module))
print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'text'));
print '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1288,12 +1320,12 @@ elseif (! empty($module))
//$objectname = preg_replace('/\.txt$/', '', $fileobj['name']);
$objectname = $reg[1];
if (empty($firstobjectname)) $firstobjectname = $objectname;
}
$head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname;
$head3[$h][1] = $objectname;
$head3[$h][2] = $objectname;
$h++;
$head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj='.$objectname;
$head3[$h][1] = $objectname;
$head3[$h][2] = $objectname;
$h++;
}
}
$head3[$h][0] = $_SERVER["PHP_SELF"].'?tab=objects&module='.$module.($forceddirread?'@'.$dirread:'').'&tabobj=deleteobject';
@ -1367,40 +1399,84 @@ elseif (! empty($module))
$pathtosql = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.sql';
$pathtosqlextra = strtolower($module).'/sql/llx_'.strtolower($tabobj).'_extrafields.sql';
$pathtosqlkey = strtolower($module).'/sql/llx_'.strtolower($tabobj).'.key.sql';
$pathtolib = strtolower($module).'/lib/'.strtolower($tabobj).'.lib.php';
$pathtopicto = strtolower($module).'/img/object_'.strtolower($tabobj).'.png';
$realpathtoclass = dol_buildpath($pathtoclass, 0, 1);
$realpathtoapi = dol_buildpath($pathtoapi, 0, 1);
$realpathtoagenda = dol_buildpath($pathtoagenda, 0, 1);
$realpathtocard = dol_buildpath($pathtocard, 0, 1);
$realpathtodocument = dol_buildpath($pathtodocument, 0, 1);
$realpathtolist = dol_buildpath($pathtolist, 0, 1);
$realpathtonote = dol_buildpath($pathtonote, 0, 1);
$realpathtophpunit = dol_buildpath($pathtophpunit, 0, 1);
$realpathtosql = dol_buildpath($pathtosql, 0, 1);
$realpathtosqlextra = dol_buildpath($pathtosqlextra, 0, 1);
$realpathtosqlkey = dol_buildpath($pathtosqlkey, 0, 1);
$realpathtolib = dol_buildpath($pathtolib, 0, 1);
$realpathtopicto = dol_buildpath($pathtopicto, 0, 1);
print '<div class="fichehalfleft">';
print '<span class="fa fa-file"></span> '.$langs->trans("ClassFile").' : <strong>'.$pathtoclass.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtoclass).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("ClassFile").' : <strong>'.($realpathtoclass?'':'<strike>').$pathtoclass.($realpathtoclass?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtoclass).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("ApiClassFile").' : <strong>'.$pathtoapi.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("ApiClassFile").' : <strong>'.($realpathtoapi?'':'<strike>').$pathtoapi.($realpathtoapi?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print ' &nbsp; <a href="'.DOL_URL_ROOT.'/api/index.php/explorer/" target="apiexplorer">'.$langs->trans("GoToApiExplorer").'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("TestClassFile").' : <strong>'.$pathtophpunit.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtophpunit).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("TestClassFile").' : <strong>'.($realpathtophpunit?'':'<strike>').$pathtophpunit.($realpathtophpunit?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtophpunit).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("SqlFile").' : <strong>'.$pathtosql.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=sql&file='.urlencode($pathtosql).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileExtraFields").' : <strong>'.$pathtosqlextra.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&file='.urlencode($pathtosqlextra).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForLib").' : <strong>'.($realpathtolib?'':'<strike>').$pathtolib.($realpathtodocument?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtolib).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForPicto").' : <strong>'.($realpathtopicto?'':'<strike>').$pathtopicto.($realpathtopicto?'':'</strike>').'</strong>';
//print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtopicto).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("SqlFile").' : <strong>'.($realpathtosql?'':'<strike>').$pathtosql.($realpathtosql?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=sql&file='.urlencode($pathtosql).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("DropTableIfEmpty").'</a>';
//print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileExtraFields").' : <strong>'.($realpathtosqlextra?'':'<strike>').$pathtosqlextra.($realpathtosqlextra?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&file='.urlencode($pathtosqlextra).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
//print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileKey").' : <strong>'.($realpathtosqlkey?'':'<strike>').$pathtosqlkey.($realpathtosqlkey?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=sql&file='.urlencode($pathtosqlkey).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
//print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'">'.$langs->trans("RunSql").'</a>';
print '<br>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("SqlFileKey").' : <strong>'.$pathtosqlkey.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=sql&file='.urlencode($pathtosqlkey).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '</div>';
$urloflist = dol_buildpath($pathtolist, 1);
$urlofcard = dol_buildpath($pathtocard, 1);
print '<div class="fichehalfleft">';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForList").' : <strong>'.$pathtolist.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtolist).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForList").' : <strong><a href="'.$urloflist.'" target="_test">'.($realpathtosql?'':'<strike>').$pathtolist.($realpathtosql?'':'</strike>').'</a></strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtolist).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForCreateEditView").' : <strong>'.$pathtocard.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtocard).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForCreateEditView").' : <strong><a href="'.$urlofcard.'?action=create" target="_test">'.($realpathtocard?'':'<strike>').$pathtocard.($realpathtocard?'':'</strike>').'?action=create</a></strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtocard).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForAgendaTab").' : <strong>'.$pathtoagenda.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtoagenda).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForAgendaTab").' : <strong>'.($realpathtoagenda?'':'<strike>').$pathtoagenda.($realpathtoagenda?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtoagenda).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForDocumentTab").' : <strong>'.$pathtodocument.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtodocument).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForDocumentTab").' : <strong>'.($realpathtodocument?'':'<strike>').$pathtodocument.($realpathtodocument?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtodocument).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForNoteTab").' : <strong>'.$pathtonote.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtonote).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<span class="fa fa-file"></span> '.$langs->trans("PageForNoteTab").' : <strong>'.($realpathtonote?'':'<strike>').$pathtonote.($realpathtonote?'':'</strike>').'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&tabobj='.$tabobj.'&module='.$module.($forceddirread?'@'.$dirread:'').'&action=editfile&format=php&file='.urlencode($pathtonote).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<br>';
print '</div>';
print '<br><br><br>';
@ -1413,139 +1489,174 @@ elseif (! empty($module))
{
$result = @include_once($dirread.'/'.$pathtoclass);
}
if (class_exists($tabobj)) $tmpobjet = new $tabobj($db);
$reflector = new ReflectionClass($tabobj);
$properties = $reflector->getProperties(); // Can also use get_object_vars
$propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
//$propstat = $reflector->getStaticProperties();
print load_fiche_titre($langs->trans("Properties"), '', '');
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="addproperty">';
print '<input type="hidden" name="tab" value="objects">';
print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module.($forceddirread?'@'.$dirread:'')).'">';
print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
print '<div class="div-table-responsive">';
print '<table class="noborder">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Property");
print ' (<a href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("Example").'</a>)';
print '</td>';
print '<td>';
print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey"));
print '</td>';
print '<td>'.$langs->trans("Type").'</td>';
print '<td class="center">'.$langs->trans("NotNull").'</td>';
//print '<td>'.$langs->trans("DefaultValue").'</td>';
print '<td class="center">'.$langs->trans("DatabaseIndex").'</td>';
print '<td class="right">'.$langs->trans("Position").'</td>';
print '<td class="right">'.$langs->trans("Enabled").'</td>';
print '<td class="right">'.$langs->trans("Visible").'</td>';
print '<td class="right">'.$langs->trans("IsAMeasure").'</td>';
print '<td class="center">'.$langs->trans("SearchAll").'</td>';
print '<td>'.$langs->trans("Comment").'</td>';
print '<td></td>';
print '</tr>';
print '<tr>';
print '<td><input class="text" name="propname" value=""></td>';
print '<td><input class="text" name="proplabel" value=""></td>';
print '<td><input class="text" name="proptype" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propnotnull" value=""></td>';
//print '<td><input class="text" name="propdefault" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propindex" value=""></td>';
print '<td class="right"><input class="text right" size="2" name="propposition" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propenabled" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propvisible" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propisameasure" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propsearchall" value=""></td>';
print '<td><input class="text" name="propcomment" value=""></td>';
print '<td align="center">';
print '<input class="button" type="submit" name="add" value="'.$langs->trans("Add").'">';
print '</td></tr>';
$properties = $tmpobjet->fields;
foreach($properties as $propkey => $propval)
if (class_exists($tabobj))
{
/* If from Reflection
if ($propval->class == $tabobj)
{
$propname=$propval->getName();
$comment=$propval->getDocComment();
$type=gettype($tmpobjet->$propname);
$default=$propdefault[$propname];
// Discard generic properties
if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue;
// Keep or not lines
if (in_array($propname, array('fk_element', 'lines'))) continue;
}*/
$propname=$propkey;
$proplabel=$propval['label'];
$proptype=$propval['type'];
$propnotnull=$propval['notnull'];
$propsearchall=$propval['searchall'];
//$propdefault=$propval['default'];
$propindex=$propval['index'];
$propposition=$propval['position'];
$propenabled=$propval['enabled'];
$propvisible=$propval['visible'];
$propisameasure=$propval['isameasure'];
$propcomment=$propval['comment'];
print '<tr class="oddeven">';
print '<td>';
print $propname;
print '</td>';
print '<td>';
print $proplabel;
print '</td>';
print '<td>';
print $proptype;
print '</td>';
print '<td class="center">';
print $propnotnull;
print '</td>';
/*print '<td>';
print $propdefault;
print '</td>';*/
print '<td class="center">';
print $propindex?'X':'';
print '</td>';
print '<td align="right">';
print $propposition;
print '</td>';
print '<td class="center">';
print $propenabled?$propenabled:'';
print '</td>';
print '<td class="center">';
print $propvisible?$propvisible:'';
print '</td>';
print '<td class="center">';
print $propisameasure?$propisameasure:'';
print '</td>';
print '<td class="center">';
print $propsearchall?'X':'';
print '</td>';
print '<td>';
print $propcomment;
print '</td>';
print '<td class="center">';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=deleteproperty&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_delete().'</a>';
print '</td>';
print '</tr>';
try {
$tmpobjet = @new $tabobj($db);
}
catch(Exception $e)
{
dol_syslog('Failed to load Constructor of class: '.$e->getMessage(), LOG_WARNING);
}
}
print '</table>';
print '</div>';
print '</form>';
if (! empty($tmpobjet))
{
$reflector = new ReflectionClass($tabobj);
$properties = $reflector->getProperties(); // Can also use get_object_vars
$propdefault = $reflector->getDefaultProperties(); // Can also use get_object_vars
//$propstat = $reflector->getStaticProperties();
print load_fiche_titre($langs->trans("Properties"), '', '');
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="addproperty">';
print '<input type="hidden" name="tab" value="objects">';
print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module.($forceddirread?'@'.$dirread:'')).'">';
print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
print '<div class="div-table-responsive">';
print '<table class="noborder">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Property");
print ' (<a href="https://wiki.dolibarr.org/index.php/Language_and_development_rules#Table_and_fields_structures" target="_blank">'.$langs->trans("Example").'</a>)';
print '</td>';
print '<td>';
print $form->textwithpicto($langs->trans("Label"), $langs->trans("YouCanUseTranslationKey"));
print '</td>';
print '<td>'.$langs->trans("Type").'</td>';
print '<td>'.$form->textwithpicto($langs->trans("ArrayOfKeyValues"), $langs->trans("ArrayOfKeyValuesDesc")).'</td>';
print '<td class="center">'.$langs->trans("NotNull").'</td>';
//print '<td>'.$langs->trans("DefaultValue").'</td>';
print '<td class="center">'.$langs->trans("DatabaseIndex").'</td>';
print '<td class="right">'.$langs->trans("Position").'</td>';
print '<td class="center">'.$form->textwithpicto($langs->trans("Enabled"), $langs->trans("EnabledDesc")).'</td>';
print '<td class="center">'.$form->textwithpicto($langs->trans("Visible"), $langs->trans("VisibleDesc")).'</td>';
print '<td class="center">'.$form->textwithpicto($langs->trans("IsAMeasure"), $langs->trans("IsAMeasureDesc")).'</td>';
print '<td class="center">'.$form->textwithpicto($langs->trans("SearchAll"), $langs->trans("SearchAllDesc")).'</td>';
print '<td>'.$langs->trans("Comment").'</td>';
print '<td></td>';
print '</tr>';
$properties = dol_sort_array($tmpobjet->fields, 'position');
if (! empty($properties))
{
// Line to add a property
print '<tr>';
print '<td><input class="text" name="propname" value="'.dol_escape_htmltag(GETPOST('propname','alpha')).'"></td>';
print '<td><input class="text" name="proplabel" value="'.dol_escape_htmltag(GETPOST('proplabel','alpha')).'"></td>';
print '<td><input class="text" name="proptype" value="'.dol_escape_htmltag(GETPOST('proptype','alpha')).'"></td>';
print '<td><input class="text" name="proparrayofkeyval" value="'.dol_escape_htmltag(GETPOST('proparrayofkeyval','none')).'"></td>';
print '<td class="center"><input class="text" size="2" name="propnotnull" value="'.dol_escape_htmltag(GETPOST('propnotnull','alpha')).'"></td>';
//print '<td><input class="text" name="propdefault" value=""></td>';
print '<td class="center"><input class="text" size="2" name="propindex" value="'.dol_escape_htmltag(GETPOST('propindex','alpha')).'"></td>';
print '<td class="right"><input class="text right" size="2" name="propposition" value="'.dol_escape_htmltag(GETPOST('propposition','alpha')).'"></td>';
print '<td class="center"><input class="text" size="2" name="propenabled" value="'.dol_escape_htmltag(GETPOST('propenabled','alpha')).'"></td>';
print '<td class="center"><input class="text" size="2" name="propvisible" value="'.dol_escape_htmltag(GETPOST('propvisible','alpha')).'"></td>';
print '<td class="center"><input class="text" size="2" name="propisameasure" value="'.dol_escape_htmltag(GETPOST('propisameasure','alpha')).'"></td>';
print '<td class="center"><input class="text" size="2" name="propsearchall" value="'.dol_escape_htmltag(GETPOST('propsearchall','alpha')).'"></td>';
print '<td><input class="text" name="propcomment" value="'.dol_escape_htmltag(GETPOST('propcomment','alpha')).'"></td>';
print '<td align="center">';
print '<input class="button" type="submit" name="add" value="'.$langs->trans("Add").'">';
print '</td></tr>';
foreach($properties as $propkey => $propval)
{
/* If from Reflection
if ($propval->class == $tabobj)
{
$propname=$propval->getName();
$comment=$propval->getDocComment();
$type=gettype($tmpobjet->$propname);
$default=$propdefault[$propname];
// Discard generic properties
if (in_array($propname, array('element', 'childtables', 'table_element', 'table_element_line', 'class_element_line', 'isnolinkedbythird', 'ismultientitymanaged'))) continue;
// Keep or not lines
if (in_array($propname, array('fk_element', 'lines'))) continue;
}*/
$propname=$propkey;
$proplabel=$propval['label'];
$proptype=$propval['type'];
$proparrayofkeyval=$propval['arrayofkeyval'];
$propnotnull=$propval['notnull'];
$propsearchall=$propval['searchall'];
//$propdefault=$propval['default'];
$propindex=$propval['index'];
$propposition=$propval['position'];
$propenabled=$propval['enabled'];
$propvisible=$propval['visible'];
$propisameasure=$propval['isameasure'];
$propcomment=$propval['comment'];
print '<tr class="oddeven">';
print '<td>';
print $propname;
print '</td>';
print '<td>';
print $proplabel;
print '</td>';
print '<td>';
print $proptype;
print '</td>';
print '<td>';
if ($proparrayofkeyval)
{
print json_encode($proparrayofkeyval);
}
print '</td>';
print '<td class="center">';
print $propnotnull;
print '</td>';
/*print '<td>';
print $propdefault;
print '</td>';*/
print '<td class="center">';
print $propindex?'X':'';
print '</td>';
print '<td align="right">';
print $propposition;
print '</td>';
print '<td class="center">';
print $propenabled?$propenabled:'';
print '</td>';
print '<td class="center">';
print $propvisible?$propvisible:'';
print '</td>';
print '<td class="center">';
print $propisameasure?$propisameasure:'';
print '</td>';
print '<td class="center">';
print $propsearchall?'X':'';
print '</td>';
print '<td>';
print $propcomment;
print '</td>';
print '<td class="center">';
print '<a href="'.$_SERVER["PHP_SELF"].'?action=deleteproperty&propertykey='.urlencode($propname).'&tab='.urlencode($tab).'&module='.urlencode($module).'&tabobj='.urlencode($tabobj).'">'.img_delete().'</a>';
print '</td>';
print '</tr>';
}
}
else
{
print '<tr><td><span class="warning">'.$langs->trans('Property $field not found into the class. The class was probably not generated by modulebuilder.').'</warning></td></tr>';
}
print '</table>';
print '</div>';
print '</form>';
}
else
{
print '<tr><td><span class="warning">'.$langs->trans('Failed to init the object with the new.').'</warning></td></tr>';
}
}
catch(Exception $e)
{
@ -1571,13 +1682,14 @@ elseif (! empty($module))
print '<input type="hidden" name="action" value="savefile">';
print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
print '<input type="hidden" name="tab" value="'.$tab.'">';
print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
print '<input type="hidden" name="module" value="'.$module.($forceddirread?'@'.$dirread:'').'">';
$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 '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1591,22 +1703,267 @@ elseif (! empty($module))
if ($tab == 'menus')
{
print $langs->trans("FeatureNotYetAvailable");
$pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php';
//$menus = $moduleobj->;
if ($action != 'editfile' || empty($file))
{
print $langs->trans("MenusDefDesc", '<a href="'.DOL_URL_ROOT.'/admin/menus/index.php">'.$langs->trans('Menus').'</a>').'<br>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong>'.$pathtofile.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<br>';
//print load_fiche_titre($langs->trans("MenusList"), '', '');
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="addproperty">';
print '<input type="hidden" name="tab" value="objects">';
print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
/*
print '<div class="div-table-responsive">';
print '<table class="noborder">';
print '<tr class="liste_titre">';
print_liste_field_titre("Menu",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder);
print_liste_field_titre("CronTask",'','',"",$param,'',$sortfield,$sortorder);
print_liste_field_titre("CronFrequency",'',"","",$param,'',$sortfield,$sortorder);
print_liste_field_titre("StatusAtInstall",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder);
print_liste_field_titre("Comment",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder);
print "</tr>\n";
if (count($menus))
{
foreach ($cronjobs as $cron)
{
print '<tr class="oddeven">';
print '<td>';
print $cron['label'];
print '</td>';
print '<td>';
if ($cron['jobtype']=='method')
{
$text=$langs->trans("CronClass");
$texttoshow=$langs->trans('CronModule').': '.$module.'<br>';
$texttoshow.=$langs->trans('CronClass').': '. $cron['class'].'<br>';
$texttoshow.=$langs->trans('CronObject').': '. $cron['objectname'].'<br>';
$texttoshow.=$langs->trans('CronMethod').': '. $cron['method'];
$texttoshow.='<br>'.$langs->trans('CronArgs').': '. $cron['parameters'];
$texttoshow.='<br>'.$langs->trans('Comment').': '. $langs->trans($cron['comment']);
}
elseif ($cron['jobtype']=='command')
{
$text=$langs->trans('CronCommand');
$texttoshow=$langs->trans('CronCommand').': '.dol_trunc($cron['command']);
$texttoshow.='<br>'.$langs->trans('CronArgs').': '. $cron['parameters'];
$texttoshow.='<br>'.$langs->trans('Comment').': '. $langs->trans($cron['comment']);
}
print $form->textwithpicto($text, $texttoshow, 1);
print '</td>';
print '<td>';
if($cron['unitfrequency'] == "60") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes');
if($cron['unitfrequency'] == "3600") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours');
if($cron['unitfrequency'] == "86400") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days');
if($cron['unitfrequency'] == "604800") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks');
print '</td>';
print '<td>';
print $cron['status'];
print '</td>';
print '<td>';
if (!empty($cron['comment'])) {print $cron['comment'];}
print '</td>';
print '</tr>';
}
}
else
{
print '<tr><td class="opacitymedium" colspan="5">'.$langs->trans("None").'</td></tr>';
}
print '</table>';
print '</div>';
print '</form>';
*/
}
else
{
$fullpathoffile=dol_buildpath($file, 0);
$content = file_get_contents($fullpathoffile);
// New module
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="savefile">';
print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
print '<input type="hidden" name="tab" value="'.$tab.'">';
print '<input type="hidden" name="module" value="'.$module.'">';
$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 '<br>';
print '<center>';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
print '</form>';
}
}
if ($tab == 'permissions')
{
print $langs->trans("FeatureNotYetAvailable");
$pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php';
//$perms = $moduleobj->;
if ($action != 'editfile' || empty($file))
{
print $langs->trans("PermissionsDefDesc", '<a href="'.DOL_URL_ROOT.'/admin/perms.php">'.$langs->trans('DefaultPermissions').'</a>').'<br>';
print '<br>';
print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong>'.$pathtofile.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
print '<br>';
print load_fiche_titre($langs->trans("ListOfPermissionsDefined"), '', '');
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="addproperty">';
print '<input type="hidden" name="tab" value="objects">';
print '<input type="hidden" name="module" value="'.dol_escape_htmltag($module).'">';
print '<input type="hidden" name="tabobj" value="'.dol_escape_htmltag($tabobj).'">';
print 'TODO...';
/*
print '<div class="div-table-responsive">';
print '<table class="noborder">';
print '<tr class="liste_titre">';
print_liste_field_titre("CronLabel",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder);
print_liste_field_titre("CronTask",'','',"",$param,'',$sortfield,$sortorder);
print_liste_field_titre("CronFrequency",'',"","",$param,'',$sortfield,$sortorder);
print_liste_field_titre("StatusAtInstall",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder);
print_liste_field_titre("Comment",$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder);
print "</tr>\n";
if (count($cronjobs))
{
foreach ($cronjobs as $cron)
{
print '<tr class="oddeven">';
print '<td>';
print $cron['label'];
print '</td>';
print '<td>';
if ($cron['jobtype']=='method')
{
$text=$langs->trans("CronClass");
$texttoshow=$langs->trans('CronModule').': '.$module.'<br>';
$texttoshow.=$langs->trans('CronClass').': '. $cron['class'].'<br>';
$texttoshow.=$langs->trans('CronObject').': '. $cron['objectname'].'<br>';
$texttoshow.=$langs->trans('CronMethod').': '. $cron['method'];
$texttoshow.='<br>'.$langs->trans('CronArgs').': '. $cron['parameters'];
$texttoshow.='<br>'.$langs->trans('Comment').': '. $langs->trans($cron['comment']);
}
elseif ($cron['jobtype']=='command')
{
$text=$langs->trans('CronCommand');
$texttoshow=$langs->trans('CronCommand').': '.dol_trunc($cron['command']);
$texttoshow.='<br>'.$langs->trans('CronArgs').': '. $cron['parameters'];
$texttoshow.='<br>'.$langs->trans('Comment').': '. $langs->trans($cron['comment']);
}
print $form->textwithpicto($text, $texttoshow, 1);
print '</td>';
print '<td>';
if($cron['unitfrequency'] == "60") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Minutes');
if($cron['unitfrequency'] == "3600") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Hours');
if($cron['unitfrequency'] == "86400") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Days');
if($cron['unitfrequency'] == "604800") print $langs->trans('CronEach')." ".($cron['frequency'])." ".$langs->trans('Weeks');
print '</td>';
print '<td>';
print $cron['status'];
print '</td>';
print '<td>';
if (!empty($cron['comment'])) {print $cron['comment'];}
print '</td>';
print '</tr>';
}
}
else
{
print '<tr><td class="opacitymedium" colspan="5">'.$langs->trans("None").'</td></tr>';
}
print '</table>';
print '</div>';
print '</form>';
*/
}
else
{
$fullpathoffile=dol_buildpath($file, 0);
$content = file_get_contents($fullpathoffile);
// New module
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
print '<input type="hidden" name="action" value="savefile">';
print '<input type="hidden" name="file" value="'.dol_escape_htmltag($file).'">';
print '<input type="hidden" name="tab" value="'.$tab.'">';
print '<input type="hidden" name="module" value="'.$module.'">';
$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 '<br>';
print '<center>';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
print '</form>';
}
}
if ($tab == 'hooks')
{
if ($action != 'editfile' || empty($file))
{
$pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
print '<span class="fa fa-file"></span> '.$langs->trans("HooksFile").' : <strong>'.$pathtohook.'</strong>';
print $langs->trans("HooksDefDesc").'<br>';
print '<br>';
$pathtofile = $modulelowercase.'/core/modules/mod'.$module.'.class.php';
print '<span class="fa fa-file"></span> '.$langs->trans("DescriptorFile").' : <strong>'.$pathtofile.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&format=php&file='.urlencode($pathtofile).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
$pathtohook = strtolower($module).'/class/actions_'.strtolower($module).'.class.php';
print '<span class="fa fa-file"></span> '.$langs->trans("HooksFile").' : <strong>'.$pathtohook.'</strong>';
print ' <a href="'.$_SERVER['PHP_SELF'].'?tab='.$tab.'&module='.$module.'&action=editfile&format=php&file='.urlencode($pathtohook).'">'.img_picto($langs->trans("Edit"), 'edit').'</a>';
print '<br>';
}
@ -1628,7 +1985,7 @@ elseif (! empty($module))
print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html'));
print '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1646,6 +2003,9 @@ elseif (! empty($module))
if ($action != 'editfile' || empty($file))
{
print $langs->trans("TriggerDefDesc").'<br>';
print '<br>';
if (! empty($triggers))
{
foreach ($triggers as $trigger)
@ -1680,7 +2040,7 @@ elseif (! empty($module))
print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html'));
print '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1731,7 +2091,7 @@ elseif (! empty($module))
print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html'));
print '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';
@ -1832,6 +2192,8 @@ elseif (! empty($module))
print '</table>';
print '</div>';
print '</form>';
}
else
{
@ -1851,7 +2213,7 @@ elseif (! empty($module))
print $doleditor->Create(1, '', false, $langs->trans("File").' : '.$file, (GETPOST('format','aZ09')?GETPOST('format','aZ09'):'html'));
print '<br>';
print '<center>';
print '<input type="submit" class="button" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print '<input type="submit" class="button buttonforacesave" id="savefile" name="savefile" value="'.dol_escape_htmltag($langs->trans("Save")).'">';
print ' &nbsp; ';
print '<input type="submit" class="button" name="cancel" value="'.dol_escape_htmltag($langs->trans("Cancel")).'">';
print '</center>';

View File

@ -1,4 +1,4 @@
# CHANGELOG FOR DOLIBARR ERP CRM
# CHANGELOG MYMODULE FOR DOLIBARR ERP CRM
## 1.0
Initial version

View File

@ -62,7 +62,7 @@ class MyObject extends CommonObject
* 'type' if the field format.
* 'label' the translation key.
* 'enabled' is a condition when the filed must be managed.
* 'visible' says if field is visible in list (-1 means not shown by default but can be aded into list to be viewed).
* 'visible' says if field is visible in list (-1 means not shown by default but can be added into list to be viewed).
* 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
* 'index' if we want an index in database.
* 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...).
@ -78,19 +78,19 @@ class MyObject extends CommonObject
* @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
*/
public $fields=array(
'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'),
'ref' =>array('type'=>'varchar(64)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'index'=>1, 'position'=>20),
'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'index'=>1, 'position'=>1, 'comment'=>'Id'),
'ref' =>array('type'=>'varchar(64)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
'entity' =>array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'index'=>1, 'position'=>20),
'label' =>array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1),
'amount' =>array('type'=>'double(24,8)', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Amount'),
'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>1000),
'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
'date_creation' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
//'date_valid' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500),
'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'position'=>500),
//'fk_user_valid' =>array('type'=>'integer', 'label'=>'UserValid', 'enabled'=>1, 'visible'=>-1, 'position'=>500),
'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'notnull'=>-1, 'index'=>1, 'position'=>1000),
'status' =>array('type'=>'integer', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'index'=>1, 'position'=>1000, 'arrayofkeyval'=>array(0=>'Draft', 1=>'Active', -1=>'Cancel')),
);
public $rowid;
@ -144,7 +144,7 @@ class MyObject extends CommonObject
$this->db = $db;
if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $fields['rowid']['visible']=0;
if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $this->fields['rowid']['visible']=0;
}
/**

View File

@ -1 +1,127 @@
# SPECIFICATIONS OF MODULE MYMODULE FOR DOLIBARR ERP CRM
= MYMODULE =
Copyright (C) ---Put here your own copyright and developer email---
:subtitle: MYMODULE SPECIFICATIONS
== Topic of document
This document was build from following input:
* Date 1
...
* Date 2
...
The document includes an introductory chapter of functional specifications, presenting the different actors involved in the rebuild of the definitions
of business terms that will be used (some of which may be new or different).
The main following chapter will present the entire process, also known as *uses cases*, according to a principle of a description, in chronological sequence if possible,
to present the actor and the action performed, as in the following example:
* *X* Actor realizes Action A.
* *Y* Actor communicates Info B to Actor *Z*
* *Automaton* performs update of data for...
* Etc ...
Functional requirements are complemented by a chapter of technical requirements.
The chapter on data lists key information specific to Presto that were identified at the time of writing specification. It will be enriched as
iterations occurs.
Finally, in the Appendix, the documents known when writing this document are centralized to illustrate the existing document or inspire the new expected one.
These documents have their content directly integrated in this specification or have a reference to
external documents stored in the *Appendices* directory accompanying this document.
*Log of versions*
[options="header",format="csv"]
|===
Author, Date, Version
John Doe, Date YYY-MM-DD, Version 1.0
|===
<<<
== BUSINESS SPECIFICATIONS - INTRODUCTION
=== List of actors [[actors]]
Actors are physical people or moral entities working on at least one process.
The following chart prensts list of actors or partners identified by the project for the defined scope of project. We will use then the name defined into first column to speak about roles in the rest of documents.
[options="header",format="csv"]
|===
Actor/profil/role, Description of role, Access to system or not, Example of actor
Customer Service, Receive and create Sales orders (SO), Yes, Mr Smith
Purchase, Make puchase order (PO), Yes, 5 people
Administrator - IT, Administration of users/groups and IT services, Yes, John Doe
Automaton, Execute automatic data processing, Yes, NA
|===
=== Definitions [[definitions]]
To understand the descriptions of the target process, it was necessary to define or redefine some vocabulary concepts. We must see these definitions as defined in the
new system. Indeed, some terms are already being used but have either not a definition in line with standards, or even differs between services. To bring everyone,
and to consolidate the process, these terms are redefined here, and with their definition in the target objective.
*Definition ABC*
...
*Definition DEF*
...
[NOTE]
==============
Important information will be noticed with a notice like this one.
* Main information 1
* Main information 2
==============
== BUSINESS SPECIFICATION - PROCESS
Specifications were cut into different business process. We call a business process a workflow with a starting situation and ending situation. Between start and end, we will find actions
done by actors to bring the value of the company. This actions are described using the syntax rule:
*Actor X* do action Y, *Actor Z* do action W.
_Each process/use case is described into a separate chapter._
=== Use case / Process 1 [[process_1]]
==== Title and goals
...
==== Actors or roles
* Members of group *...*
==== Standard flow
* Members of Groupe *...*: Do ...
* Members of Groupe *...*: Do ...
* Members of Groupe *...*: Do ...
==== Alternative flow
* A user without role *...*: Can't do ...
==== Business rules
* Business rule 1
* Business rule 2

View File

@ -27,8 +27,8 @@
//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test
//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test
//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on.
//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu
@ -270,12 +270,32 @@ if ($action == 'create')
foreach($object->fields as $key => $val)
{
if (in_array($key, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat', 'fk_user_modif', 'import_key'))) continue;
print '<tr id="field_'.$key.'"><td';
print '<tr id="field_'.$key.'">';
print '<td';
print ' class="titlefieldcreate';
if ($val['notnull'] > 0) print ' fieldrequired';
print '"';
print '>'.$langs->trans($val['label']).'</td>';
print '<td><input class="flat" type="text" name="'.$key.'" value="'.(GETPOST($key,'alpha')?GETPOST($key,'alpha'):'').'"></td>';
if ($val['type'] == 'text') print ' tdtop';
print '"';
print '>';
print $langs->trans($val['label']);
print '</td>';
print '<td>';
if ($val['type'] == 'text')
{
print '<textarea class="flat quatrevingtpercent" rows="'.ROWS_4.'" name="'.$key.'">';
print GETPOST($key,'none');
print '</textarea>';
}
elseif (is_array($val['arrayofkeyval']))
{
print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int'));
}
else
{
$cssforinput = 'minwidth100';
print '<input class="flat" class="'.$cssforinput.'" type="text" name="'.$key.'" value="'.(GETPOST($key,'alpha')?GETPOST($key,'alpha'):'').'">';
}
print '</td>';
print '</tr>';
}
print '</table>'."\n";
@ -292,7 +312,7 @@ if ($action == 'create')
// Part to edit record
if (($id || $ref) && $action == 'edit')
{
print load_fiche_titre($langs->trans("MyModule"));
print load_fiche_titre($langs->trans("MyObject"));
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="action" value="update">';
@ -308,9 +328,26 @@ if (($id || $ref) && $action == 'edit')
print '<tr><td';
print ' class="titlefieldcreate';
if ($val['notnull'] > 0) print ' fieldrequired';
if ($val['type'] == 'text') print ' tdtop';
print '"';
print '>'.$langs->trans($val['label']).'</td>';
print '<td><input class="flat" type="text" name="'.$key.'" value="'.(GETPOST($key,'alpha')?GETPOST($key,'alpha'):'').'"></td>';
print '<td>';
if ($val['type'] == 'text')
{
print '<textarea class="flat quatrevingtpercent" rows="'.ROWS_4.'" name="'.$key.'">';
print GETPOST($key,'none');
print '</textarea>';
}
elseif (is_array($val['arrayofkeyval']))
{
print $form->selectarray($key, $val['arrayofkeyval'], GETPOST($key, 'int'));
}
else
{
$cssforinput = 'minwidth100';
print '<input class="flat" class="'.$cssforinput.'" type="text" name="'.$key.'" value="'.(GETPOST($key,'alpha')?GETPOST($key,'alpha'):'').'">';
}
print '</td>';
print '</tr>';
}
print '</table>';
@ -326,6 +363,7 @@ if (($id || $ref) && $action == 'edit')
// Part to show record
if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create')))
{
@ -509,10 +547,12 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '</div><div class="fichehalfright"><div class="ficheaddleft">';
$MAXEVENT = 10;
// List of actions on element
include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php';
$formactions = new FormActions($db);
$somethingshown = $formactions->showactions($object, 'myobject', $socid, 1);
$somethingshown = $formactions->showactions($object, 'myobject', $socid, 1, '', $MAXEVENT);
print '</div></div></div>';
}

View File

@ -27,8 +27,8 @@
//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
//if (! defined('NOSCANGETFORINJECTION')) define('NOSCANGETFORINJECTION','1'); // Do not check anti CSRF attack test
//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test
//if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
//if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK','1'); // Do not check anti CSRF attack test done when option MAIN_SECURITY_CSRF_WITH_TOKEN is on.
//if (! defined('NOSTYLECHECK')) define('NOSTYLECHECK','1'); // Do not check style html tag into posted data
//if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Do not check anti POST attack test
//if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU','1'); // If there is no need to load and show top and left menu

View File

@ -219,10 +219,9 @@ class FormProduct
include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
$comboenhancement = ajax_combobox($htmlname, $events);
$out.= $comboenhancement;
$nodatarole=($comboenhancement?' data-role="none"':'');
}
$out.='<select class="flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled':'').' id="'.$htmlname.'" name="'.($htmlname.($disabled?'_disabled':'')).'"'.$nodatarole.'>';
$out.='<select class="flat'.($morecss?' '.$morecss:'').'"'.($disabled?' disabled':'').' id="'.$htmlname.'" name="'.($htmlname.($disabled?'_disabled':'')).'">';
if ($empty) $out.='<option value="-1">'.($empty_label?$empty_label:'&nbsp;').'</option>';
foreach($this->cache_warehouses as $id => $arraytypes)
{

View File

@ -1133,13 +1133,11 @@ foreach ($listofreferent as $key => $value)
}
// Enhance with select2
$nodatarole='';
if ($conf->use_javascript_ajax)
{
include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
$comboenhancement = ajax_combobox('.elementselect');
$out.=$comboenhancement;
$nodatarole=($comboenhancement?' data-role="none"':'');
print $comboenhancement;
}

View File

@ -719,7 +719,9 @@ div.myavailability {
margin-top: 6px;
margin-bottom: 12px;
}
#builddoc_form ~ .showlinkedobjectblock {
margin-top: 20px;
}
/* For the long description of module */
.moduledesclong p img, .moduledesclong p a img {
@ -863,11 +865,11 @@ div.fiche>form>div.div-table-responsive {
.minwidth500imp { min-width: 250px !important; }
}
/* Force values for small screen 570 */
/* Force values for small screen 767 */
@media only screen and (max-width: 767px)
{
body {
font-size: <?php print $fontsize+1; ?>px;
font-size: <?php print $fontsize+3; ?>px;
}
}
@ -875,7 +877,7 @@ div.fiche>form>div.div-table-responsive {
@media only screen and (max-width: 570px)
{
body {
font-size: <?php print $fontsize+1; ?>px;
font-size: <?php print $fontsize+3; ?>px;
}
.divmainbodylarge { margin-left: 20px !important; margin-right: 20px !important; }
@ -2037,7 +2039,9 @@ div.tabs {
div.tabsElem {
margin-top: 1px;
} /* To avoid overlap of tabs when not browser */
div.tabsElem a {
font-weight: normal !important;
}
div.tabBar {
color: #<?php echo $colortextbacktab; ?>;
padding-top: 16px;
@ -2749,14 +2753,16 @@ input.liste_titre {
line-height: 24px;
}
.noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total {
/* height: 32px; */
}
.noborder tr.liste_total td, tr.liste_total td, form.liste_total div {
.noborder tr.liste_total td, tr.liste_total td, form.liste_total div, .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div {
color: #551188;
font-weight: normal;
}
.noborder tr.liste_total td, tr.liste_total td, form.liste_total div {
white-space: nowrap;
}
.noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div {
white-space: normal;
}
form.liste_total div {
border-top: 1px solid #DDDDDD;
}
@ -3025,11 +3031,12 @@ div.warning {
color: #302020;
padding: 0.3em 0.3em 0.3em 0.3em;
margin: 0.5em 0em 0.5em 0em;
border: 1px solid #e0d0b0;
/* border: 1px solid #e0d0b0; */
border: 2px solid #805000;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
background: #EFDF9A;
/* background: #EFDF9A; */
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
}
@ -3131,12 +3138,11 @@ td.legendLabel { padding: 2px 2px 2px 0 !important; }
div.titre {
font-family: <?php print $fontlist ?>;
font-size: 14px;
font-weight: bold;
/* font-weight: bold; */
color: rgb(<?php print $colortexttitlenotab; ?>);
text-decoration: none;
padding-top: 5px;
padding-bottom: 5px;
/* text-shadow: 1px 1px 2px #FFFFFF; */
}
#dolpaymenttable { min-width: 310px; font-size: 16px; } /* Width must have min to make stripe input area visible */
@ -3984,6 +3990,12 @@ div#ecm-layout-center {
padding-left: 10px !important;
padding-right: 10px !important;
}
.jnotify-container .jnotify-notification .jnotify-message {
font-weight: normal;
}
.jnotify-container .jnotify-notification-warning .jnotify-close, .jnotify-container .jnotify-notification-warning .jnotify-message {
color: #a28918 !important;
}
/* use or not ? */
div.jnotify-background {

View File

@ -730,7 +730,9 @@ div.myavailability {
margin-top: 6px;
margin-bottom: 12px;
}
#builddoc_form ~ .showlinkedobjectblock {
margin-top: 20px;
}
/* For the long description of module */
.moduledesclong p img,.moduledesclong p a img {
@ -865,11 +867,11 @@ div.fiche>form>div.div-table-responsive {
.minwidth500imp { min-width: 100px !important; }
}
/* Force values for small screen 570 */
/* Force values for small screen 767 */
@media only screen and (max-width: 767px)
{
body {
font-size: <?php print $fontsize+1; ?>px;
font-size: <?php print $fontsize+3; ?>px;
}
}
@ -877,7 +879,7 @@ div.fiche>form>div.div-table-responsive {
@media only screen and (max-width: 570px)
{
body {
font-size: <?php print $fontsize+1; ?>px;
font-size: <?php print $fontsize+3; ?>px;
}
.divmainbodylarge { margin-left: 20px; margin-right: 20px; }
@ -2062,8 +2064,12 @@ div.tabs {
clear:both;
height:100%;
}
div.tabsElem { margin-top: 6px; } /* To avoid overlap of tabs when not browser */
div.tabsElem {
margin-top: 6px;
} /* To avoid overlap of tabs when not browser */
div.tabsElem a {
font-weight: normal !important;
}
div.tabBar {
color: #<?php echo $colortextbacktab; ?>;
padding-top: 16px;
@ -2865,16 +2871,19 @@ input.liste_titre {
border: 0px;
}
.noborder tr.liste_total, .noborder tr.liste_total td, tr.liste_total, form.liste_total {
/* height: 32px; */
}
.noborder tr.liste_total td, tr.liste_total td, form.liste_total div {
/* border-top: 1px solid #f4f4f4; */
.noborder tr.liste_total td, tr.liste_total td, form.liste_total div, .noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div {
color: #332266;
font-weight: normal;
white-space: nowrap;
padding: 4px;
}
.noborder tr.liste_total td, tr.liste_total td, form.liste_total div {
white-space: nowrap;
}
.noborder tr.liste_total_wrap td, tr.liste_total_wrap td, form.liste_total_wrap div {
white-space: normal;
}
tr.liste_sub_total, tr.liste_sub_total td {
border-bottom: 2px solid #aaa;
}
@ -3124,11 +3133,12 @@ div.warning {
color: #302020;
padding: 0.3em 0.3em 0.3em 0.3em;
margin: 0.5em 0em 0.5em 0em;
border: 1px solid #e0d0b0;
/* border: 1px solid #e0d0b0; */
border: 2px solid #805000
-moz-border-radius:3px;
-webkit-border-radius: 3px;
border-radius: 3px;
background: #EFDF9A;
/* background: #EFDF9A; */
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
}
@ -4033,6 +4043,12 @@ div#ecm-layout-center {
padding-left: 10px !important;
padding-right: 10px !important;
}
.jnotify-container .jnotify-notification .jnotify-message {
font-weight: normal;
}
.jnotify-container .jnotify-notification-warning .jnotify-close, .jnotify-container .jnotify-notification-warning .jnotify-message {
color: #a28918 !important;
}
/* use or not ? */
div.jnotify-background {

View File

@ -275,11 +275,11 @@ if ($action == 'add')
}
else
{
$objectpage->title = GETPOST('WEBSITE_TITLE');
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
$objectpage->keywords = GETPOST('WEBSITE_KEYWORDS');
$objectpage->lang = GETPOST('WEBSITE_LANG');
$objectpage->title = GETPOST('WEBSITE_TITLE','alpha');
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME','alpha');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION','alpha');
$objectpage->keywords = GETPOST('WEBSITE_KEYWORDS','alpha');
$objectpage->lang = GETPOST('WEBSITE_LANG','alpha');
}
if (! $error)
@ -392,7 +392,7 @@ if ($action == 'updatecss')
// $htmlheadercontent.= "header('Content-type: text/html');\n"; // Not required. htmlheader.html is never call as a standalone page
$htmlheadercontent.= "// END PHP ?>\n";*/
$htmlheadercontent.= preg_replace(array('/<html>\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER'));
$htmlheadercontent.= preg_replace(array('/<html>\n*/ims','/<\/html>\n*/ims'),array('',''),GETPOST('WEBSITE_HTML_HEADER', 'none'));
/*$htmlheadercontent.= "\n".'<?php // BEGIN PHP'."\n";
$htmlheadercontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n";
@ -425,7 +425,7 @@ if ($action == 'updatecss')
$csscontent.= "header('Content-type: text/css');\n";
$csscontent.= "// END PHP ?>\n";
$csscontent.= GETPOST('WEBSITE_CSS_INLINE');
$csscontent.= GETPOST('WEBSITE_CSS_INLINE', 'none');
$csscontent.= "\n".'<?php // BEGIN PHP'."\n";
$csscontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n";
@ -457,7 +457,7 @@ if ($action == 'updatecss')
$robotcontent.= "header('Content-type: text/css');\n";
$robotcontent.= "// END PHP ?>\n";*/
$robotcontent.= GETPOST('WEBSITE_ROBOT');
$robotcontent.= GETPOST('WEBSITE_ROBOT', 'none');
/*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n";
$robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n";
@ -489,7 +489,7 @@ if ($action == 'updatecss')
$robotcontent.= "header('Content-type: text/css');\n";
$robotcontent.= "// END PHP ?>\n";*/
$htaccesscontent.= GETPOST('WEBSITE_HTACCESS');
$htaccesscontent.= GETPOST('WEBSITE_HTACCESS', 'none');
/*$robotcontent.= "\n".'<?php // BEGIN PHP'."\n";
$robotcontent.= '$tmp = ob_get_contents(); ob_end_clean(); dolWebsiteOutput($tmp);'."\n";
@ -587,11 +587,11 @@ if ($action == 'updatemeta')
{
$objectpage->old_object = clone $objectpage;
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME');
$objectpage->title = GETPOST('WEBSITE_TITLE');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION');
$objectpage->keywords = GETPOST('WEBSITE_KEYWORDS');
$objectpage->lang = GETPOST('WEBSITE_LANG');
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha');
$objectpage->title = GETPOST('WEBSITE_TITLE', 'alpha');
$objectpage->description = GETPOST('WEBSITE_DESCRIPTION', 'alpha');
$objectpage->keywords = GETPOST('WEBSITE_KEYWORDS', 'alpha');
$objectpage->lang = GETPOST('WEBSITE_LANG', 'alpha');
$res = $objectpage->update($user);
if (! $res > 0)