diff --git a/ChangeLog b/ChangeLog index f61ce7ee4b6..a38c7751875 100644 --- a/ChangeLog +++ b/ChangeLog @@ -220,6 +220,8 @@ Dolibarr better: - Fix: [ bug #1832 ] SQL error when adding a product with no price defined to an object - Fix: [ bug #1826 ] Supplier payment types are not translated into fourn/facture/paiement.php - Fix: [ bug #1830 ] Salaries payment only allows checking accounts +- Fix: [ bug #1825 ] External agenda: hide/show checkbox doesn't work +- Fix: [ bug #1790 ] Email form behaves in an unexpected way when pressing Enter key ***** ChangeLog for 3.6.2 compared to 3.6.1 ***** - Fix: fix ErrorBadValueForParamNotAString error message in price customer multiprice. @@ -386,6 +388,7 @@ Fix: [ bug #1752 ] Date filter of margins module, filters since 12H instead of 0 Fix: [ bug #1757 ] Sorting breaks product/service statistics Fix: [ bug #1797 ] Tulip supplier invoice module takes creation date instead of invoice date Fix: [ bug #1792 ] Users are not allowed to see margins module index page when no product view permission is enabled +Fix: [ bug #1846 ] Browser IE11 not detected ***** ChangeLog for 3.5.6 compared to 3.5.5 ***** Fix: Avoid missing class error for fetch_thirdparty method #1973 diff --git a/build/generate_filecheck_xml.php b/build/generate_filecheck_xml.php new file mode 100644 index 00000000000..04970b667f5 --- /dev/null +++ b/build/generate_filecheck_xml.php @@ -0,0 +1,70 @@ +#!/usr/bin/php + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file build/generate_filecheck_xml.php + * \ingroup dev + * \brief This script create a xml checksum file + */ + +$sapi_type = php_sapi_name(); +$script_file = basename(__FILE__); +$path=dirname(__FILE__).'/'; + +// Test if batch mode +if (substr($sapi_type, 0, 3) == 'cgi') { + echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n"; + exit; +} + + +// Main +parse_str($argv[1]); +//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml'; +$outputfile=dirname(__FILE__).'/../htdocs/install/filelist.xml'; +$fp = fopen($outputfile,'w'); +fputs($fp, ''."\n"); +fputs($fp, ''."\n"); +fputs($fp, ''."\n"); +$dir_iterator = new RecursiveDirectoryIterator(dirname(__FILE__).'/../htdocs/'); +$iterator = new RecursiveIteratorIterator($dir_iterator); +// need to ignore document custom etc +$files = new RegexIterator($iterator, '#^(?:[A-Z]:)?(?:/(?!(?:custom|documents|conf|install|nltechno))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); +$dir=''; +$needtoclose=0; +foreach ($files as $file) { + $newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file)); + if ($newdir!=$dir) { + if ($needtoclose) + fputs($fp, ''."\n"); + fputs($fp, ''."\n"); + $dir = $newdir; + $needtoclose=1; + } + if (filetype($file)=="file") { + fputs($fp, ''.md5_file($file).''."\n"); + } +} +fputs($fp, ''."\n"); +fputs($fp, ''."\n"); +fputs($fp, ''."\n"); +fclose($fp); + +print "File ".$outputfile." generated\n"; + +exit(0); diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index c14fb86a104..ecdf371dc6f 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -204,7 +204,10 @@ else { my $NUM_SCRIPT; my $cpt=0; while (! $found) { - printf(" %2d - %-14s (%s)\n",$cpt,"ALL (1..9)","Need ".join(",",values %REQUIREMENTTARGET)); + $cpt=0; + printf(" %2d - %-14s (%s)\n",$cpt,"ALL (1..10)","Need ".join(",",values %REQUIREMENTTARGET)); + $cpt++; + printf(" %2d - %-14s\n",$cpt,"Generate check file"); foreach my $target (@LISTETARGET) { $cpt++; printf(" %2d - %-14s (%s)\n",$cpt,$target,"Need ".$REQUIREMENTTARGET{$target}); @@ -215,7 +218,7 @@ else { printf(" %2d - %-14s (%s)\n",$cpt,"SF (publish)","Need ".join(",",values %REQUIREMENTPUBLISH)); # Ask which target to build - print "Choose one package number or several separated with space (0 - ".$cpt."): "; + print "Choose one target number or several separated with space (0 - ".$cpt."): "; $NUM_SCRIPT=; chomp($NUM_SCRIPT); if ($NUM_SCRIPT !~ /^[0-9\s]+$/) @@ -232,30 +235,30 @@ else { if ($NUM_SCRIPT eq "98") { $CHOOSEDPUBLISH{"ASSO"}=1; } - else - { - if ($NUM_SCRIPT eq "99") { - $CHOOSEDPUBLISH{"SF"}=1; + elsif ($NUM_SCRIPT eq "99") { + $CHOOSEDPUBLISH{"SF"}=1; + } + elsif ($NUM_SCRIPT eq "0") { + $CHOOSEDTARGET{"-CHKSUM"}=1; + foreach my $key (@LISTETARGET) { + if ($key ne 'SNAPSHOT' && $key ne 'ASSO' && $key ne 'SF') { $CHOOSEDTARGET{$key}=1; } } - else { - if ($NUM_SCRIPT eq "0") { - foreach my $key (@LISTETARGET) { - if ($key ne 'SNAPSHOT' && $key ne 'ASSO' && $key ne 'SF') { $CHOOSEDTARGET{$key}=1; } - } - } - else { - foreach my $num (split(/\s+/,$NUM_SCRIPT)) { - $CHOOSEDTARGET{$LISTETARGET[$num-1]}=1; - } - } + } + elsif ($NUM_SCRIPT eq "1") { + $CHOOSEDTARGET{"-CHKSUM"}=1 + } + else { + foreach my $num (split(/\s+/,$NUM_SCRIPT)) { + $CHOOSEDTARGET{$LISTETARGET[$num-2]}=1; } } } + # Test if requirement is ok #-------------------------- $atleastonerpm=0; -foreach my $target (keys %CHOOSEDTARGET) { +foreach my $target (sort keys %CHOOSEDTARGET) { if ($target =~ /RPM/i) { if ($atleastonerpm && ($DESTI eq "$SOURCE/build")) @@ -297,20 +300,32 @@ foreach my $target (keys %CHOOSEDTARGET) { print "\n"; -# Check if there is at least on target to build +# Build xml check file +#----------------------- +if ($CHOOSEDTARGET{'-CHKSUM'}) +{ + print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filecheck_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n"; + $ret=`php $SOURCE/build/generate_filecheck_xml.php release=$MAJOR.$MINOR.$BUILD`; + print $ret."\n"; +} + + +#print join(',',sort keys %CHOOSEDTARGET)."\n"; + +# Check if there is at least one target to build #---------------------------------------------- $nboftargetok=0; $nboftargetneedbuildroot=0; $nbofpublishneedtag=0; -foreach my $target (keys %CHOOSEDTARGET) { +foreach my $target (sort keys %CHOOSEDTARGET) { if ($CHOOSEDTARGET{$target} < 0) { next; } - if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP') + if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') { $nboftargetneedbuildroot++; } $nboftargetok++; } -foreach my $target (keys %CHOOSEDPUBLISH) { +foreach my $target (sort keys %CHOOSEDPUBLISH) { if ($CHOOSEDPUBLISH{$target} < 0) { next; } if ($target eq 'ASSO') { $nbofpublishneedtag++; } if ($target eq 'SF') { $nbofpublishneedtag++; } @@ -474,10 +489,11 @@ if ($nboftargetok) { # Build package for each target #------------------------------ - foreach my $target (keys %CHOOSEDTARGET) + foreach my $target (sort keys %CHOOSEDTARGET) { if ($CHOOSEDTARGET{$target} < 0) { next; } - + if ($target eq '-CHKSUM') { next; } + print "\nBuild package for target $target\n"; if ($target eq 'SNAPSHOT') @@ -979,7 +995,7 @@ if ($nboftargetok) { # Publish package for each target #-------------------------------- - foreach my $target (keys %CHOOSEDPUBLISH) + foreach my $target (sort keys %CHOOSEDPUBLISH) { if ($CHOOSEDPUBLISH{$target} < 0) { next; } @@ -1062,7 +1078,8 @@ if ($nboftargetok) { } print "\n----- Summary -----\n"; -foreach my $target (keys %CHOOSEDTARGET) { +foreach my $target (sort keys %CHOOSEDTARGET) { + if ($target eq '-CHKSUM') { print "Checksum was generated"; next; } if ($CHOOSEDTARGET{$target} < 0) { print "Package $target not built (bad requirement).\n"; } else { diff --git a/htdocs/admin/expensereport.php b/htdocs/admin/expensereport.php new file mode 100644 index 00000000000..d8b3d727bb5 --- /dev/null +++ b/htdocs/admin/expensereport.php @@ -0,0 +1,499 @@ + + * Copyright (C) 2004-2015 Laurent Destailleur + * Copyright (C) 2004 Sebastien Di Cintio + * Copyright (C) 2004 Benoit Mortier + * Copyright (C) 2005-2014 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2011-2013 Juanjo Menent + * Copyright (C) 2011-2013 Philippe Grand + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/expensereport.php + * \ingroup expensereport + * \brief Setup page of module ExpenseReport + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/expensereport.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php'; + +$langs->load("admin"); +$langs->load("errors"); +$langs->load("trips"); +$langs->load('other'); + +if (! $user->admin) accessforbidden(); + +$action = GETPOST('action','alpha'); +$value = GETPOST('value','alpha'); +$label = GETPOST('label','alpha'); +$scandir = GETPOST('scandir','alpha'); +$type='expensereport'; + + +/* + * Actions + */ +if ($action == 'updateMask') +{ + $maskconst=GETPOST('maskconst','alpha'); + $maskvalue=GETPOST('maskvalue','alpha'); + if ($maskconst) $res = dolibarr_set_const($db,$maskconst,$maskvalue,'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +else if ($action == 'specimen') // For fiche inter +{ + $modele= GETPOST('module','alpha'); + + $inter = new ExpenseReport($db); + $inter->initAsSpecimen(); + + // Search template files + $file=''; $classname=''; $filefound=0; + $dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + foreach($dirmodels as $reldir) + { + $file=dol_buildpath($reldir."core/modules/expensereport/doc/pdf_".$modele.".modules.php",0); + if (file_exists($file)) + { + $filefound=1; + $classname = "pdf_".$modele; + break; + } + } + + if ($filefound) + { + require_once $file; + + $module = new $classname($db); + + if ($module->write_file($inter,$langs) > 0) + { + header("Location: ".DOL_URL_ROOT."/document.php?modulepart=expensereport&file=SPECIMEN.pdf"); + return; + } + else + { + setEventMessage($obj->error,'errors'); + dol_syslog($obj->error, LOG_ERR); + } + } + else + { + setEventMessage($langs->trans("ErrorModuleNotFound"),'errors'); + dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); + } +} + +// Define constants for submodules that contains parameters (forms with param1, param2, ... and value1, value2, ...) +if ($action == 'setModuleOptions') +{ + $post_size=count($_POST); + + $db->begin(); + + for($i=0;$i < $post_size;$i++) + { + if (array_key_exists('param'.$i,$_POST)) + { + $param=GETPOST("param".$i,'alpha'); + $value=GETPOST("value".$i,'alpha'); + if ($param) $res = dolibarr_set_const($db,$param,$value,'chaine',0,'',$conf->entity); + if (! $res > 0) $error++; + } + } + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + setEventMessage($langs->trans("Error"),'errors'); + } +} + +// Activate a model +else if ($action == 'set') +{ + $ret = addDocumentModel($value, $type, $label, $scandir); +} + +else if ($action == 'del') +{ + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + if ($conf->global->EXPENSEREPORT_ADDON_PDF == "$value") dolibarr_del_const($db, 'EXPENSEREPORT_ADDON_PDF',$conf->entity); + } +} + +// Set default model +else if ($action == 'setdoc') +{ + if (dolibarr_set_const($db, "EXPENSEREPORT_ADDON_PDF",$value,'chaine',0,'',$conf->entity)) + { + // La constante qui a ete lue en avant du nouveau set + // on passe donc par une variable pour avoir un affichage coherent + $conf->global->EXPENSEREPORT_ADDON_PDF = $value; + } + + // On active le modele + $ret = delDocumentModel($value, $type); + if ($ret > 0) + { + $ret = addDocumentModel($value, $type, $label, $scandir); + } +} + +else if ($action == 'setmod') +{ + // TODO Verifier si module numerotation choisi peut etre active + // par appel methode canBeActivated + + dolibarr_set_const($db, "EXPENSEREPORT_ADDON",$value,'chaine',0,'',$conf->entity); +} + +else if ($action == 'set_EXPENSEREPORT_FREE_TEXT') +{ + $freetext= GETPOST('EXPENSEREPORT_FREE_TEXT','alpha'); + $res = dolibarr_set_const($db, "EXPENSEREPORT_FREE_TEXT",$freetext,'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + +else if ($action == 'set_EXPENSEREPORT_DRAFT_WATERMARK') +{ + $draft= GETPOST('EXPENSEREPORT_DRAFT_WATERMARK','alpha'); + + $res = dolibarr_set_const($db, "EXPENSEREPORT_DRAFT_WATERMARK",trim($draft),'chaine',0,'',$conf->entity); + + if (! $res > 0) $error++; + + if (! $error) + { + setEventMessage($langs->trans("SetupSaved")); + } + else + { + setEventMessage($langs->trans("Error"),'errors'); + } +} + + + +/* + * View + */ + +$dirmodels=array_merge(array('/'),(array) $conf->modules_parts['models']); + +llxHeader(); + +$form=new Form($db); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("ExpenseReportsSetup"),$linkback,'setup'); + + +$head=expensereport_admin_prepare_head(); + +dol_fiche_head($head, 'expensereport', $langs->trans("ExpenseReports"), 0, 'trip'); + +// Interventions numbering model +/* +print_titre($langs->trans("FicheinterNumberingModules")); + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/fichinter/"); + + if (is_dir($dir)) + { + $handle = opendir($dir); + if (is_resource($handle)) + { + $var=true; + + while (($file = readdir($handle))!==false) + { + if (preg_match('/^(mod_.*)\.php$/i',$file,$reg)) + { + $file = $reg[1]; + $classname = substr($file,4); + + require_once $dir.$file.'.php'; + + $module = new $file; + + if ($module->isEnabled()) + { + // Show modules according to features level + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) continue; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) continue; + + $var=!$var; + print ''; + + // Show example of numbering model + print ''."\n"; + + print ''; + + $ficheinter=new Fichinter($db); + $ficheinter->initAsSpecimen(); + + // Info + $htmltooltip=''; + $htmltooltip.=''.$langs->trans("Version").': '.$module->getVersion().'
'; + $nextval=$module->getNextValue($mysoc,$ficheinter); + if ("$nextval" != $langs->trans("NotAvailable")) { // Keep " on nextval + $htmltooltip.=''.$langs->trans("NextValue").': '; + if ($nextval) { + if (preg_match('/^Error/',$nextval) || $nextval=='NotConfigured') + $nextval = $langs->trans($nextval); + $htmltooltip.=$nextval.'
'; + } else { + $htmltooltip.=$langs->trans($module->error).'
'; + } + } + print ''; + + print ''; + } + } + } + closedir($handle); + } + } +} + +print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Example").''.$langs->trans("Status").''.$langs->trans("ShortInfo").'
'.$module->nom."\n"; + print $module->info(); + print ''; + $tmp=$module->getExample(); + if (preg_match('/^Error/',$tmp)) print '
'.$langs->trans($tmp).'
'; + elseif ($tmp=='NotConfigured') print $langs->trans($tmp); + else print $tmp; + print '
'; + if ($conf->global->FICHEINTER_ADDON == $classname) + { + print img_picto($langs->trans("Activated"),'switch_on'); + } + else + { + print ''.img_picto($langs->trans("Disabled"),'switch_off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,1,0); + print '

