Merge remote-tracking branch 'upstream/develop' into newfixes

This commit is contained in:
Frédéric France 2024-03-14 20:46:47 +01:00
commit bb8604e265
33 changed files with 408 additions and 416 deletions

View file

@ -104,3 +104,6 @@ Scope is the web application (backoffice) and the APIs.
* SSL/TLS best practices
* Invalid or missing SPF (Sender Policy Framework) records (Incomplete or missing SPF/DKIM/DMARC)
* Physical or social engineering attempts or issues that require physical access to a victim’s computer/device
* Ability to include javascript into a page of the website using the website page editor are not qualified (this is the expected behaviour)
* Ability to execute PHP code on the server using the website using the website page editor by a user that own the super permission "add php code into pages" are not qualified (this is the expected behaviour).

View file

@ -191,10 +191,10 @@ if (GETPOST('actionadd', 'alpha') || GETPOST('actionmodify', 'alpha')) {
// Si verif ok et action add, on ajoute la ligne
if ($ok && GETPOST('actionadd', 'alpha')) {
$newid = 0;
if ($tabrowid[$id]) {
// Get free id for insert
$newid = 0;
$sql = "SELECT MAX(".$db->sanitize($tabrowid[$id]).") newid FROM ".$db->sanitize($tabname[$id]);
$sql = "SELECT MAX(".$db->sanitize($tabrowid[$id]).") as newid FROM ".$db->sanitize($tabname[$id]);
$result = $db->query($sql);
if ($result) {
$obj = $db->fetch_object($result);

View file

@ -484,7 +484,7 @@ if (empty($reshook)) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
break;
} elseif (isset($object->date_validation) || $object->date_validation != '') {
} elseif (isset($object->date_validation) && $object->date_validation != '') {
setEventMessages($langs->trans("ValidatedRecordWhereFound"), null, 'errors');
$error++;
break;

View file

@ -447,7 +447,7 @@ if (empty($reshook)) {
setEventMessages($object->error, $object->errors, 'errors');
$error++;
break;
} elseif (isset($object->date_validation) || $object->date_validation != '') {
} elseif (isset($object->date_validation) && $object->date_validation != '') {
setEventMessages($langs->trans("ValidatedRecordWhereFound"), null, 'errors');
$error++;
break;

View file

@ -120,12 +120,13 @@ print '<div class="underbanner clearboth"></div>';
print '<table class="border centpercent tableforfield">';
// Login
print '<tr><td class="titlefield">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.$object->login.'&nbsp;</td></tr>';
print '<tr><td class="titlefield">'.$langs->trans("Login").' / '.$langs->trans("Id").'</td><td class="valeur">'.dol_escape_htmltag($object->login).'&nbsp;</td></tr>';
// If there is a link to the unencrypted password, we show the value in database here so we can compare because it is shown nowhere else
// This is for very old situation. Password are now encrypted and $object->pass is empty.
if (getDolGlobalString('LDAP_MEMBER_FIELD_PASSWORD')) {
print '<tr><td>'.$langs->trans("LDAPFieldPasswordNotCrypted").'</td>';
print '<td class="valeur">'.$object->pass.'</td>';
print '<td class="valeur">'.dol_escape_htmltag($object->pass).'</td>';
print "</tr>\n";
}

View file

@ -617,13 +617,14 @@ if (getDolGlobalString('INVOICE_USE_DEFAULT_DOCUMENT')) { // Hidden conf
print '<form action="'.$_SERVER["PHP_SELF"].'#default-pdf-modules-by-type-table" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="action" value="setDefaultPDFModulesByType" >';
print '<input type="hidden" name="page_y" value="" />';
print '<div class="div-table-responsive-no-min">';
print '<table id="default-pdf-modules-by-type-table" class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Type").'</td>';
print '<td>'.$langs->trans("Name").'</td>';
print '<td class="right"><input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'"></td>';
print '<td class="right"><input type="submit" class="button button-edit reposition" value="'.$langs->trans("Modify").'"></td>';
print "</tr>\n";
$listtype = array(
@ -659,6 +660,7 @@ print load_fiche_titre($langs->trans("SuggestedPaymentModesIfNotDefinedInInvoice
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="page_y" value="" />';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
@ -667,17 +669,16 @@ print '<tr class="liste_titre">';
print '<td>';
print '<input type="hidden" name="action" value="setribchq">';
print $langs->trans("PaymentMode").'</td>';
print '<td class="right"><input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'"></td>';
print '<td class="right"><input type="submit" class="button button-edit reposition" value="'.$langs->trans("Modify").'"></td>';
print "</tr>\n";
print '<tr class="oddeven">';
print "<td>".$langs->trans("SuggestPaymentByRIBOnAccount")."</td>";
print "<td>";
if (isModEnabled('bank')) {
$sql = "SELECT rowid, label";
$sql = "SELECT rowid, label, clos";
$sql .= " FROM ".MAIN_DB_PREFIX."bank_account";
$sql .= " WHERE clos = 0";
$sql .= " AND courant = 1";
$sql .= " WHERE courant = 1";
$sql .= " AND entity IN (".getEntity('bank_account').")";
$resql = $db->query($sql);
if ($resql) {
@ -687,15 +688,19 @@ if (isModEnabled('bank')) {
print '<select name="rib" class="flat" id="rib">';
print '<option value="0">'.$langs->trans("DoNotSuggestPaymentMode").'</option>';
while ($i < $num) {
$row = $db->fetch_row($resql);
$obj = $db->fetch_object($resql);
print '<option value="'.$row[0].'"';
print $conf->global->FACTURE_RIB_NUMBER == $row[0] ? ' selected' : '';
print '>'.$row[1].'</option>';
print '<option value="'.$obj->rowid.'"';
print getDolGlobalString('FACTURE_RIB_NUMBER') == $obj->rowid ? ' selected' : '';
if (!empty($obj->clos)) {
print ' disabled';
}
print '>'.dol_escape_htmltag($obj->label).'</option>';
$i++;
}
print "</select>";
print ajax_combobox("rib");
} else {
print '<span class="opacitymedium">'.$langs->trans("NoActiveBankAccountDefined").'</span>';
}
@ -735,6 +740,8 @@ if ($resql) {
}
}
print "</select>";
print ajax_combobox("chq", array(), 0, 0, 'resolve', -2);
print "</td></tr>";
print "</table>";
print '</div>';
@ -757,12 +764,13 @@ print "</tr>\n";
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="action" value="setforcedate" />';
print '<input type="hidden" name="page_y" value="" />';
print '<tr class="oddeven"><td>';
print $langs->trans("ForceInvoiceDate");
print '</td><td width="60" class="center">';
print $form->selectyesno("forcedate", getDolGlobalInt('FAC_FORCE_DATE_VALIDATION', 0), 1);
print '</td><td class="right">';
print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'" />';
print '<input type="submit" class="button button-edit reposition" value="'.$langs->trans("Modify").'" />';
print "</td></tr>\n";
print '</form>';
@ -777,6 +785,7 @@ $htmltext .= '</i>';
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="action" value="set_INVOICE_FREE_TEXT" />';
print '<input type="hidden" name="page_y" value="" />';
print '<tr class="oddeven"><td colspan="2">';
print $form->textwithpicto($langs->trans("FreeLegalTextOnInvoices"), $langs->trans("AddCRIfTooLong").'<br><br>'.$htmltext, 1, 'help', '', 0, 2, 'freetexttooltip').'<br>';
$variablename = 'INVOICE_FREE_TEXT';
@ -788,7 +797,7 @@ if (!getDolGlobalString('PDF_ALLOW_HTML_FOR_FREE_TEXT')) {
print $doleditor->Create();
}
print '</td><td class="right">';
print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'" />';
print '<input type="submit" class="button button-edit reposition" value="'.$langs->trans("Modify").'" />';
print "</td></tr>\n";
print '</form>';
@ -796,12 +805,13 @@ print '</form>';
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'" />';
print '<input type="hidden" name="action" value="set_FACTURE_DRAFT_WATERMARK" />';
print '<input type="hidden" name="page_y" value="" />';
print '<tr class="oddeven"><td>';
print $form->textwithpicto($langs->trans("WatermarkOnDraftBill"), $htmltext, 1, 'help', '', 0, 2, 'watermarktooltip').'<br>';
print '</td>';
print '<td><input class="flat minwidth200imp" type="text" name="FACTURE_DRAFT_WATERMARK" value="'.dol_escape_htmltag(getDolGlobalString('FACTURE_DRAFT_WATERMARK')).'">';
print '</td><td class="right">';
print '<input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'" />';
print '<input type="submit" class="button button-edit reposition" value="'.$langs->trans("Modify").'" />';
print "</td></tr>\n";
print '</form>';

View file

@ -165,9 +165,6 @@ if ($action == 'confirm_deleteproperty' && GETPOST('confirm') == 'yes') {
}
}
}
if ($action == 'confirm_deleteproperty') {
var_dump(GETPOST('confirm'));exit;
}
/*
@ -344,7 +341,7 @@ if ($action == 'edit' || $action == 'create') {
$('#postPromptInput').val('');
}
});
$('.showInputBtn').click(function() {
event.preventDefault();
var index = $(this).data('index');
@ -357,7 +354,7 @@ if ($action == 'edit' || $action == 'create') {
$(this).html($(this).data('icon-cancel'));
$(this).data('state', 'cancel');
} else {
} else {
$('#prePromptInput_'+index).attr('disabled', 'disabled');
$('#postPromptInput_'+index).attr('disabled', 'disabled');
@ -367,8 +364,8 @@ if ($action == 'edit' || $action == 'create') {
}
});
});
</script>";
print $out;

View file

@ -2903,19 +2903,23 @@ if ($action == 'create') {
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
$object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
}
if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
print '<tr>';
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
print '<tr>';
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 1, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
$object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, 0, $langs, 1, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
}
print '<tr>';

View file

@ -281,18 +281,6 @@ class Propal extends CommonObject
public $labelStatus = array();
public $labelStatusShort = array();
// Multicurrency
/**
* @var int ID
*/
public $fk_multicurrency;
public $multicurrency_code;
public $multicurrency_tx;
public $multicurrency_total_ht;
public $multicurrency_total_tva;
public $multicurrency_total_ttc;
/**
* 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')

View file

@ -2804,20 +2804,24 @@ if ($action == 'create' && $usercancreate) {
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
$object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
}
// Amount Local Taxes
if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
print '<tr>';
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
// Amount Local Taxes
if ($mysoc->localtax2_assuj == "1" || $object->total_localtax2 != 0) {
print '<tr>';
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
$object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
}
print '<tr>';

View file

@ -253,20 +253,6 @@ class Commande extends CommonOrder
*/
public $lines = array();
// Multicurrency
/**
* @var int Currency ID
*/
public $fk_multicurrency;
/**
* @var string multicurrency code
*/
public $multicurrency_code;
public $multicurrency_tx;
public $multicurrency_total_ht;
public $multicurrency_total_tva;
public $multicurrency_total_ttc;
//! key of module source when order generated from a dedicated module ('cashdesk', 'takepos', ...)
public $module_source;

View file

@ -5014,21 +5014,24 @@ if ($action == 'create') {
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax1, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
$object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_localtax1, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) {
print '<tr>';
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
}
}
if (($mysoc->localtax2_assuj == "1" && $mysoc->useLocalTax(2)) || $object->total_localtax2 != 0) {
print '<tr>';
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
print '<td class="nowrap amountcard right">' . price($sign * $object->total_localtax2, 0, $langs, 0, -1, -1, $conf->currency) . '</td>';
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
$object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
print '<td class="nowrap amountcard right">' . price($sign * $object->multicurrency_total_localtax2, 0, $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
}
print '</tr>';
}
// Add the revenue stamp
if ($selleruserevenustamp) {

View file

@ -194,6 +194,7 @@ class Facture extends CommonInvoice
public $date_pointoftax;
/**
* @var int Situation cycle reference number
*/

View file

@ -504,6 +504,16 @@ abstract class CommonObject
*/
public $multicurrency_total_ttc;
/**
* @var float Multicurrency total localta1
*/
public $multicurrency_total_localtax1; // not in database
/**
* @var float Multicurrency total localtax2
*/
public $multicurrency_total_localtax2; // not in database
/**
* @var string
* @see SetDocModel()

View file

@ -857,14 +857,14 @@ function dol_copy($srcfile, $destfile, $newmask = '0', $overwriteifexists = 1, $
/**
* Copy a dir to another dir. This include recursive subdirectories.
*
* @param string $srcfile Source file (a directory)
* @param string $destfile Destination file (a directory)
* @param string $newmask Mask for new file ('0' by default means getDolGlobalString('MAIN_UMASK')). Example: '0666'
* @param int $overwriteifexists Overwrite file if exists (1 by default)
* @param string $srcfile Source file (a directory)
* @param string $destfile Destination file (a directory)
* @param string $newmask Mask for new file ('0' by default means getDolGlobalString('MAIN_UMASK')). Example: '0666'
* @param int $overwriteifexists Overwrite file if exists (1 by default)
* @param array<string,string> $arrayreplacement Array to use to replace filenames with another one during the copy (works only on file names, not on directory names).
* @param int $excludesubdir 0=Do not exclude subdirectories, 1=Exclude subdirectories, 2=Exclude subdirectories if name is not a 2 chars (used for country codes subdirectories).
* @param string[] $excludefileext Exclude some file extensions
* @return int Return integer <0 if error, 0 if nothing done (all files already exists and overwriteifexists=0), >0 if OK
* @param int $excludesubdir 0=Do not exclude subdirectories, 1=Exclude subdirectories, 2=Exclude subdirectories if name is not a 2 chars (used for country codes subdirectories).
* @param string[] $excludefileext Exclude some file extensions
* @return int Return integer <0 if error, 0 if nothing done (all files already exists and overwriteifexists=0), >0 if OK
* @see dol_copy()
*/
function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement = null, $excludesubdir = 0, $excludefileext = null)
@ -878,6 +878,7 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep
}
$destexists = dol_is_dir($destfile);
//if (! $overwriteifexists && $destexists) return 0; // The overwriteifexists is for files only, so propagated to dol_copy only.
if (!$destexists) {
@ -888,7 +889,13 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep
$dirmaskdec = octdec(getDolGlobalString('MAIN_UMASK'));
}
$dirmaskdec |= octdec('0200'); // Set w bit required to be able to create content for recursive subdirs files
dol_mkdir($destfile, '', decoct($dirmaskdec));
$result = dol_mkdir($destfile, '', decoct($dirmaskdec));
if (!dol_is_dir($destfile)) {
// The output directory does not exists and we failed to create it. So we stop here.
return -1;
}
}
$ossrcfile = dol_osencode($srcfile);

View file

@ -4618,7 +4618,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0, $srco
if (empty($srconly) && in_array($pictowithouttext, array(
'1downarrow', '1uparrow', '1leftarrow', '1rightarrow', '1uparrow_selected', '1downarrow_selected', '1leftarrow_selected', '1rightarrow_selected',
'accountancy', 'accounting_account', 'account', 'accountline', 'action', 'add', 'address', 'ai', 'angle-double-down', 'angle-double-up', 'asset',
'bank_account', 'barcode', 'bank', 'bell', 'bill', 'billa', 'billr', 'billd', 'birthday-cake', 'bookmark', 'bom', 'briefcase-medical', 'bug', 'building',
'bank_account', 'barcode', 'bank', 'bell', 'bill', 'billa', 'billr', 'billd', 'birthday-cake', 'bom', 'bookcal', 'bookmark', 'briefcase-medical', 'bug', 'building',
'card', 'calendarlist', 'calendar', 'calendarmonth', 'calendarweek', 'calendarday', 'calendarperuser', 'calendarpertype',
'cash-register', 'category', 'chart', 'check', 'clock', 'clone', 'close_title', 'code', 'cog', 'collab', 'company', 'contact', 'country', 'contract', 'conversation', 'cron', 'cross', 'cubes',
'check-circle', 'check-square', 'currency', 'multicurrency',
@ -4666,6 +4666,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0, $srco
'asset' => 'money-check-alt', 'autofill' => 'fill',
'bank_account' => 'university',
'bill' => 'file-invoice-dollar', 'billa' => 'file-excel', 'billr' => 'file-invoice-dollar', 'billd' => 'file-medical',
'bookcal' => 'calendar-check',
'supplier_invoice' => 'file-invoice-dollar', 'supplier_invoicea' => 'file-excel', 'supplier_invoicer' => 'file-invoice-dollar', 'supplier_invoiced' => 'file-medical',
'bom' => 'shapes',
'card' => 'address-card', 'chart' => 'chart-line', 'company' => 'building', 'contact' => 'address-book', 'contract' => 'suitcase', 'collab' => 'people-arrows', 'conversation' => 'comments', 'country' => 'globe-americas', 'cron' => 'business-time', 'cross' => 'times',
@ -4764,6 +4765,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = 0, $srco
'action' => 'infobox-action', 'account' => 'infobox-bank_account', 'accounting_account' => 'infobox-bank_account', 'accountline' => 'infobox-bank_account', 'accountancy' => 'infobox-bank_account', 'asset' => 'infobox-bank_account',
'bank_account' => 'infobox-bank_account',
'bill' => 'infobox-commande', 'billa' => 'infobox-commande', 'billr' => 'infobox-commande', 'billd' => 'infobox-commande',
'bookcal' => 'infobox-action',
'margin' => 'infobox-bank_account', 'conferenceorbooth' => 'infobox-project',
'cash-register' => 'infobox-bank_account', 'contract' => 'infobox-contrat', 'check' => 'font-status4', 'collab' => 'infobox-action', 'conversation' => 'infobox-contrat',
'donation' => 'infobox-commande', 'dolly' => 'infobox-commande', 'dollyrevert' => 'flip infobox-order_supplier',
@ -7424,7 +7426,7 @@ function dol_mkdir($dir, $dataroot = '', $newmask = '')
}
$dirmaskdec |= octdec('0111'); // Set x bit required for directories
if (!@mkdir($ccdir_osencoded, $dirmaskdec)) {
// Si le is_dir a renvoye une fausse info, alors on passe ici.
// If the is_dir has returned a false information, we arrive here
dol_syslog("functions.lib::dol_mkdir: Fails to create directory '".$ccdir."' or directory already exists.", LOG_WARNING);
$nberr++;
} else {
@ -8322,7 +8324,7 @@ function getCommonSubstitutionArray($outputlangs, $onlykey = 0, $exclude = null,
'__USER_SIGNATURE__' => (string) (($usersignature && !getDolGlobalString('MAIN_MAIL_DO_NOT_USE_SIGN')) ? ($onlykey == 2 ? dol_trunc(dol_string_nohtmltag($usersignature), 30) : $usersignature) : '')
));
if (is_object($user)) {
if (is_object($user) && ($user instanceof User)) {
$substitutionarray = array_merge($substitutionarray, array(
'__USER_ID__' => (string) $user->id,
'__USER_LOGIN__' => (string) $user->login,

View file

@ -839,7 +839,8 @@ function deletePropsAndPermsFromDoc($file, $objectname)
/**
* Search a string and return all lines needed from file
* Search a string and return all lines needed from file. Does not include line $start nor $end
*
* @param string $file file for searching
* @param string $start start line if exist
* @param string $end end line if exist
@ -953,106 +954,136 @@ function writePermsInAsciiDoc($file, $destfile)
/**
* Add Object in ModuleApi File
* @param string $file path of file
* @param array $objects array of objects in the module
* @param string $modulename name of module
* @return int 1 if OK, -1 if KO
*
* @param string $srcfile Source file to use as example
* @param string $file Path of modified file
* @param array $objects Array of objects in the module
* @param string $modulename Name of module
* @return int Return 1 if OK, -1 if KO
*/
function addObjectsToApiFile($file, $objects, $modulename)
function addObjectsToApiFile($srcfile, $file, $objects, $modulename)
{
global $langs, $user;
if (!file_exists($file)) {
return -1;
}
$content = file($file);
$includeClass = "dol_include_once('/mymodule/class/myobject.class.php');";
$props = "public \$myobject;";
$varcomented = "@var MyObject \$myobject {@type MyObject}";
$constructObj = "\$this->myobject = new MyObject(\$this->db);";
$now = dol_now();
$content = file($file); // $content is an array
$includeClass = "dol_include_once\(\'\/\w+\/class\/\w+\.class\.php\'\);";
$props = 'public\s+\$\w+;';
$varcommented = '@var\s+\w+\s+\$\w+\s+{@type\s+\w+}';
$constructObj = '\$this->\w+\s+=\s+new\s+\w+\(\$this->db\);';
// add properties and declare them in constructor
foreach ($content as $lineNumber => &$lineContent) {
if (strpos($lineContent, $varcomented) !== false) {
if (preg_match('/'.$varcommented.'/', $lineContent)) {
$lineContent = '';
foreach ($objects as $object) {
$lineContent .= "\t * @var ".$object." \$".strtolower($object)." {@type ".$object."}". PHP_EOL;
foreach ($objects as $objectname) {
$lineContent .= "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}". PHP_EOL;
}
//var_dump($lineContent);exit;
}
if (strpos($lineContent, $props) !== false) {
} elseif (preg_match('/'.$props.'/', $lineContent)) {
$lineContent = '';
foreach ($objects as $object) {
$lineContent .= "\tpublic \$".strtolower($object).";". PHP_EOL;
foreach ($objects as $objectname) {
$lineContent .= "\tpublic \$".strtolower($objectname).";". PHP_EOL;
}
}
if (strpos($lineContent, $constructObj) !== false) {
} elseif (preg_match('/'.$constructObj.'/', $lineContent)) {
$lineContent = '';
foreach ($objects as $object) {
$lineContent .= "\t\t\$this->".strtolower($object)." = new ".$object."(\$this->db);". PHP_EOL;
foreach ($objects as $objectname) {
$lineContent .= "\t\t\$this->".strtolower($objectname)." = new ".$objectname."(\$this->db);". PHP_EOL;
}
}
if (strpos($lineContent, $includeClass) !== false) {
} elseif (preg_match('/'.$includeClass.'/', $lineContent)) {
$lineContent = '';
foreach ($objects as $object) {
$lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($object).".class.php');". PHP_EOL;
foreach ($objects as $objectname) {
$lineContent .= "dol_include_once('/".strtolower($modulename)."/class/".strtolower($objectname).".class.php');". PHP_EOL;
}
}
}
$allContent = implode("", $content);
file_put_contents($file, $allContent);
//add methods for each object
$allContent = getFromFile($file, '/*begin methods CRUD*/', '/*end methods CRUD*/');
foreach ($objects as $object) {
$contentReplaced = str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent);
dolReplaceInFile($file, array('/*end methods CRUD*/' => '/*CRUD FOR '.strtoupper($object).'*/'."\n".$contentReplaced."\n\t".'/*END CRUD FOR '.strtoupper($object).'*/'."\n\t".'/*end methods CRUD*/'));
// Add methods for each object
$allContent = getFromFile($srcfile, '/* BEGIN MODULEBUILDER API MYOBJECT */', '/* END MODULEBUILDER API MYOBJECT */');
foreach ($objects as $objectname) {
$arrayreplacement = array(
'mymodule' => strtolower($modulename),
'MyModule' => $modulename,
'MYMODULE' => strtoupper($modulename),
'My module' => $modulename,
'my module' => $modulename,
'Mon module' => $modulename,
'mon module' => $modulename,
'htdocs/modulebuilder/template' => strtolower($modulename),
'myobject' => strtolower($objectname),
'MyObject' => $objectname,
'MYOBJECT' => strtoupper($objectname),
'---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
);
$contentReplaced = make_substitutions($allContent, $arrayreplacement, null);
//$contentReplaced = str_replace(["myobject","MyObject"], [strtolower($object),$object], $allContent);
dolReplaceInFile($file, array(
'/* BEGIN MODULEBUILDER API MYOBJECT */' => '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */'.$contentReplaced."\t".'/* END MODULEBUILDER API '.strtoupper($objectname).' */'."\n\n\n\t".'/* BEGIN MODULEBUILDER API MYOBJECT */'
));
}
dolReplaceInFile($file, array($allContent => '','MyModule' => ucfirst($modulename)));
// Remove the block $allContent found in src file
// TODO Replace with a replacement of all text including into /* BEGIN MODULEBUILDER API MYOBJECT */ and /* END MODULEBUILDER API MYOBJECT */
dolReplaceInFile($file, array($allContent => ''));
return 1;
}
/**
* Remove Object variables and methods from API_Module File
* @param string $file file api module
* @param string $objectname name of object want to remove
* @param string $modulename name of module
* @return int 1 if OK, -1 if KO
* Remove Object variables and methods from API_Module File
*
* @param string $file File api module
* @param array $objects Array of objects in the module
* @param string $objectname Name of object want to remove
* @return int 1 if OK, -1 if KO
*/
function removeObjectFromApiFile($file, $objectname, $modulename)
function removeObjectFromApiFile($file, $objects, $objectname)
{
$begin = '/*CRUD FOR '.strtoupper($objectname).'*/';
$end = '/*END CRUD FOR '.strtoupper($objectname).'*/';
$includeClass = "dol_include_once('/".strtolower($modulename)."/class/".strtolower($objectname).".class.php');";
$varcomentedDel = "\t * @var ".$objectname." \$".strtolower($objectname)." {@type ".$objectname."}";
$propsDel = "\tpublic \$".strtolower($objectname).";";
$constructObjDel = "\t\t\$this->".strtolower($objectname)." = new ".$objectname."(\$this->db);";
if (!file_exists($file)) {
return -1;
}
$content = file($file);
// for delete property and the initialization from the construct
$content = file($file); // $content is an array
$includeClass = "dol_include_once\(\'\/\w+\/class\/".strtolower($objectname)."\.class\.php\'\);";
$props = 'public\s+\$'.strtolower($objectname);
$varcommented = '@var\s+\w+\s+\$'.strtolower($objectname).'\s+{@type\s+\w+}';
$constructObj = '\$this->'.strtolower($objectname).'\s+=\s+new\s+\w+\(\$this->db\);';
// add properties and declare them in constructor
foreach ($content as $lineNumber => &$lineContent) {
if (strpos($lineContent, $includeClass) !== false) {
if (preg_match('/'.$varcommented.'/i', $lineContent)) {
$lineContent = '';
}
if (strpos($lineContent, $varcomentedDel) !== false) {
} elseif (preg_match('/'.$props.'/i', $lineContent)) {
$lineContent = '';
}
if (strpos($lineContent, $propsDel) !== false) {
} elseif (preg_match('/'.$constructObj.'/i', $lineContent)) {
$lineContent = '';
}
if (strpos($lineContent, $constructObjDel) !== false) {
} elseif (preg_match('/'.$includeClass.'/i', $lineContent)) {
$lineContent = '';
}
}
$allContent = implode("", $content);
file_put_contents($file, $allContent);
// for delete methods of object
$begin = '/* BEGIN MODULEBUILDER API '.strtoupper($objectname).' */';
$end = '/* END MODULEBUILDER API '.strtoupper($objectname).' */';
$allContent = getFromFile($file, $begin, $end);
$check = dolReplaceInFile($file, array($allContent => ''));
if ($check) {
dolReplaceInFile($file, array($begin => '', $end => ''));
}
return 1;
}

View file

@ -453,7 +453,7 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
$err += $this->insert_tabs();
}
// Insert activation of module's parts
// Insert activation of module's parts. Copy website templates into doctemplates.
if (!$err) {
$err += $this->insert_module_parts();
}
@ -2310,6 +2310,15 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
$this->errors[] = ($errormsg ? $errormsg : $langs->trans('ErrorFailToCreateZip', $dest));
}
}
// Copy also the preview website_xxx.jpg file
$docs = dol_dir_list($srcroot, 'files', 0, 'website_.*\.jpg$');
foreach ($docs as $cursorfile) {
$src = $srcroot.'/'.$cursorfile['name'];
$dest = DOL_DATA_ROOT.'/doctemplates/websites/'.$cursorfile['name'];
dol_copy($src, $dest);
}
}
$entity = $conf->entity; // Reset the current entity

View file

@ -947,8 +947,10 @@ class pdf_einstein extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -977,8 +979,10 @@ class pdf_einstein extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1038,8 +1042,11 @@ class pdf_einstein extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1071,8 +1078,10 @@ class pdf_einstein extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}

View file

@ -1149,8 +1149,10 @@ class pdf_eratosthene extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1179,8 +1181,10 @@ class pdf_eratosthene extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1240,8 +1244,11 @@ class pdf_eratosthene extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1273,8 +1280,10 @@ class pdf_eratosthene extends ModelePDFCommandes
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}

View file

@ -1397,8 +1397,6 @@ class pdf_crabe extends ModelePDFFactures
if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL') && $tvaisnull) {
// Nothing to do
} else {
// FIXME amount of vat not supported with multicurrency
//Local tax 1 before VAT
//if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
//{
@ -1425,8 +1423,10 @@ class pdf_crabe extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1456,8 +1456,10 @@ class pdf_crabe extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1517,8 +1519,11 @@ class pdf_crabe extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1547,8 +1552,10 @@ class pdf_crabe extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
//}

View file

@ -1658,8 +1658,6 @@ class pdf_sponge extends ModelePDFFactures
if (getDolGlobalString('MAIN_GENERATE_DOCUMENTS_WITHOUT_VAT_IFNULL') && $tvaisnull) {
// Nothing to do
} else {
// FIXME amount of vat not supported with multicurrency
//Local tax 1 before VAT
//if (!empty($conf->global->FACTURE_LOCAL_TAX1_OPTION) && $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on')
//{
@ -1686,8 +1684,10 @@ class pdf_sponge extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1717,8 +1717,10 @@ class pdf_sponge extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1802,8 +1804,11 @@ class pdf_sponge extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1835,8 +1840,10 @@ class pdf_sponge extends ModelePDFFactures
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}

View file

@ -69,7 +69,7 @@ class modAi extends DolibarrModules
$this->descriptionlong = "AiDescriptionLong";
// Possible values for version are: 'development', 'experimental', 'dolibarr', 'dolibarr_deprecated' or a version string like 'x.y.z'
$this->version = 'development';
$this->version = 'experimental';
// Key used in llx_const table to save module status enabled/disabled (where BOOKCAL is value of property name of module in uppercase)
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
@ -78,7 +78,7 @@ class modAi extends DolibarrModules
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
// To use a supported fa-xxx css style of font awesome, use this->picto='xxx'
$this->picto = 'fa-microchip';
$this->picto = 'fa-magic';
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
$this->module_parts = array(

View file

@ -78,7 +78,7 @@ class modBookCal extends DolibarrModules
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
// To use a supported fa-xxx css style of font awesome, use this->picto='xxx'
$this->picto = 'fa-calendar-check';
$this->picto = 'bookcal';
// Define some features supported by module (triggers, login, substitutions, menus, css, etc...)
$this->module_parts = array(

View file

@ -1132,8 +1132,10 @@ class pdf_azur extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1150,8 +1152,6 @@ class pdf_azur extends ModelePDFPropales
if ($tvakey != 0) { // On affiche pas taux 0
//$this->atleastoneratenotnull++;
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
@ -1164,8 +1164,10 @@ class pdf_azur extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1224,8 +1226,11 @@ class pdf_azur extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1256,8 +1261,10 @@ class pdf_azur extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}

View file

@ -1232,8 +1232,10 @@ class pdf_cyan extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1250,8 +1252,6 @@ class pdf_cyan extends ModelePDFPropales
if ($tvakey != 0) { // On affiche pas taux 0
//$this->atleastoneratenotnull++;
$index++;
$pdf->SetXY($col1x, $tab2_top + $tab2_hl * $index);
@ -1265,8 +1265,10 @@ class pdf_cyan extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1320,8 +1322,11 @@ class pdf_cyan extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}
@ -1353,8 +1358,10 @@ class pdf_cyan extends ModelePDFPropales
$totalvat .= vatrate(abs($tvakey), 1).$tvacompl;
$pdf->MultiCell($col2x - $col1x, $tab2_hl, $totalvat, 0, 'L', 1);
$total_localtax = ((isModEnabled("multicurrency") && isset($object->multicurrency_tx) && $object->multicurrency_tx != 1) ? price2num($tvaval * $object->multicurrency_tx, 'MT') : $tvaval);
$pdf->SetXY($col2x, $tab2_top + $tab2_hl * $index);
$pdf->MultiCell($largcol2, $tab2_hl, price($tvaval, 0, $outputlangs), 0, 'R', 1);
$pdf->MultiCell($largcol2, $tab2_hl, price($total_localtax, 0, $outputlangs), 0, 'R', 1);
}
}
}

View file

@ -165,7 +165,7 @@ BadValueForType=Bad value for type %s
DefinePropertiesFromExistingTable=Define the fields/properties from an existing table
DefinePropertiesFromExistingTableDesc=If a table in the database (for the object to create) already exists, you can use it to define the properties of the object.
DefinePropertiesFromExistingTableDesc2=Keep empty if the table does not exist yet. The code generator will use different kinds of fields to build an example of table that you can edit later.
GeneratePermissions=I want to manage permissions on this object
GeneratePermissions=I want to manage permissions on this object
GeneratePermissionsHelp=If you check this, some code will be added to manage permissions to read, write and delete record of the objects
PermissionDeletedSuccesfuly=Permission has been successfully removed
PermissionUpdatedSuccesfuly=Permission has been successfully updated
@ -173,6 +173,7 @@ PermissionAddedSuccesfuly=Permission has been successfully added
MenuDeletedSuccessfuly=Menu has been successfully deleted
MenuAddedSuccessfuly=Menu has been successfully added
MenuUpdatedSuccessfuly=Menu has been successfully updated
AddAPIsForThisObject=Add APIs for this object
ApiObjectDeleted=API for object %s has been successfully deleted
CRUDRead=Read
CRUDCreateWrite=Create or Update
@ -181,8 +182,8 @@ DictionariesCreated=Dictionary <b>%s</b> created successfully
DictionaryDeleted=Dictionary <b>%s</b> removed successfully
PropertyModuleUpdated=Property <b>%s</b> has been update successfully
InfoForApiFile=* When you generate file for the first time then all methods will be created <strong>for each object.</strong><br>* When you click in <strong>remove</strong> you just remove all methods for the <strong>selected object</strong>.
SetupFile=Page for module setup
SetupFile=Page for module setup
EmailingSelectors=Emails selectors
EmailingSelectorDesc=You can generate and edit here the class files to provide new email target selectors for the mass emailing module
EmailingSelectorFile=Emails selector file
NoEmailingSelector=No emails selector file
NoEmailingSelector=No emails selector file

View file

@ -467,13 +467,13 @@ if ($dirins && in_array($action, array('initapi', 'initphpunit', 'initpagecontac
'---Put here your own copyright and developer email---' => dol_print_date($now, '%Y').' '.$user->getFullName($langs).($user->email ? ' <'.$user->email.'>' : '')
);
if (count($objects) > 1) {
addObjectsToApiFile($destfile, $objects, $modulename);
if ($action == 'initapi') {
if (count($objects) >= 1) {
addObjectsToApiFile($srcfile, $destfile, $objects, $modulename);
}
} else {
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
dolReplaceInFile($destfile, $arrayreplacement);
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
dolReplaceInFile($destfile, array('/*begin methods CRUD*/' => '/*begin methods CRUD*/'."\n\t".'/*CRUD FOR '.strtoupper($objectname).'*/', '/*end methods CRUD*/' => '/*END CRUD FOR '.strtoupper($objectname).'*/'."\n\t".'/*end methods CRUD*/'));
}
if ($varnametoupdate) {
@ -952,20 +952,31 @@ if ($dirins && $action == 'confirm_removefile' && !empty($module)) {
$filetodelete = $dirins.'/'.$relativefilename;
$dirtodelete = $dirins.'/'.$dirnametodelete;
//check when we want delete api_file
// Get list of existing objects
$objects = dolGetListOfObjectClasses($destdir);
$keyofobjecttodelete = array_search($objectname, $objects);
if ($keyofobjecttodelete !== false) {
unset($objects[$keyofobjecttodelete]);
}
// Delete or modify the file
if (strpos($relativefilename, 'api') !== false) {
$file_api = $destdir.'/class/api_'.strtolower($module).'.class.php';
$removeFile = removeObjectFromApiFile($file_api, $objectname, $module);
$var = getFromFile($file_api, '/*begin methods CRUD*/', '/*end methods CRUD*/');
if (str_word_count($var) == 0) {
$removeFile = removeObjectFromApiFile($file_api, $objects, $objectname);
if (count($objects) == 0) {
$result = dol_delete_file($filetodelete);
}
if ($removeFile) {
setEventMessages($langs->trans("ApiObjectDeleted"), null);
}
} else {
$result = dol_delete_file($filetodelete);
}
if (!$result) {
setEventMessages($langs->trans("ErrorFailToDeleteFile", basename($filetodelete)), null, 'errors');
} else {
@ -4209,7 +4220,7 @@ if ($module == 'initmodule') {
print '<a href="'.DOL_URL_ROOT.'/api/index.php/explorer/" target="apiexplorer">'.$langs->trans("ApiExplorer").'</a>';
}
} else {
print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initapi&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto('AddAPIsForThisObject', 'generate', 'class="paddingleft"').'</a>';
print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initapi&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto($langs->trans('AddAPIsForThisObject'), 'generate', 'class="paddingleft"').'</a>';
}
} else {
print '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?tab='.urlencode($tab).'&tabobj='.$tabobj.'&module='.$module.($forceddirread ? '@'.$dirread : '').'&action=initapi&token='.newToken().'&format=php&file='.urlencode($pathtoapi).'">'.img_picto('Generate', 'generate', 'class="paddingleft"').'</a>';

View file

@ -83,7 +83,7 @@ $backtopage = GETPOST('backtopage', 'alpha');
$form = new Form($db);
$help_url = '';
$title = "MyModuleAbout";
$title = "MyModuleSetup";
llxHeader('', $langs->trans($title), $help_url, '', 0, 0, '', '', '', 'mod-mymodule page-admin_about');

View file

@ -12,7 +12,7 @@
* Copyright (C) 2014 Henry Florian <florian.henry@open-concept.pro>
* Copyright (C) 2014-2016 Philippe Grand <philippe.grand@atoo-net.com>
* Copyright (C) 2014 Ion agorria <ion@agorria.com>
* Copyright (C) 2016-2018 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2016-2024 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2017 Gustavo Novaro
* Copyright (C) 2019-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
@ -1362,8 +1362,8 @@ class Product extends CommonObject
if (!$this->hasbatch() && $this->oldcopy->hasbatch()) {
// Selection of all product stock movements that contains batchs
$sql = 'SELECT pb.qty, pb.fk_entrepot, pb.batch FROM '.MAIN_DB_PREFIX.'product_batch as pb';
$sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'product_stock as ps ON (ps.rowid = batch.fk_product_stock)';
$sql = 'SELECT pb.qty, ps.fk_entrepot, pb.batch FROM '.MAIN_DB_PREFIX.'product_batch as pb';
$sql .= ' INNER JOIN '.MAIN_DB_PREFIX.'product_stock as ps ON (ps.rowid = pb.fk_product_stock)';
$sql .= ' WHERE ps.fk_product = '.(int) $this->id;
$resql = $this->db->query($sql);

View file

@ -1,7 +1,8 @@
<?php
/* Copyright (C) 2007-2023 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2013-2014 Cedric GROSS <c.gross@kreiz-it.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Ferran Marcet <fmarcet@2byte.es>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -522,7 +523,7 @@ class Productbatch extends CommonObject
$tmp->import_key = $obj->import_key;
if (getDolGlobalString('SHIPPING_DISPLAY_STOCK_ENTRY_DATE')) {
$tmp->context['stock_date_entry'] = $obj->date_entree;
$tmp->context['stock_entry_date'] = $dbs->jdate($obj->date_entree);
}
if ($fk_product > 0) {

View file

@ -1075,15 +1075,16 @@ class Website extends CommonObject
$i++;
}
$line = '-- File generated by Dolibarr '.DOL_VERSION.' --;'."\n";
$line .= "\n";
fwrite($fp, $line);
foreach ($listofpages as $pageid => $objectpageold) {
$oldpageid = $objectpageold->id;
$allaliases = $objectpageold->pageurl;
$allaliases .= ($objectpageold->aliasalt ? ','.$objectpageold->aliasalt : '');
$line = '-- File generated by Dolibarr '.DOL_VERSION.' -- '.dol_print_date(dol_now('gmt'), 'standard', 'gmt').' UTC --;'."\n";
$line .= "\n";
if (!getDolGlobalInt('WEBSITE_EXPORT_KEEP_FILES_OF_PAGES')) { // We don't need to keep the PHP files of pages and aliases (they are regenerated at import) so we remove them. You can ask to keep them in the export
// Delete the pageX.tpl.php page
dol_delete_file($conf->website->dir_temp.'/'.$website->ref.'/containers/page'.$objectpageold->id.'.tpl.php', 0, 0, 0, null, false, 0);
@ -1098,13 +1099,12 @@ class Website extends CommonObject
}
// This comment syntax is important, it is parsed by import to get information on page ID and all aliases to regenerate
$line .= '-- Page ID '.$objectpageold->newid.'__+MAX_llx_website_page__ - Aliases '.$allaliases.' --;'; // newid start at 1, 2...
$line = '-- Page ID '.$objectpageold->newid.'__+MAX_llx_website_page__ - Aliases '.$allaliases.' --;'; // newid start at 1, 2...
$line .= "\n";
fwrite($fp, $line);
// Warning: We must keep llx_ here. It is a generic SQL.
$line = 'INSERT INTO llx_website_page(rowid, fk_page, fk_website, pageurl, aliasalt, title, description, lang, image, keywords, status, date_creation, tms, import_key, grabbed_from, type_container, htmlheader, content, author_alias, allowed_in_frames)';
$line .= " VALUES(";
$line .= $objectpageold->newid."__+MAX_llx_website_page__, ";
$line .= ($objectpageold->newfk_page ? $this->db->escape($objectpageold->newfk_page)."__+MAX_llx_website_page__" : "null").", ";
@ -1170,7 +1170,7 @@ class Website extends CommonObject
fwrite($fp, $line);
}
$line .= "\n";
fwrite($fp, "\n");
}
$line = "\n-- For Dolibarr v14+ --;\n";
@ -1180,6 +1180,7 @@ class Website extends CommonObject
fwrite($fp, $line);
fclose($fp);
dolChmod($filesql);
// Build zip file
@ -1244,7 +1245,8 @@ class Website extends CommonObject
$arrayreplacement['__LOGO_MINI_KEY__'] = $this->db->escape($mysoc->logo_mini);
$arrayreplacement['__LOGO_KEY__'] = $this->db->escape($mysoc->logo);
// Copy containers
// Copy containers directory
dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/containers', $conf->website->dir_output.'/'.$object->ref, 0, 1); // Overwrite if exists
// Make replacement into css and htmlheader file
@ -1262,8 +1264,17 @@ class Website extends CommonObject
$error++;
}
dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/image/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/image/'.$object->ref, 0, 1); // Medias can be shared, do not overwrite if exists
dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/js/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/js/'.$object->ref, 0, 1); // Medias can be shared, do not overwrite if exists
$result = dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/image/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/image/'.$object->ref, 0, 1);
if ($result < 0) {
$this->errors[] = 'Failed to copy files into '.$conf->website->dir_output.'/'.$object->ref.'/medias/image/'.$object->ref.'.';
return -5;
}
$result = dolCopyDir($conf->website->dir_temp.'/'.$object->ref.'/medias/js/websitekey', $conf->website->dir_output.'/'.$object->ref.'/medias/js/'.$object->ref, 0, 1);
if ($result < 0) {
$this->errors[] = 'Failed to copy files into '.$conf->website->dir_output.'/'.$object->ref.'/medias/js/'.$object->ref.'.';
return -5;
}
$sqlfile = $conf->website->dir_temp."/".$object->ref.'/website_pages.sql';
@ -1288,7 +1299,7 @@ class Website extends CommonObject
$objectpagestatic = new WebsitePage($this->db);
// Make replacement of IDs
// Regenerate the php files for pages
$fp = fopen($sqlfile, "r");
if ($fp) {
while (!feof($fp)) {
@ -1296,18 +1307,30 @@ class Website extends CommonObject
// Warning fgets with second parameter that is null or 0 hang.
$buf = fgets($fp, 65000);
$newid = 0;
// Scan the line
if (preg_match('/^-- Page ID (\d+)\s[^\s]+\s(\d+).*Aliases\s(.*)\s--;/i', $buf, $reg)) {
// Example of line: "-- Page ID 179 -> 1__+MAX_llx_website_page__ - Aliases about-us --;"
$oldid = $reg[1];
$newid = ($reg[2] + $maxrowid);
$aliasesarray = explode(',', $reg[3]);
dol_syslog("Found ID ".$oldid." to replace with ID ".$newid." and shortcut aliases to create: ".$reg[3]);
dol_syslog("In sql source file, we have the page ID ".$oldid." to replace with the new ID ".$newid.", and we must create the shortcut aliases: ".$reg[3]);
dol_move($conf->website->dir_output.'/'.$object->ref.'/page'.$oldid.'.tpl.php', $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php', 0, 1, 0, 0);
//dol_move($conf->website->dir_output.'/'.$object->ref.'/page'.$oldid.'.tpl.php', $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php', 0, 1, 0, 0);
} elseif (preg_match('/^-- Page ID (\d+).*Aliases\s(.*)\s--;/i', $buf, $reg)) {
// Example of line: "-- Page ID 1__+MAX_llx_website_page__ - Aliases about-us --;"
$newid = ($reg[1] + $maxrowid);
$aliasesarray = explode(',', $reg[2]);
dol_syslog("In sql source file, we have the page with the new ID ".$newid.", and we must create the shortcut aliases: ".$reg[3]);
}
if ($newid) {
$objectpagestatic->fetch($newid);
// The move is not enough, so we regenerate pageX.tpl.php
// We regenerate the pageX.tpl.php
$filetpl = $conf->website->dir_output.'/'.$object->ref.'/page'.$newid.'.tpl.php';
$result = dolSavePageContent($filetpl, $object, $objectpagestatic);
if (!$result) {
@ -1346,7 +1369,7 @@ class Website extends CommonObject
}
}
// Regenerate index page to point to the new index page
// Regenerate the index.php page to point to the new index page
$pathofwebsite = $conf->website->dir_output.'/'.$object->ref;
dolSaveIndexPage($pathofwebsite, $pathofwebsite.'/index.php', $pathofwebsite.'/page'.$object->fk_default_home.'.tpl.php', $pathofwebsite.'/wrapper.php', $object);
@ -1684,173 +1707,20 @@ class Website extends CommonObject
// Export on target sources
$resultarray = dol_uncompress($pathtotmpzip, $destdir);
// Remove the file README and LICENSE from the $destdir (already into the containers directory)
dol_delete_file($destdir.'/README.md');
dol_delete_file($destdir.'/LICENSE');
// Remove non required files (will be re-generated during the import)
dol_delete_file($destdir.'/containers/index.php');
dol_delete_file($destdir.'/containers/master.inc.php');
if (!empty($resultarray)) {
setEventMessages("Error, failed to unzip the export into target dir", null, 'errors');
} else {
setEventMessages("Website content written into ".$destdirrel, null, 'mesgs');
}
/*
$sourcedir = $conf->website->dir_output."/".$website->ref;
// Get array with hash of files (for the last sync)
$fichierEtat = $sourcedir . '/filelist-'.dol_sanitizeFileName($destdir).'.txt';
$etatPrecedent = $this->checkPreviousState($fichierEtat);
// Get list of all source files of the website
$arraySourcedir = dol_dir_list($sourcedir);
// Get list of modified files
$modifications = [];
foreach ($arraySourcedir as $file) {
if (substr($file['name'], -4) === '.old') {
continue;
}
$hashActuel = hash_file('md5', $file['fullname']);
// Check whether the file is new or has been modified
if (!isset($etatPrecedent[$file['name']]) || $etatPrecedent[$file['name']] !== $hashActuel) {
$modifications[] = $file;
}
$etatPrecedent[$file['name']] = $hashActuel; // we store he new hash to record it later on disk.
}
$arraydestdir = dol_dir_list($destdir, "all", 1);
$differences = [];
$names = array_column($arraydestdir, 'name');
$namesSource = array_column($arraySourcedir, 'name');
if (count($modifications) > 1) {
foreach ($modifications as $fichierModifie) {
$nomFichierModifie = $fichierModifie['name'];
if ($nomFichierModifie == basename($fichierEtat)) {
continue;
}
$success = 0;
//check if it is a new file
if ((!preg_match('/^page\d+\.tpl\.php$/', $nomFichierModifie)) && (!in_array($nomFichierModifie, $names))) {
if (file_exists($fichierModifie['fullname']) && dol_is_dir($destdir.'/containers')) {
$cp = dol_copy($fichierModifie['fullname'], $destdir.'/containers/'.$nomFichierModifie, '0664');
if ($cp > 0) {
if (file_exists($destdir.'/containers/'.$nomFichierModifie)) {
$tabnumpage = array();
foreach ($arraydestdir as $fileDest) {
if ($this->extractNumberFromFilename($fileDest['name']) !== -1) {
$tabnumpage[] = $this->extractNumberFromFilename($fileDest['name']);
}
}
$getContentSource = file_get_contents($destdir.'/containers/'.$nomFichierModifie);
$nextpage = max($tabnumpage) + 1;
$chaineModifiee = preg_replace('/page\d+\.tpl\.php/', 'page' . $nextpage . '.tpl.php', $getContentSource);
$write = file_put_contents($destdir.'/containers/'.$nomFichierModifie, $chaineModifiee);
if ($write !== false) {
if (!touch($destdir.'/containers/'."page" . $nextpage . ".tpl.php")) {
setEventMessages("Please check permission to create <b>page" . $nextpage . ".tpl.php</b> in template <b>".$website->name_template."</b>", null, 'errors');
}
$filesFound = '';
foreach ($arraySourcedir as $file) {
if ($file['name'] == $nomFichierModifie) {
$fileContent = file_get_contents($file['fullname']);
$matches = array();
if (preg_match("/page\d+\.tpl\.php/", $fileContent, $matches)) {
$filesFound = $matches[0];
break;
}
}
}
foreach ($arraySourcedir as $file) {
if ($file['name'] == $filesFound) {
if (!is_writable($file['fullname'])) {
dolChmod($file['fullname'], '0664');
}
$diff = $this->showDifferences(file_get_contents($destdir.'/containers/'."page" . $nextpage . ".tpl.php"), file_get_contents($file['fullname']), array($nextpage,$this->extractNumberFromFilename($file['name'])));
if ($diff != -1) {
$replace = $this->replaceLineUsingNum($destdir.'/containers/'."page" . $nextpage . ".tpl.php", $diff);
if ($replace !== false) {
setEventMessages("Copy file <b>page".$nextpage.".tpl.php</b> in template <b>".$this->name_template."</b> with success", null, 'warnings');
}
}
}
}
}
}
$this->saveState($etatPrecedent, $fichierEtat);
setEventMessages("file <b>".$nomFichierModifie."</b> was created in template <b>".$website->name_template."</b>", null, 'warnings');
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref);
exit();
}
} else {
setEventMessages("Error, target dir containers not found", null, 'errors');
$error = 1;
break;
}
}
// Find the corresponding file in the destination folder
if (!$error && in_array($nomFichierModifie, $namesSource)) {
foreach ($arraydestdir as $destFile) {
if ($destFile['name'] == $nomFichierModifie) {
$sourceContent = file_get_contents($fichierModifie['fullname']);
$destContent = file_get_contents($destFile['fullname']);
if ($sourceContent !== $destContent) {
$differences[$nomFichierModifie] = $this->showDifferences($destContent, $sourceContent);
if (count($differences[$nomFichierModifie]) > 0) {
$result = $this->replaceLineUsingNum($destFile['fullname'], $differences[$nomFichierModifie]);
if ($result >= 0) {
setEventMessages("file <b>".$nomFichierModifie."</b> was modified in template <b>".$website->name_template."</b>", null, 'warnings');
} else {
if ($result == -2) {
setEventMessages("No permissions to write into file <b>".$destdirrel.'/'.$nomFichierModifie."</b> from the current website <b>".$website->name_template."</b>", null, 'errors');
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref);
exit();
}
setEventMessages("file ".$nomFichierModifie." was not modified", null, 'errors');
}
}
}
}
if (preg_match('/page(\d+)\.tpl\.php/', $nomFichierModifie)) {
$differences[$nomFichierModifie] = $this->compareFichierModifie($sourcedir, $destdir, $fichierModifie);
if (count($differences[$nomFichierModifie]) > 0) {
$result = $this->replaceLineUsingNum($differences[$nomFichierModifie]['file_destination']['fullname'], $differences[$nomFichierModifie]);
if ($result !== false) {
if ($result == -2) {
setEventMessages("No permissions to write into file <b>".$destdirrel.'/'.$differences[$nomFichierModifie]['file_destination']['name']."</b> from the current website <b>".$website->name_template."</b>", null, 'errors');
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref);
exit();
}
$success++;
}
}
}
}
}
}
if ($success > 0) {
// Save the state file filelist.txt
$this->saveState($etatPrecedent, $fichierEtat);
setEventMessages("file <b>".$differences[$nomFichierModifie]['file_destination']['name']."</b> was modified in template <b>".$website->name_template."</b>", null, 'warnings');
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref);
exit();
}
} else {
setEventMessages("No file has been modified", null, 'errors');
}
// save state file
if (!$error) {
$this->saveState($etatPrecedent, $fichierEtat);
}
*/
header("Location: ".$_SERVER["PHP_SELF"].'?website='.$website->ref);
exit();
}
@ -1918,38 +1788,6 @@ class Website extends CommonObject
return file_put_contents($pathname, serialize($etat));
}
/**
* create file for save state of all files in folder
*
* @param string $sourcedir path of folder
* @return void
*/
/*
public function initFilesStatus($sourcedir)
{
$fichierEtat = $sourcedir . '/filelist-lastwrite-doctemplates.txt';
$etatPrecedent = $this->checkPreviousState($fichierEtat);
// for first save state when create file
if (empty($etatPrecedent)) {
$arraySourcedir = dol_dir_list($sourcedir, "files");
$etatFichiers = [];
foreach ($arraySourcedir as $file) {
// Ignore .old files and the status file itself
if (substr($file['name'], -4) === '.old' || $file['name'] === basename($fichierEtat)) {
continue;
}
$hashActuel = hash_file('md5', $file['fullname']);
$etatFichiers[$file['name']] = $hashActuel;
}
$this->saveState($etatFichiers, $fichierEtat);
}
}
*/
/**
* Compare two files has not same name but same content
* @param string $dossierSource filepath of folder source

View file

@ -1155,7 +1155,17 @@ if ($action == 'addcontainer' && $usercanedit) {
$substitutionarray = array();
$substitutionarray['__WEBSITE_CREATE_BY__'] = $user->getFullName($langs);
// Define id of page the new page is translation of
// Define id of the page the new page is translation of
/*
if ($objectpage->lang == $object->lang) {
// If
$pageidfortranslation = (GETPOSTINT('pageidfortranslation') > 0 ? GETPOSTINT('pageidfortranslation') : 0);
if ($pageidfortranslation > 0) {
// We must update the page $pageidfortranslation to set fk_page = $object->id.
// But what if page $pageidfortranslation is already linked to another ?
}
} else {
*/
$pageidfortranslation = (GETPOSTINT('pageidfortranslation') > 0 ? GETPOSTINT('pageidfortranslation') : 0);
if ($pageidfortranslation > 0) {
// Check if the page we are translation of is already a translation of a source page. if yes, we will use source id instead
@ -1166,6 +1176,7 @@ if ($action == 'addcontainer' && $usercanedit) {
}
}
$objectpage->fk_page = $pageidfortranslation;
//}
$sample = GETPOST('sample', 'alpha');
if (empty($sample)) {
@ -2406,6 +2417,22 @@ if ($usercanedit && (($action == 'updatesource' || $action == 'updatecontent' ||
}
}
if ($action == 'deletelang' && $usercanedit) {
$sql = "UPDATE ".MAIN_DB_PREFIX."website_page SET fk_page = NULL";
$sql .= " WHERE rowid = ".GETPOSTINT('deletelangforid');
//$sql .= " AND fk_page = ".((int) $objectpage->id);
$resql = $db->query($sql);
if (!$resql) {
setEventMessages($db->lasterror(), null, 'errors');
} else {
$objectpage->fk_page = null;
}
$action = 'editmeta';
}
// Export site
if ($action == 'exportsite' && $user->hasRight('website', 'export')) {
$fileofzip = $object->exportWebSite();
@ -4360,7 +4387,9 @@ if ($action == 'editmeta' || $action == 'createcontainer') { // Edit properties
if ($i > 0) {
$tmpstring .= '<br>';
}
$tmpstring .= $tmppage->getNomUrl(1).' ('.$tmppage->lang.')';
$tmpstring .= $tmppage->getNomUrl(1).' '.picto_from_langcode($tmppage->lang).' '.$tmppage->lang;
// Button unlink
$tmpstring .= ' <a class="paddingleft" href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($object->ref).'&pageid='.((int) $objectpage->id).'&action=deletelang&token='.newToken().'&deletelangforid='.((int) $tmppage->id).'">'.img_picto($langs->trans("Remove"), 'unlink').'</a>';
$translatedby++;
$i++;
}
@ -4376,17 +4405,27 @@ if ($action == 'editmeta' || $action == 'createcontainer') { // Edit properties
dol_print_error($db);
}
}
if (empty($translatedby) && ($action == 'editmeta' || $action == 'createcontainer' || $objectpage->fk_page > 0)) {
if ((empty($translatedby) || ($objectpage->lang != $object->lang)) && ($action == 'editmeta' || $action == 'createcontainer' || $objectpage->fk_page > 0)) {
$sourcepage = new WebsitePage($db);
$result = $sourcepage->fetch($objectpage->fk_page);
if ($result == 0) {
// not found, we can reset value to clean database
} elseif ($result > 0) {
$result = 1;
if ($objectpage->fk_page > 0) {
$result = $sourcepage->fetch($objectpage->fk_page);
if ($result == 0) {
// not found, we can reset value to clean database
// TODO
}
}
if ($result >= 0) {
if ($translatedby) {
print '<br>';
}
$translationof = $objectpage->fk_page;
print '<span class="opacitymedium">'.$langs->trans('ThisPageIsTranslationOf').'</span> ';
print $formwebsite->selectContainer($website, 'pageidfortranslation', ($translationof ? $translationof : -1), 1, $action, 'minwidth300', array($objectpage->id));
print $sourcepage->getNomUrl(2).' '.$formwebsite->selectContainer($website, 'pageidfortranslation', ($translationof ? $translationof : -1), 1, $action, 'minwidth300', array($objectpage->id));
if ($translationof > 0 && $sourcepage->lang) {
print $sourcepage->getNomUrl(2).' ('.$sourcepage->lang.')';
print picto_from_langcode($sourcepage->lang).' '.$sourcepage->lang;
// Button unlink
print ' <a class="paddingleft" href="'.$_SERVER["PHP_SELF"].'?website='.urlencode($object->ref).'&pageid='.((int) $objectpage->id).'&action=deletelang&token='.newToken().'&deletelangforid='.((int) $objectpage->id).'">'.img_picto($langs->trans("Remove"), 'unlink').'</a>';
}
}
}