'; +*/ + +/* + * Documents models for Interventions + */ + +print_titre($langs->trans("TemplatePDFExpenseReports")); + +// Defini tableau def des modeles +$type='expensereport'; +$def = array(); +$sql = "SELECT nom"; +$sql.= " FROM ".MAIN_DB_PREFIX."document_model"; +$sql.= " WHERE type = '".$type."'"; +$sql.= " AND entity = ".$conf->entity; +$resql=$db->query($sql); +if ($resql) +{ + $i = 0; + $num_rows=$db->num_rows($resql); + while ($i < $num_rows) + { + $array = $db->fetch_array($resql); + array_push($def, $array[0]); + $i++; + } +} +else +{ + dol_print_error($db); +} + + +print ''; +print ''; +print ''; +print ''; +print '\n"; +print '\n"; +print ''; +print ''; +print "\n"; + +clearstatcache(); + +$var=true; +foreach ($dirmodels as $reldir) +{ + $dir = dol_buildpath($reldir."core/modules/expensereport/doc"); + + if (is_dir($dir)) + { + $handle=opendir($dir); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + $filelist[]=$file; + } + closedir($handle); + arsort($filelist); + + foreach($filelist as $file) + { + if (preg_match('/\.modules\.php$/i',$file) && preg_match('/^(pdf_|doc_)/',$file)) + { + + if (file_exists($dir.'/'.$file)) + { + $var=!$var; + + $name = substr($file, 4, dol_strlen($file) -16); + $classname = substr($file, 0, dol_strlen($file) -12); + + require_once $dir.'/'.$file; + $module = new $classname($db); + + $modulequalified=1; + if ($module->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($module->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + + if ($modulequalified) + { + print ''; + + // Active + if (in_array($name, $def)) + { + print ""; + } + else + { + print ""; + } + + // Default + print "'; + + // Info + $htmltooltip = ''.$langs->trans("Name").': '.$module->name; + $htmltooltip.='
'.$langs->trans("Type").': '.($module->type?$module->type:$langs->trans("Unknown")); + $htmltooltip.='
'.$langs->trans("Width").'/'.$langs->trans("Height").': '.$module->page_largeur.'/'.$module->page_hauteur; + $htmltooltip.='

'.$langs->trans("FeaturesSupported").':'; + $htmltooltip.='
'.$langs->trans("Logo").': '.yn($module->option_logo,1,1); + $htmltooltip.='
'.$langs->trans("PaymentMode").': '.yn($module->option_modereg,1,1); + $htmltooltip.='
'.$langs->trans("PaymentConditions").': '.yn($module->option_condreg,1,1); + $htmltooltip.='
'.$langs->trans("MultiLanguage").': '.yn($module->option_multilang,1,1); + $htmltooltip.='
'.$langs->trans("WatermarkOnDraftOrders").': '.yn($module->option_draft_watermark,1,1); + print ''; + + // Preview + print ''; + + print ''; + } + } + } + } + } + } +} + +print '
'.$langs->trans("Name").''.$langs->trans("Description").''.$langs->trans("Status")."'.$langs->trans("Default")."'.$langs->trans("ShortInfo").''.$langs->trans("Preview").'
'; + print (empty($module->name)?$name:$module->name); + print "\n"; + if (method_exists($module,'info')) print $module->info($langs); + else print $module->description; + print '\n"; + print 'scandir.'&label='.urlencode($module->name).'">'; + print img_picto($langs->trans("Enabled"),'switch_on'); + print ''; + print "\n"; + print 'scandir.'&label='.urlencode($module->name).'">'.img_picto($langs->trans("Disabled"),'switch_off').''; + print ""; + if ($conf->global->EXPENSEREPORT_ADDON_PDF == "$name") + { + print img_picto($langs->trans("Default"),'on'); + } + else + { + print 'scandir.'&label='.urlencode($module->name).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').''; + } + print ''; + print $form->textwithpicto('',$htmltooltip,-1,0); + print ''; + if ($module->type == 'pdf') + { + print ''.img_object($langs->trans("Preview"),'intervention').''; + } + else + { + print img_object($langs->trans("PreviewNotAvailable"),'generic'); + } + print '
'; + +dol_fiche_end(); + + +llxFooter(); + +$db->close(); diff --git a/htdocs/admin/notification.php b/htdocs/admin/notification.php index ce3c8d10f73..03832cdb861 100644 --- a/htdocs/admin/notification.php +++ b/htdocs/admin/notification.php @@ -33,6 +33,7 @@ $langs->load("orders"); $langs->load("propal"); $langs->load("bills"); $langs->load("errors"); +$langs->load("mails"); // Security check if (!$user->admin) @@ -76,7 +77,9 @@ if ($action == 'setvalue' && $user->admin) * View */ -llxHeader(); +$form=new Form($db); + +llxHeader('',$langs->trans("NotificationSetup")); $linkback=''.$langs->trans("BackToModuleList").''; print_fiche_titre($langs->trans("NotificationSetup"),$linkback,'setup'); @@ -132,9 +135,19 @@ foreach($listofnotifiedevents as $notifiedevent) print ''.$elementLabel.''; print ''.$notifiedevent['code'].''; print ''.$label.''; + print ''; $param='NOTIFICATION_FIXEDEMAIL_'.$notifiedevent['code']; - print ''; - if (! empty($conf->global->$param) && ! isValidEmail($conf->global->$param)) print ' '.img_warning($langs->trans("ErrorBadEMail")); + $value=GETPOST($param)?GETPOST($param,'alpha'):$conf->global->$param; + $s=''; // Do not use type="email" here, we must be able to enter a list of email with , separator. + $arrayemail=explode(',',$value); + $showwarning=0; + foreach($arrayemail as $key=>$valuedet) + { + $valuedet=trim($valuedet); + if (! empty($valuedet) && ! isValidEmail($valuedet)) $showwarning++; + } + if ((! empty($conf->global->$param)) && $showwarning) $s.=' '.img_warning($langs->trans("ErrorBadEMail")); + print $form->textwithpicto($s,$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients")); print ''; print ''; } diff --git a/htdocs/admin/stock.php b/htdocs/admin/stock.php index 6b2c626da39..0592b738fdd 100644 --- a/htdocs/admin/stock.php +++ b/htdocs/admin/stock.php @@ -87,6 +87,9 @@ if($action) if($action == 'STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT') { $res = dolibarr_set_const($db, "STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT", GETPOST('STOCK_MUST_BE_ENOUGH_FOR_SHIPMENT','alpha'),'chaine',0,'',$conf->entity); } + if($action == 'INDEPENDANT_SUBPRODUCT_STOCK') { + $res = dolibarr_set_const($db, "INDEPENDANT_SUBPRODUCT_STOCK", GETPOST('INDEPENDANT_SUBPRODUCT_STOCK','alpha'),'chaine',0,'',$conf->entity); + } if (! $res > 0) $error++; @@ -339,9 +342,29 @@ print ''; print "\n"; print "\n"; print '
'; -print ''; -print '
'; +/* I keep the option/feature, but hidden to end users for the moment. If feature is used by module, no need to have users see it. +If not used by a module, I still need to understand in which case user may need this now we can set rule on product page. +if ($conf->global->PRODUIT_SOUSPRODUITS) +{ + $var=!$var; + + print ""; + print ''.$langs->trans("IndependantSubProductStock").''; + + print ''; + print "
"; + print ''; + print ""; + print $form->selectyesno("INDEPENDANT_SUBPRODUCT_STOCK",$conf->global->INDEPENDANT_SUBPRODUCT_STOCK,1); + print ''; + print '
'; + print "\n"; + print "\n"; +} +*/ + +print ''; llxFooter(); diff --git a/htdocs/admin/supplierinvoice_extrafields.php b/htdocs/admin/supplierinvoice_extrafields.php index e47c8738041..e1f71d8d147 100644 --- a/htdocs/admin/supplierinvoice_extrafields.php +++ b/htdocs/admin/supplierinvoice_extrafields.php @@ -31,6 +31,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +$langs->load("orders"); if (!$user->admin) accessforbidden(); diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php new file mode 100644 index 00000000000..278aae8ea5b --- /dev/null +++ b/htdocs/admin/system/filecheck.php @@ -0,0 +1,138 @@ + + * Copyright (C) 2007 Rodolphe Quiedeville + * Copyright (C) 2007-2012 Regis Houssin + * Copyright (C) 2015 Frederic France + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/system/filecheck.php + * \brief Page to check Dolibarr files integrity + */ + +require '../../main.inc.php'; + +$langs->load("admin"); + +if (!$user->admin) + accessforbidden(); + + +/* + * View + */ + +llxHeader(); + +print_fiche_titre($langs->trans("FileCheckDolibarr"),'','setup'); + +// Version +$var = true; +print ''; +print ''."\n"; +$var = ! $var; +print ''."\n"; +$var = ! $var; +print ''."\n"; +$var = ! $var; +print ''."\n"; +print '
'.$langs->trans("Version").''.$langs->trans("Value").'
'.$langs->trans("VersionLastInstall").''.$conf->global->MAIN_VERSION_LAST_INSTALL.'
'.$langs->trans("VersionLastUpgrade").''.$conf->global->MAIN_VERSION_LAST_UPGRADE.'
'.$langs->trans("VersionProgram").''.DOL_VERSION; +// If current version differs from last upgrade +if (empty($conf->global->MAIN_VERSION_LAST_UPGRADE)) { + // Compare version with last install database version (upgrades never occured) + if (DOL_VERSION != $conf->global->MAIN_VERSION_LAST_INSTALL) + print ' '.img_warning($langs->trans("RunningUpdateProcessMayBeRequired",DOL_VERSION,$conf->global->MAIN_VERSION_LAST_INSTALL)); +} else { + // Compare version with last upgrade database version + if (DOL_VERSION != $conf->global->MAIN_VERSION_LAST_UPGRADE) + print ' '.img_warning($langs->trans("RunningUpdateProcessMayBeRequired",DOL_VERSION,$conf->global->MAIN_VERSION_LAST_UPGRADE)); +} +print '
'; +print '
'; + + +// Modified or missing files +$file_list = array('missing' => array(), 'updated' => array()); +$xmlfile = DOL_DOCUMENT_ROOT.'/core/filelist-'.DOL_VERSION.'.xml'; +if (file_exists($xmlfile)) { + $xml = simplexml_load_file($xmlfile); + if ($xml) { + $ret = getFilesUpdated($xml->dolibarr_root_dir[0]); + print ''; + print ''; + print ''; + print ''."\n"; + $var = true; + foreach ($file_list['missing'] as $file) { + $var = !$var; + print ''; + print '' . "\n"; + print "\n"; + } + print '
' . $langs->trans("FilesMissing") . '
'.$file.'
'; + print ''; + print ''; + print ''; + print ''."\n"; + $var = true; + foreach ($file_list['updated'] as $file) { + $var = !$var; + print ''; + print '' . "\n"; + print "\n"; + } + print '
' . $langs->trans("FilesUpdated") . '
'.$file.'
'; + } +} else { + print $langs->trans('XmlNotFound') . ': ' . DOL_DOCUMENT_ROOT . '/core/filelist-' . DOL_VERSION . '.xml'; +} + +llxFooter(); + +$db->close(); + + +/** + * Function to get list of updated or modified files + * + * @param object $dir SimpleXMLElement of files to test + * @param string $path Path of file + * @return array Array of filenames + */ +function getFilesUpdated(SimpleXMLElement $dir, $path = '') +{ + global $file_list; + $exclude = 'install'; + + foreach ($dir->md5file as $file) { + $filename = $path.$file['name']; + + if (preg_match('#'.$exclude.'#', $filename)) + continue; + + if (!file_exists(DOL_DOCUMENT_ROOT.'/'.$filename)) { + $file_list['missing'][] = $filename; + } else { + $md5_local = md5_file(DOL_DOCUMENT_ROOT.'/'.$filename); + if ($md5_local != (string) $file) + $file_list['updated'][] = $filename; + } + } + + foreach ($dir->dir as $subdir) + getFilesUpdated($subdir, $path.$subdir['name'].'/'); +return $file_list; +} diff --git a/htdocs/comm/action/class/ical.class.php b/htdocs/comm/action/class/ical.class.php index da062176d13..e7bddb8bd7e 100644 --- a/htdocs/comm/action/class/ical.class.php +++ b/htdocs/comm/action/class/ical.class.php @@ -23,10 +23,11 @@ * \ingroup agenda * \brief File of class to parse ical calendars */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/xcal.lib.php'; /** - * Class to parse ICal calendars + * Class to read/parse ICal calendars */ class ICal { @@ -107,6 +108,7 @@ class ICal if (!stristr($this->file_text[0],'BEGIN:VCALENDAR')) return 'error not VCALENDAR'; $insidealarm=0; + $tmpkey='';$tmpvalue=''; foreach ($this->file_text as $text) { $text = trim($text); // trim one line @@ -137,7 +139,7 @@ class ICal case "BEGIN:DAYLIGHT": case "BEGIN:VTIMEZONE": case "BEGIN:STANDARD": - $type = $value; // save tu array under value key + $type = $value; // save array under value key break; case "END:VTODO": // end special text - goto VCALENDAR key @@ -159,8 +161,31 @@ class ICal $insidealarm=0; break; - default: // no special string - if (! $insidealarm) $this->add_to_array($type, $key, $value); // add to array + default: // no special string (SUMMARY, DESCRIPTION, ...) + if ($tmpvalue) + { + $tmpvalue .= $text; + if (! preg_match('/=$/',$text)) // No more lines + { + $key=$tmpkey; + $value=quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i','',$tmpvalue)); + $tmpkey=''; + $tmpvalue=''; + } + } + elseif (preg_match('/^ENCODING=QUOTED-PRINTABLE:/i',$value)) + { + if (preg_match('/=$/',$value)) + { + $tmpkey=$key; + $tmpvalue=$tmpvalue.preg_replace('/=$/',"",$value); // We must wait to have next line to have complete message + } + else + { + $value=quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i','',$tmpvalue.$value)); + } + } //$value=quotedPrintDecode($tmpvalue.$value); + if (! $insidealarm && ! $tmpkey) $this->add_to_array($type, $key, $value); // add to array break; } } diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index ae646e5d2c3..2ec95810536 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -361,6 +361,7 @@ if (! empty($conf->use_javascript_ajax)) foreach ($showextcals as $val) { $htmlname = dol_string_nospecial($val['name']); + $htmlname = dol_string_nospecial($htmlname,'_',array("\.","#")); $s.='