diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d898628013e..a992c0a13f6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -36,7 +36,7 @@ Definition: As the Developer: -1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/DCO) +1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/blob/develop/DCO) 2. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr). 3. Clone your fork. 4. Choose a branch(See the [Branches](#branches) section below). diff --git a/.github/workflows/pr-18-autolabel.yaml b/.github/workflows/pr-18-autolabel.yaml index 4524d02815b..feb9ee17c97 100644 --- a/.github/workflows/pr-18-autolabel.yaml +++ b/.github/workflows/pr-18-autolabel.yaml @@ -18,3 +18,4 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/changed-lines-count-labeler.yml + continue-on-error: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e6953f04578..5f75f64fc16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: # git commit -a -m "My message" --no-verify # (Recommendation: run git commit -a .. once, then with `--no-verify`) - id: no-commit-to-branch - args: [--branch, develop, --pattern, \d+.0] + args: [--branch, develop, --pattern, \d+.0$] # This checks that xml files are correct - id: check-xml exclude: | diff --git a/README-FR.md b/README-FR.md index c1c474f2597..34ca2f596f1 100644 --- a/README-FR.md +++ b/README-FR.md @@ -1,6 +1,7 @@ # DOLIBARR ERP & CRM ![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) +![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/) [![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521) diff --git a/README.md b/README.md index c5870358438..136f946a257 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # DOLIBARR ERP & CRM ![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) +![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/) [![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 629672d06c4..9370d504627 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -4,7 +4,7 @@ # \brief Dolibarr package builder (tgz, zip, rpm, deb, exe, aps) # \author (c)2004-2023 Laurent Destailleur # -# This is list of constant you can set to have generated packages moved into a specific dir: +# This is list of constant you can set to have generated packages moved into a specific dir: #DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild' #DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable' #DESTIMODULES='/media/HDDATA1_LD/Mes Sites/Web/Admin1/wwwroot/files/modules' @@ -129,7 +129,7 @@ if (! $TEMP || ! -d $TEMP) { print "$PROG.$Extension aborted.\n"; sleep 2; exit 2; -} +} $BUILDROOT="$TEMP/buildroot"; @@ -172,7 +172,7 @@ $newbuild = $BUILD; $newbuild =~ s/(dev|alpha)/1/gi; # dev $newbuild =~ s/beta(.?)/2/gi; # beta (we want beta1, beta2, betax to be same package name) $newbuild =~ s/rc(.?)/3/gi; # rc (we want rc1, rc2, rcx to be same package name) -if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc. +if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc. # now newbuild is 0-1 or 0-4 for example. Note that for native package (see debian/source/format), we should not use a dash part but to get a better version management $build = $newbuild; $build =~ s/-.*$//g; @@ -190,8 +190,8 @@ for (0..@ARGV-1) { if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; } if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; } if ($ARGV[$_] =~ /^-*prefix=(.+)/i) { - $PREFIX=$1; - $FILENAMESNAPSHOT.="-".$PREFIX; + $PREFIX=$1; + $FILENAMESNAPSHOT.="-".$PREFIX; } } if ($ENV{"DESTIBETARC"} && $BUILD =~ /[a-z]/i) { $DESTI = $ENV{"DESTIBETARC"}; } # Force output dir if env DESTIBETARC is defined @@ -210,7 +210,7 @@ print "Target directory (DESTI) : $DESTI\n"; # Choose package targets #----------------------- if ($target) { - if ($target eq "ALL") { + if ($target eq "ALL") { foreach my $key (@LISTETARGET) { if ($key ne 'SNAPSHOT' && $key ne 'SF' && $key ne 'ASSO') { $CHOOSEDTARGET{$key}=1; } } @@ -236,10 +236,10 @@ else { printf(" %2d - %-14s (%s)\n",$cpt,"ASSO (publish)","Need ".$REQUIREMENTPUBLISH{"ASSO"}); $cpt=99; printf(" %2d - %-14s (%s)\n",$cpt,"SF (publish)","Need ".$REQUIREMENTPUBLISH{"SF"}); - + # Ask which target to build print "Choose one target number or several separated with space (0 - ".$cpt."): "; - $NUM_SCRIPT=; + $NUM_SCRIPT=; chomp($NUM_SCRIPT); if ($NUM_SCRIPT !~ /^[0-9\s]+$/) { @@ -286,11 +286,11 @@ foreach my $target (sort keys %CHOOSEDTARGET) { print "Error: You asked creation of several rpms. Because all rpm have same name, you must defined an environment variable DESTI to tell packager where it can create subdirs for each generated package.\n"; exit; } - $atleastonerpm=1; - } - foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) + $atleastonerpm=1; + } + foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) { - # Test + # Test print "Test requirement for target $target: Search '$req'... "; $newreq=$req; $newparam=''; if ($newreq eq 'zip') { $newparam.='-h'; } @@ -299,12 +299,12 @@ foreach my $target (sort keys %CHOOSEDTARGET) { print "Test command ".$cmd."... "; $ret=`$cmd`; $coderetour=$?; $coderetour2=$coderetour>>8; - if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) { + if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) { # Not found error, we try in PROGPATH $ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`; $coderetour=$?; $coderetour2=$coderetour>>8; $REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req"; - } + } if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) { # Not found error @@ -333,7 +333,7 @@ $nbofpublishneedchangelog=0; foreach my $target (sort keys %CHOOSEDTARGET) { if ($target eq '-CHKSUM') { $nbofpublishneedchangelog++; } if ($CHOOSEDTARGET{$target} < 0) { next; } - if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') + if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') { $nboftargetneedbuildroot++; } @@ -397,10 +397,10 @@ if ($nboftargetok) { print "Go to directory $SOURCE\n"; $olddir=getcwd(); chdir("$SOURCE"); - + print "Clean $SOURCE/htdocs/includes/autoload.php\n"; $ret=`rm -f $SOURCE/htdocs/includes/autoload.php`; - + $ret=`git ls-files . --exclude-standard --others`; if ($ret) { @@ -409,7 +409,7 @@ if ($nboftargetok) { print "Canceled.\n"; exit; } - + print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n"; $ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`; print $ret."\n"; @@ -427,13 +427,13 @@ if ($nboftargetok) { print "Go to directory $SOURCE\n"; $olddir=getcwd(); chdir("$SOURCE"); - + print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n"; $ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`; if ($ret =~ /(already exists|existe déjà)/) { print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? "; - $QUESTIONOVERWRITETAG=; + $QUESTIONOVERWRITETAG=; chomp($QUESTIONOVERWRITETAG); if ($QUESTIONOVERWRITETAG =~ /(o|y)/) { @@ -452,7 +452,7 @@ if ($nboftargetok) { } chdir("$olddir"); } - + # Update buildroot if required #----------------------------- if ($nboftargetneedbuildroot) @@ -462,7 +462,7 @@ if ($nboftargetok) { print "Delete directory $BUILDROOT\n"; $ret=`rm -fr "$BUILDROOT"`; - + mkdir "$BUILDROOT"; mkdir "$BUILDROOT/$PROJECT"; print "Copy $SOURCE into $BUILDROOT/$PROJECT\n"; @@ -491,7 +491,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/phpstan.neon.dist`; $ret=`rm -f $BUILDROOT/$PROJECT/pom.xml`; $ret=`rm -f $BUILDROOT/$PROJECT/README-*.md`; - + $ret=`rm -fr $BUILDROOT/$PROJECT/build/html`; $ret=`rm -f $BUILDROOT/$PROJECT/build/Doli*-*`; $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr_*.deb`; @@ -507,6 +507,7 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr-*.xz`; $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr-*.zip`; $ret=`rm -f $BUILDROOT/$PROJECT/build/doxygen/doxygen_warnings.log`; + $ret=`rm -fr $BUILDROOT/$PROJECT/build/phpstan/phpstan`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/cache.manifest`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.mysql`; @@ -560,20 +561,20 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot11.png`; $ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot12.png`; - # Security to avoid to package data files + # Security to avoid to package data files print "Remove documents dir\n"; $ret=`rm -fr $BUILDROOT/$PROJECT/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/documents`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/documents`; - + print "Remove subdir of custom dir\n"; print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\;\n"; $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs but not files print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\;\n"; $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs, even symbolic links, but not files - # Removed known external modules to avoid any error when packaging from env where external modules are tested + # Removed known external modules to avoid any error when packaging from env where external modules are tested $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/abricot*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/allscreens*`; @@ -599,15 +600,15 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`; - + # Removed other test files $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/Thumbs.db $BUILDROOT/$PROJECT/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/*/Thumbs.db`; $ret=`rm -f $BUILDROOT/$PROJECT/.cvsignore $BUILDROOT/$PROJECT/*/.cvsignore $BUILDROOT/$PROJECT/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.cvsignore`; $ret=`rm -f $BUILDROOT/$PROJECT/.gitignore $BUILDROOT/$PROJECT/*/.gitignore $BUILDROOT/$PROJECT/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.gitignore`; - - # Removed files installed by the awful composer + + # Removed files installed by the awful composer $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/geoip/sample*.*`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/adapters`; # Keep this removal in case we embed libraries @@ -642,7 +643,7 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/vendor`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/webmozart`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/autoload.php`; - + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/*/bin`; @@ -652,14 +653,14 @@ if ($nboftargetok) { # Build package for each target #------------------------------ - foreach my $target (sort 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') + if ($target eq 'SNAPSHOT') { $NEWDESTI=$DESTI; @@ -683,13 +684,13 @@ if ($nboftargetok) { next; } - if ($target eq 'TGZ') + if ($target eq 'TGZ') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); - if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } + if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } } print "Remove target $FILENAMETGZ.tgz...\n"; @@ -703,7 +704,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$FILENAMETGZ/build/exe`; $ret=`rm -fr $BUILDROOT/$FILENAMETGZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages - + print "Compress $FILENAMETGZ into $FILENAMETGZ.tgz...\n"; $cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMETGZ.tgz\" $FILENAMETGZ"; print "$cmd\n"; @@ -715,14 +716,14 @@ if ($nboftargetok) { next; } - if ($target eq 'XZ') + if ($target eq 'XZ') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } - } + } print "Remove target $FILENAMEXZ.xz...\n"; unlink("$NEWDESTI/$FILENAMEXZ.xz"); @@ -735,7 +736,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$FILENAMEXZ/build/exe`; $ret=`rm -fr $BUILDROOT/$FILENAMEXZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages - + print "Compress $FILENAMEXZ into $FILENAMEXZ.xz...\n"; print "Go to directory $BUILDROOT\n"; @@ -751,15 +752,15 @@ if ($nboftargetok) { $ret=`mv "$BUILDROOT/$FILENAMEXZ.xz" "$NEWDESTI/$FILENAMEXZ.xz"`; next; } - - if ($target eq 'ZIP') + + if ($target eq 'ZIP') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } - } + } print "Remove target $FILENAMEZIP.zip...\n"; unlink("$NEWDESTI/$FILENAMEZIP.zip"); @@ -782,14 +783,14 @@ if ($nboftargetok) { print $cmd."\n"; $ret= `$cmd`; chdir("$olddir"); - + # Move to final dir print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n"; $ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`; next; } - - if ($target =~ /RPM/) # Linux only + + if ($target =~ /RPM/) # Linux only { $NEWDESTI=$DESTI; $subdir="package_rpm_generic"; @@ -800,7 +801,7 @@ if ($nboftargetok) { { mkdir($DESTI.'/'.$subdir); if (-d $DESTI.'/'.$subdir) { $NEWDESTI=$DESTI.'/'.$subdir; } - } + } if ($RPMDIR eq "") { $RPMDIR=$ENV{'HOME'}."/rpmbuild"; } @@ -813,7 +814,7 @@ if ($nboftargetok) { print "Create directory $BUILDROOT/$FILENAMETGZ2\n"; $ret=`rm -fr $BUILDROOT/$FILENAMETGZ2`; - + print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$FILENAMETGZ2\n"; $cmd="cp -pr '$BUILDROOT/$PROJECT' '$BUILDROOT/$FILENAMETGZ2'"; $ret=`$cmd`; @@ -839,7 +840,7 @@ if ($nboftargetok) { if ($target =~ /FEDO/i) { $BUILDFICSRC="${FILENAME}_fedora.spec"; } if ($target =~ /MAND/i) { $BUILDFICSRC="${FILENAME}_mandriva.spec"; } if ($target =~ /OPEN/i) { $BUILDFICSRC="${FILENAME}_opensuse.spec"; } - + use Date::Language; $lang=Date::Language->new('English'); $datestring = $lang->time2str("%a %b %e %Y", time); @@ -857,7 +858,7 @@ if ($nboftargetok) { } close SPECFROM; close SPECTO; - + print "Copy patch file to $RPMDIR/SOURCES\n"; $ret=`cp "$SOURCE/build/rpm/dolibarr-forrpm.patch" "$RPMDIR/SOURCES"`; $ret=`chmod 644 $RPMDIR/SOURCES/dolibarr-forrpm.patch`; @@ -879,14 +880,14 @@ if ($nboftargetok) { next; } - if ($target eq 'DEB') + if ($target eq 'DEB') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/package_debian-ubuntu'); if (-d $DESTI.'/package_debian-ubuntu') { $NEWDESTI=$DESTI.'/package_debian-ubuntu'; } - } + } $olddir=getcwd(); @@ -967,13 +968,13 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/jquery/plugins/select2/LICENSE`; $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mike42/escpos-php/LICENSE.md`; $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mobiledetect/mobiledetectlib/LICENSE.txt`; - + # Removed files we don't need (already removed) #$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/ckeditor/ckeditor/_source`; - + # Rename upstream changelog to match debian rules $ret=`mv $BUILDROOT/$PROJECT.tmp/ChangeLog $BUILDROOT/$PROJECT.tmp/changelog`; - + # Prepare source package (init debian dir) print "Create directory $BUILDROOT/$PROJECT.tmp/debian\n"; $ret=`mkdir "$BUILDROOT/$PROJECT.tmp/debian"`; @@ -1011,7 +1012,7 @@ if ($nboftargetok) { $ret=`cp -f "$SOURCE/build/debian/dolibarr.postrm" "$BUILDROOT/$PROJECT.tmp/debian"`; $ret=`cp -f "$SOURCE/build/debian/dolibarr.templates" "$BUILDROOT/$PROJECT.tmp/debian"`; $ret=`cp -f "$SOURCE/build/debian/install.forced.php.install" "$BUILDROOT/$PROJECT.tmp/debian"`; - + # Set owners and permissions #print "Set owners on files/dir\n"; #$ret=`chown -R root.root $BUILDROOT/$PROJECT.tmp`; @@ -1042,8 +1043,8 @@ if ($nboftargetok) { $ret=`$cmd`; $cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.sh' -type f -exec chmod 755 {} \\; "; $ret=`$cmd`; - - + + print "Rename directory $BUILDROOT/$PROJECT.tmp into $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; $cmd="mv $BUILDROOT/$PROJECT.tmp $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; $ret=`$cmd`; @@ -1051,14 +1052,14 @@ if ($nboftargetok) { print "Go into directory $BUILDROOT\n"; chdir("$BUILDROOT"); - + # We need a tarball to be able to build "quilt" debian package (not required for native but we need patch so it is not a native) print "Compress $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build into $BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz...\n"; $cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz\" $PROJECT-$MAJOR.$MINOR.$build"; print $cmd."\n"; $ret=`$cmd`; - # Creation of source package + # Creation of source package print "Go into directory $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; chdir("$BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"); #$cmd="dpkg-source -b $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; @@ -1077,12 +1078,12 @@ if ($nboftargetok) { $ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`; - #$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option + #$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option $ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`; next; } - + if ($target eq 'EXEDOLIWAMP') { $NEWDESTI=$DESTI; @@ -1090,22 +1091,22 @@ if ($nboftargetok) { { mkdir($DESTI.'/package_windows'); if (-d $DESTI.'/package_windows') { $NEWDESTI=$DESTI.'/package_windows'; } - } + } print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n"; unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"; - + if ($OS eq 'windows') { print "Check that ISCC.exe is in your PATH.\n"; } else { print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n"; } - + $SOURCEBACK=$SOURCE; $SOURCEBACK =~ s/\//\\/g; print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n"; - + #$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!; open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!; @@ -1118,7 +1119,7 @@ if ($nboftargetok) { close(OUT); print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n"; - + if ($OS eq 'windows') { $cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; } else { @@ -1132,26 +1133,26 @@ if ($nboftargetok) { print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; - + use File::Copy; #$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`; $ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); - + print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n"; #$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; $ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"); - + next; } } # Publish package for each target #-------------------------------- - foreach my $target (sort keys %CHOOSEDPUBLISH) + foreach my $target (sort keys %CHOOSEDPUBLISH) { if ($CHOOSEDPUBLISH{$target} < 0) { next; } - + print "\nList of files to publish (BUILD=$BUILD)\n"; %filestoscansf=( "$DESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml"=>'none', # none means it won't be published on SF @@ -1209,26 +1210,26 @@ if ($nboftargetok) { print "\n"; } - if ($target eq 'SF' || $target eq 'ASSO') + if ($target eq 'SF' || $target eq 'ASSO') { print "\n"; - + if ($target eq 'SF') { $PUBLISH = $PUBLISHSTABLE; } if ($target eq 'ASSO' && $BUILD =~ /[a-z]/i) { $PUBLISH = $PUBLISHBETARC.'/lastbuild'; } if ($target eq 'ASSO' && $BUILD =~ /^[0-9]+$/) { $PUBLISH = $PUBLISHBETARC.'/stable'; } - + $NEWPUBLISH=$PUBLISH; print "Publish to target $NEWPUBLISH. Click enter or CTRL+C...\n"; # Ask which target to build - $NUM_SCRIPT=; + $NUM_SCRIPT=; chomp($NUM_SCRIPT); print "Create empty dir /tmp/emptydir. We need it to create target dir using rsync.\n"; $ret=`mkdir -p "/tmp/emptydir/"`; - + %filestoscan=%filestoscansf; - + foreach my $file (sort keys %filestoscan) { $found=0; @@ -1238,30 +1239,30 @@ if ($nboftargetok) { if ($target eq 'SF') { if ($filestoscan{$file} eq 'none') { next; - } + } $destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD; } elsif ($target eq 'ASSO' and $NEWPUBLISH =~ /stable/) { $destFolder="$NEWPUBLISH/$filestoscanstableasso{$file}"; - } + } elsif ($target eq 'ASSO' and $NEWPUBLISH !~ /stable/) { $destFolder="$NEWPUBLISH"; - } + } else # No more used { $dirnameonly=$file; - $dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/; + $dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/; $filenameonly=$file; - $filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/; + $filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/; $destFolder="$NEWPUBLISH/$dirnameonly"; } print "\n"; print "Publish file ".$file." to ".$destFolder."\n"; - # mkdir + # mkdir #my $ssh = Net::SSH::Perl->new("frs.sourceforge.net"); - #$ssh->login("$user","$pass"); + #$ssh->login("$user","$pass"); #use String::ShellQuote qw( shell_quote ); #$ssh->cmd('mkdir '.shell_quote($destFolder).' && exit'); @@ -1270,20 +1271,20 @@ if ($nboftargetok) { #$sftp->mkdir($destFolder) #$command="ssh eldy,dolibarr\@frs.sourceforge.net mkdir -p \"$destFolder\""; - #print "$command\n"; + #print "$command\n"; #my $ret=`$command 2>&1`; $command="rsync -s -e 'ssh' --recursive /tmp/emptydir/ \"".$destFolder."\""; - print "$command\n"; + print "$command\n"; my $ret=`$command 2>&1`; $command="rsync -s -e 'ssh' \"$file\" \"".$destFolder."\""; - print "$command\n"; + print "$command\n"; my $ret2=`$command 2>&1`; print "$ret2\n"; } } - } + } } print "\n----- Summary -----\n"; diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 44ad747741d..a3ec7716200 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -463,7 +463,7 @@ parameters: path: ../../htdocs/accountancy/class/accountingaccount.class.php - - message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#' + message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#' identifier: function.impossibleType count: 1 path: ../../htdocs/accountancy/class/accountingjournal.class.php @@ -625,7 +625,7 @@ parameters: path: ../../htdocs/accountancy/class/lettering.class.php - - message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\\>, array\\> given\.$#' + message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\\>, array\\> given\.$#' identifier: argument.type count: 1 path: ../../htdocs/accountancy/class/lettering.class.php @@ -894,10 +894,16 @@ parameters: count: 1 path: ../../htdocs/adherents/card.php + - + message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType + count: 1 + path: ../../htdocs/adherents/class/adherent.class.php + - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType - count: 2 + count: 1 path: ../../htdocs/adherents/class/adherent.class.php - @@ -942,12 +948,6 @@ parameters: count: 1 path: ../../htdocs/adherents/class/adherent.class.php - - - message: '#^Property Adherent\:\:\$first_subscription_amount \(int\|string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../htdocs/adherents/class/adherent.class.php - - message: '#^Property Adherent\:\:\$last_subscription_amount \(int\|string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -1098,12 +1098,6 @@ parameters: count: 1 path: ../../htdocs/adherents/messaging.php - - - message: '#^Variable \$socid might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/adherents/messaging.php - - message: '#^Property Partnership\:\:\$entity \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -1116,42 +1110,12 @@ parameters: count: 1 path: ../../htdocs/adherents/partnership.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../htdocs/adherents/subscription.php - - message: '#^Variable \$bankline in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable count: 1 path: ../../htdocs/adherents/subscription/card.php - - - message: '#^Empty array passed to foreach\.$#' - identifier: foreach.emptyArray - count: 1 - path: ../../htdocs/adherents/subscription/list.php - - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 2 - path: ../../htdocs/adherents/subscription/list.php - - - - message: '#^Result of && is always false\.$#' - identifier: booleanAnd.alwaysFalse - count: 1 - path: ../../htdocs/adherents/subscription/list.php - - - - message: '#^Right side of && is always false\.$#' - identifier: booleanAnd.rightAlwaysFalse - count: 1 - path: ../../htdocs/adherents/subscription/list.php - - message: '#^Variable \$object might not be defined\.$#' identifier: variable.undefined @@ -1812,6 +1776,48 @@ parameters: count: 2 path: ../../htdocs/admin/tools/purge.php + - + message: '#^Method Documentation\:\:displayMenu\(\) has parameter \$menu with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Method Documentation\:\:displaySummary\(\) has parameter \$menu with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Method Documentation\:\:setMenu\(\) should return mixed but return statement is missing\.$#' + identifier: return.missing + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Method Documentation\:\:showCode\(\) has parameter \$lines with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Property Documentation\:\:\$menu type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Property Documentation\:\:\$summary type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Property Documentation\:\:\$view type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + - message: '#^Variable \$massactionbutton in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable @@ -3343,7 +3349,7 @@ parameters: path: ../../htdocs/categories/class/categorie.class.php - - message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\ but returns array\\.$#' + message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\ but returns array\\.$#' identifier: return.type count: 1 path: ../../htdocs/categories/class/categorie.class.php @@ -3361,7 +3367,7 @@ parameters: path: ../../htdocs/categories/class/categorie.class.php - - message: '#^Property Categorie\:\:\$cats \(array\\) does not accept array\\.$#' + message: '#^Property Categorie\:\:\$cats \(array\\) does not accept array\\.$#' identifier: assign.propertyType count: 2 path: ../../htdocs/categories/class/categorie.class.php @@ -5311,7 +5317,7 @@ parameters: path: ../../htdocs/compta/cashcontrol/class/cashcontrol.class.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\<\(float\|int\)\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/compta/cashcontrol/report.php @@ -5586,12 +5592,6 @@ parameters: count: 3 path: ../../htdocs/compta/facture/class/facture-rec.class.php - - - message: '#^Parameter \#1 \$qty of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture-rec.class.php - - message: '#^Parameter \#1 \$vatrate of function getLocalTaxesFromRate expects int\|string, float given\.$#' identifier: argument.type @@ -5604,12 +5604,6 @@ parameters: count: 1 path: ../../htdocs/compta/facture/class/facture-rec.class.php - - - message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture-rec.class.php - - message: '#^Property CommonObject\:\:\$array_options \(array\\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -5664,12 +5658,6 @@ parameters: count: 3 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#1 \$qty of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Parameter \#1 \$substitutionarray of function complete_substitutions_array expects array\, array\ given\.$#' identifier: argument.type @@ -5682,42 +5670,18 @@ parameters: count: 2 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#15 \$pu_devise of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Parameter \#2 \$alreadypaid of method CommonInvoice\:\:getLibStatut\(\) expects int, float given\.$#' identifier: argument.type count: 1 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Parameter \#4 \$txtva of method Facture\:\:addline\(\) expects float, string given\.$#' identifier: argument.type count: 1 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#5 \$uselocaltax1_rate of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture.class.php - - - - message: '#^Parameter \#6 \$uselocaltax2_rate of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Property CommonInvoice\:\:\$close_code \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -6601,7 +6565,7 @@ parameters: path: ../../htdocs/compta/resultat/index.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\\}\> will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\\}\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/compta/resultat/result.php @@ -7969,7 +7933,7 @@ parameters: path: ../../htdocs/core/actions_linkedfiles.inc.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/actions_massactions.inc.php @@ -10537,7 +10501,7 @@ parameters: path: ../../htdocs/core/class/notify.class.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/class/openid.class.php @@ -12252,12 +12216,6 @@ parameters: count: 1 path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - - message: '#^Variable \$outputlangsbis might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - message: '#^Property mod_asset_standard\:\:\$prefix has no type specified\.$#' identifier: missingType.property @@ -13603,7 +13561,7 @@ parameters: path: ../../htdocs/core/modules/hrm/mod_evaluation_standard.php - - message: '#^Call to function is_array\(\) with non\-empty\-array will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-list\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/modules/import/import_csv.modules.php @@ -16908,18 +16866,6 @@ parameters: count: 1 path: ../../htdocs/core/tpl/objectline_view.tpl.php - - - message: '#^Variable \$action might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/core/tpl/objectline_view.tpl.php - - - - message: '#^Variable \$i might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../htdocs/core/tpl/objectline_view.tpl.php - - message: '#^Variable \$objp might not be defined\.$#' identifier: variable.undefined @@ -23305,7 +23251,7 @@ parameters: path: ../../htdocs/master.inc.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/modulebuilder/index.php @@ -24864,18 +24810,6 @@ parameters: count: 1 path: ../../htdocs/product/canvas/product/actions_card_product.class.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/product/tpl/card_create.tpl.php - - - - message: '#^Variable \$refalreadyexists might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/product/tpl/card_create.tpl.php - - message: '#^Property ActionsCardService\:\:\$field_list has no type specified\.$#' identifier: missingType.property @@ -24888,30 +24822,6 @@ parameters: count: 1 path: ../../htdocs/product/canvas/service/actions_card_service.class.php - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 2 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - - - message: '#^Variable \$refalreadyexists might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue @@ -29658,12 +29568,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 2 - path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - message: '#^Property CommonObject\:\:\$ismultientitymanaged \(int\<0, 1\>\|string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -29676,12 +29580,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - - message: '#^Variable \$error in empty\(\) always exists and is always falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - message: '#^Parameter \#1 \$object of method CommonDocGenerator\:\:get_substitutionarray_each_var_object\(\) expects array\, RecruitmentJobPosition given\.$#' identifier: argument.type @@ -29730,12 +29628,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php - - - message: '#^Variable \$outputlangsbis might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php - - message: '#^Variable \$badgeStatus0 might not be defined\.$#' identifier: variable.undefined @@ -30336,12 +30228,6 @@ parameters: count: 1 path: ../../htdocs/salaries/list.php - - - message: '#^Variable \$resteapayer might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/salaries/list.php - - message: '#^Variable \$selected might not be defined\.$#' identifier: variable.undefined @@ -30360,12 +30246,6 @@ parameters: count: 2 path: ../../htdocs/salaries/paiement_salary.php - - - message: '#^Variable \$sumpaid might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../htdocs/salaries/paiement_salary.php - - message: '#^Negated boolean expression is always false\.$#' identifier: booleanNot.alwaysFalse @@ -30456,24 +30336,6 @@ parameters: count: 1 path: ../../htdocs/societe/ajax/company.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/company/tpl/card_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/company/tpl/card_edit.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php - - message: '#^Variable \$db might not be defined\.$#' identifier: variable.undefined @@ -30498,24 +30360,6 @@ parameters: count: 3 path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/individual/tpl/card_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/individual/tpl/card_edit.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/societe/canvas/individual/tpl/card_view.tpl.php - - message: '#^Variable \$objcanvas might not be defined\.$#' identifier: variable.undefined @@ -30961,7 +30805,7 @@ parameters: path: ../../htdocs/societe/notify/card.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/societe/paymentmodes.php diff --git a/dev/tools/apstats.php b/dev/tools/apstats.php index fa27133329a..825257dadbe 100755 --- a/dev/tools/apstats.php +++ b/dev/tools/apstats.php @@ -883,7 +883,7 @@ $html .= '

'.$title_security $html .= '
'."\n"; $html .= '
'."\n"; $html .= ''."\n"; -$html .= ''."\n"; +$html .= ''."\n"; foreach ($arrayofalerts as $key => $alert) { $cve = ''; $yogosha = empty($alert['issueidyogosha']) ? '' : $alert['issueidyogosha']; diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index d69db0e405e..6d3df7446b4 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -17,7 +17,7 @@ return [ // PhanTypeMismatchProperty : 130+ occurrences // PhanPluginUnknownArrayMethodParamType : 120+ occurrences // PhanPluginUnknownPropertyType : 110+ occurrences - // PhanPossiblyUndeclaredVariable : 80+ occurrences + // PhanPossiblyUndeclaredVariable : 65+ occurrences // PhanRedefineFunction : 45+ occurrences // PhanTypeExpectedObjectPropAccess : 45+ occurrences // PhanTypeMismatchArgumentNullableInternal : 40+ occurrences @@ -507,7 +507,7 @@ return [ 'htdocs/recruitment/admin/setup_candidatures.php' => ['PhanEmptyForeach'], 'htdocs/recruitment/class/recruitmentcandidature.class.php' => ['PhanUndeclaredProperty'], 'htdocs/recruitment/class/recruitmentjobposition.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/recruitment/index.php' => ['PhanUndeclaredGlobalVariable'], @@ -523,7 +523,7 @@ return [ 'htdocs/salaries/card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/salaries/class/api_salaries.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/salaries/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], - 'htdocs/salaries/paiement_salary.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/salaries/paiement_salary.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/salaries/virement_request.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/societe/admin/societe.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredMethod'], 'htdocs/societe/ajax/company.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 53e6efa4934..f8573c3f75e 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -3,7 +3,8 @@ * Copyright (C) 2015-2022 Alexandre Spangaro * Copyright (C) 2015-2020 Florian Henry * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2024 MDW + * Copyright (C) 2024 MDW + * Copyright (C) 2024 Jose MARTINEZ * * 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 @@ -68,7 +69,7 @@ class BookKeeping extends CommonObject public $doc_date; /** - * @var int Deadline for payment + * @var int|null|'' Deadline for payment */ public $date_lim_reglement; @@ -324,7 +325,7 @@ class BookKeeping extends CommonObject $this->piece_num = 0; // First check if line not yet already in bookkeeping. - // Note that we must include 'doc_type - fk_doc - numero_compte - label' to be sure to have unicity of line (because we may have several lines + // Note that we must include 'doc_type - fk_doc - numero_compte - label - subledger_account (if not empty)' to be sure to have unicity of line (because we may have several lines // with same doc_type, fk_doc, numero_compte for 1 invoice line when using localtaxes with same account) // WARNING: This is not reliable, label may have been modified. This is just a small protection. // The page that make transfer make the test on couple (doc_type - fk_doc) only. @@ -338,6 +339,9 @@ class BookKeeping extends CommonObject } $sql .= " AND numero_compte = '".$this->db->escape($this->numero_compte)."'"; $sql .= " AND label_operation = '".$this->db->escape($this->label_operation)."'"; + if (!empty($this->subledger_account)) { + $sql .= " AND subledger_account = '".$this->db->escape($this->subledger_account)."'"; + } $sql .= " AND entity = ".$conf->entity; // Do not use getEntity for accounting features $resql = $this->db->query($sql); @@ -2863,10 +2867,8 @@ class BookKeeping extends CommonObject $sql = 'SELECT'; $sql .= " t.numero_compte,"; - $sql .= " t.label_compte,"; if ($separate_auxiliary_account) { - $sql .= " t.subledger_account,"; - $sql .= " t.subledger_label,"; + $sql .= " NULLIF(t.subledger_account, '') as subledger_account,"; // fix db issues with Null or "" values } $sql .= " aa.pcg_type,"; $sql .= " (SUM(t.credit) - SUM(t.debit)) as opening_balance"; @@ -2878,10 +2880,11 @@ class BookKeeping extends CommonObject $sql .= ' AND aa.pcg_type IN (' . $this->db->sanitize(implode(',', $pcg_type_filter), 1) . ')'; $sql .= " AND DATE(t.doc_date) >= '" . $this->db->idate($fiscal_period->date_start) . "'"; $sql .= " AND DATE(t.doc_date) <= '" . $this->db->idate($fiscal_period->date_end) . "'"; - $sql .= ' GROUP BY t.numero_compte, t.label_compte, aa.pcg_type'; + $sql .= ' GROUP BY t.numero_compte, aa.pcg_type'; if ($separate_auxiliary_account) { - $sql .= ' ,t.subledger_account, t.subledger_label'; + $sql .= " , NULLIF(t.subledger_account, '')"; } + $sql .= ' HAVING (SUM(t.credit) - SUM(t.debit)) != 0 '; // Exclude rows with opening_balance = 0 $sql .= $this->db->order("t.numero_compte", "ASC"); $resql = $this->db->query($sql); @@ -2902,24 +2905,41 @@ class BookKeeping extends CommonObject $bookkeeping = new BookKeeping($this->db); $bookkeeping->doc_date = $new_fiscal_period->date_start; - $bookkeeping->date_lim_reglement = 0; - $bookkeeping->doc_ref = $new_fiscal_period->label; + + $bookkeeping->date_lim_reglement = ''; + $bookkeeping->doc_ref = $fiscal_period->label; + $bookkeeping->date_creation = $now; $bookkeeping->doc_type = 'closure'; - $bookkeeping->fk_doc = $new_fiscal_period->id; + $bookkeeping->fk_doc = $fiscal_period->id; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = ''; if ($separate_auxiliary_account) { $bookkeeping->subledger_account = $obj->subledger_account; - $bookkeeping->subledger_label = $obj->subledger_label; + $sql = 'SELECT'; + $sql .= " subledger_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'"; + $sql .= " ORDER BY doc_date DESC"; + $sql .= " LIMIT 1"; + $result = $this->db->query($sql); + if (!$result) { + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + $error++; + } + $objtmp = $this->db->fetch_object($result); + $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used } else { - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + $bookkeeping->subledger_account = null; + $bookkeeping->subledger_label = null; } $bookkeeping->numero_compte = $obj->numero_compte; - $bookkeeping->label_compte = $obj->label_compte; + $accountingaccount = new AccountingAccount($this->db); + $accountingaccount->fetch(0, $obj->numero_compte); + $bookkeeping->label_compte = $accountingaccount->label; // latest account label used $bookkeeping->label_operation = $new_fiscal_period->label; $bookkeeping->montant = $mt; @@ -2933,8 +2953,7 @@ class BookKeeping extends CommonObject $result = $bookkeeping->create($user); if ($result < 0) { - $this->error = $bookkeeping->error; - $this->errors = $bookkeeping->errors; + $this->setErrorsFromObject($bookkeeping); $error++; break; } @@ -2949,21 +2968,35 @@ class BookKeeping extends CommonObject $bookkeeping = new BookKeeping($this->db); $bookkeeping->doc_date = $new_fiscal_period->date_start; - $bookkeeping->date_lim_reglement = 0; - $bookkeeping->doc_ref = $new_fiscal_period->label; + + $bookkeeping->date_lim_reglement = ''; + $bookkeeping->doc_ref = $fiscal_period->label; + $bookkeeping->date_creation = $now; $bookkeeping->doc_type = 'closure'; - $bookkeeping->fk_doc = $new_fiscal_period->id; + $bookkeeping->fk_doc = $fiscal_period->id; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = ''; if ($separate_auxiliary_account) { - $bookkeeping->subledger_label = ''; $bookkeeping->subledger_account = $obj->subledger_account; - $bookkeeping->subledger_label = $obj->subledger_label; + $sql = 'SELECT'; + $sql .= " subledger_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'"; + $sql .= " ORDER BY doc_date DESC"; + $sql .= " LIMIT 1"; + $result = $this->db->query($sql); + if (!$result) { + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); + $error++; + } + $objtmp = $this->db->fetch_object($result); + $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used } else { - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + $bookkeeping->subledger_account = null; + $bookkeeping->subledger_label = null; } $bookkeeping->numero_compte = $accountingaccount->account_number; @@ -2981,8 +3014,7 @@ class BookKeeping extends CommonObject $result = $bookkeeping->create($user); if ($result < 0) { - $this->error = $bookkeeping->error; - $this->errors = $bookkeeping->errors; + $this->setErrorsFromObject($bookkeeping); $error++; } } diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index ecf9ce56121..2b166dff8d9 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -461,12 +461,12 @@ SELECT fk_facture, COUNT(fd.rowid) as nb FROM - ".MAIN_DB_PREFIX."facturedet as fd + ".MAIN_DB_PREFIX."facturedet as fd WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0 AND fd.total_ttc <> 0 - AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).") + AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).") GROUP BY fk_facture "; $resql = $db->query($sql); diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 0910e85b9d3..c4ea3c8fbce 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1351,7 +1351,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // EMail print ''; - print ''; + print ''; // Website print ''; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 26833536fee..a401823fc3c 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -236,12 +236,12 @@ class Adherent extends CommonObject public $need_subscription; /** - * @var int user_id + * @var int|null user_id */ public $user_id; /** - * @var string user_login + * @var string|null user_login */ public $user_login; @@ -254,32 +254,32 @@ class Adherent extends CommonObject // Fields loaded by fetch_subscriptions() from member table /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_date; /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_date_start; /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_date_end; /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_amount; /** - * @var int|string date + * @var int|string|null date */ public $last_subscription_date; /** - * @var int|string date + * @var int|string|null date */ public $last_subscription_date_start; diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 26c7594192c..21f24487c24 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -235,10 +235,10 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa $massaction = ''; } -$permissiontoread = ($user->hasRight('adherent', 'lire') == 1); -$permissiontodelete = ($user->hasRight('adherent', 'supprimer') == 1); -$permissiontoadd = ($user->hasRight('adherent', 'creer') == 1); -$uploaddir = $conf->adherent->dir_output; +$permissiontoread = $user->hasRight('adherent', 'lire'); +$permissiontodelete = $user->hasRight('adherent', 'supprimer'); +$permissiontoadd = $user->hasRight('adherent', 'creer'); +$uploaddir = $conf->member->dir_output; $error = 0; $parameters = array('socid' => isset($socid) ? $socid : null, 'arrayfields' => &$arrayfields); diff --git a/htdocs/adherents/messaging.php b/htdocs/adherents/messaging.php index af48d7cf822..de637315753 100644 --- a/htdocs/adherents/messaging.php +++ b/htdocs/adherents/messaging.php @@ -81,7 +81,10 @@ if (!$sortfield) { if (!$sortorder) { $sortorder = 'DESC,DESC'; } - +$socid = GETPOSTINT('socid'); +if ($user->socid > 0) { + $socid = $user->socid; +} // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $hookmanager->initHooks(array('agendathirdparty', 'globalcard')); diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 3b7b80d6935..069f89de048 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -179,35 +179,33 @@ if (empty($reshook) && $action == 'setuserid' && ($user->hasRight('user', 'self' if (empty($reshook) && $action == 'setsocid' && $permissiontoaddmember) { $error = 0; - if (!$error) { - if (GETPOSTINT('socid') != $object->socid) { // If link differs from currently in database - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql .= " WHERE fk_soc = ".((int) GETPOSTINT('socid')); - $resql = $db->query($sql); - if ($resql) { - $obj = $db->fetch_object($resql); - if ($obj && $obj->rowid > 0) { - $othermember = new Adherent($db); - $othermember->fetch($obj->rowid); - $thirdparty = new Societe($db); - $thirdparty->fetch(GETPOSTINT('socid')); - $error++; - setEventMessages($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty", $othermember->getFullName($langs), $othermember->login, $thirdparty->name), null, 'errors'); - } + if (GETPOSTINT('socid') != $object->socid) { // If link differs from currently in database + $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "adherent"; + $sql .= " WHERE fk_soc = " . ((int) GETPOSTINT('socid')); + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj && $obj->rowid > 0) { + $othermember = new Adherent($db); + $othermember->fetch($obj->rowid); + $thirdparty = new Societe($db); + $thirdparty->fetch(GETPOSTINT('socid')); + $error++; + setEventMessages($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty", $othermember->getFullName($langs), $othermember->login, $thirdparty->name), null, 'errors'); } + } - if (!$error) { - $result = $object->setThirdPartyId(GETPOSTINT('socid')); - if ($result < 0) { - dol_print_error(null, $object->error); - } - $action = ''; + if (!$error) { + $result = $object->setThirdPartyId(GETPOSTINT('socid')); + if ($result < 0) { + dol_print_error(null, $object->error); } + $action = ''; } } } -if ($user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscription' && !$cancel) { +if (empty($reshook) && $user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscription' && !$cancel) { $error = 0; $langs->load("banks"); @@ -701,7 +699,7 @@ if ($user->hasRight('adherent', 'cotisation', 'creer')) { if ($action != 'addsubscription' && $action != 'create_thirdparty') { print '
'; - if ($object->statut > 0) { + if ($object->status > 0) { print '"; } else { print ''; diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index aa50ccc6a4f..c34a84824cc 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -63,7 +63,7 @@ $search_login = GETPOST('search_login', 'alpha'); $search_note = GETPOST('search_note', 'alpha'); $search_account = GETPOST('search_account', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); -$search_all = ''; +$search_all = trim(GETPOST('search_all', 'alphanohtml')); $date_select = GETPOST("date_select", 'alpha'); @@ -98,6 +98,8 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // List of fields to search into when doing a "search in all" $fieldstosearchall = array( + 'c.rowid' => 'Ref', + 'c.note' => "Label", ); $arrayfields = array( 'd.ref' => array('label' => "Ref", 'checked' => 1), @@ -105,7 +107,7 @@ $arrayfields = array( 'd.lastname' => array('label' => "Lastname", 'checked' => 1), 'd.firstname' => array('label' => "Firstname", 'checked' => 1), 'd.login' => array('label' => "Login", 'checked' => 1), - 't.libelle' => array('label' => "Label", 'checked' => 1), + 'c.note' => array('label' => "Label", 'checked' => 1), 'd.bank' => array('label' => "BankAccount", 'checked' => 1, 'enabled' => (isModEnabled('bank'))), /*'d.note_public'=>array('label'=>"NotePublic", 'checked'=>0), 'd.note_private'=>array('label'=>"NotePrivate", 'checked'=>0),*/ @@ -166,7 +168,7 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Subscription'; $objectlabel = 'Subscription'; - $uploaddir = $conf->adherent->dir_output; + $uploaddir = $conf->member->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -395,7 +397,6 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($search_all) { $setupstring = ''; - // @phan-suppress-next-line PhanEmptyForeach foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); $setupstring .= $key."=".$val.";"; @@ -474,7 +475,7 @@ if (!empty($arrayfields['d.login']['checked'])) { print ''; } -if (!empty($arrayfields['t.libelle']['checked'])) { +if (!empty($arrayfields['c.note']['checked'])) { print '
'; @@ -557,8 +558,8 @@ if (!empty($arrayfields['d.login']['checked'])) { print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder); $totalarray['nbfield']++; } -if (!empty($arrayfields['t.libelle']['checked'])) { - print_liste_field_titre($arrayfields['t.libelle']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder); +if (!empty($arrayfields['c.note']['checked'])) { + print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder); $totalarray['nbfield']++; } if (!empty($arrayfields['d.bank']['checked'])) { @@ -725,7 +726,7 @@ while ($i < $imaxinloop) { } // Label - if (!empty($arrayfields['t.libelle']['checked'])) { + if (!empty($arrayfields['c.note']['checked'])) { print ''; diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 5353b59b5ea..e3d08bb29cb 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -457,6 +457,21 @@ print ''."\n"; +// Main currency +print ''."\n"; + +// Country +print ''."\n"; + // Address print ''."\n"; @@ -468,15 +483,7 @@ print ''."\n"; -// Country -print ''."\n"; - +// State print ''."\n"; -// Currency -print ''."\n"; - // Phone print ''; +// Object of the company +print ''; +print ''; + +// Tax ID Intra-community VAT number +print ''; + // ProfId1 if ($langs->transcountry("ProfId1", $mysoc->country_code) != '-') { print ''; } -// Intra-community VAT number -print ''; - -// Object of the company -print ''; -print ''; - print '
Commit IDDateReported on
Yogosha
Reported on
GIT
Reported on
CVE
TitleBranch of fix
Commit IDDateReported on
Yogosha
Reported on
GIT
Reported on
CVE
TitleBranch of fix
'.(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '' : '').$langs->trans("EMail").(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '' : '').''.img_picto('', 'object_email', 'class="pictofixedwidth"').'email).'">
'.img_picto('', 'object_email', 'class="pictofixedwidth"').'email).'">
'.$form->editfieldkey('Web', 'member_url', GETPOST('member_url', 'alpha'), $object, 0).''; print ''; print ''; print dol_escape_htmltag(dolGetFirstLineOfText($obj->note_private)); print '
'.$langs-> print '
'; print '
'; +print img_picto('', 'multicurrency', 'class="pictofixedwidth"'); +print $form->selectCurrency($conf->currency, "currency"); +print '
'; +print img_picto('', 'globe-americas', 'class="pictofixedwidth"'); +print $form->select_country($mysoc->country_id, 'country_id', '', 0); +if ($user->admin) { + print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); +} +print '
'; print '
'; print '
'; -print img_picto('', 'globe-americas', 'class="pictofixedwidth"'); -print $form->select_country($mysoc->country_id, 'country_id', '', 0); -if ($user->admin) { - print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); -} -print '
'; $state_id = 0; if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) { @@ -487,12 +494,6 @@ print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($state_id, $mysoc->country_code, 'state_id', 'maxwidth200onsmartphone minwidth300'); print '
'; -print img_picto('', 'multicurrency', 'class="pictofixedwidth"'); -print $form->selectCurrency($conf->currency, "currency"); -print '
'; print img_picto('', 'object_phoning', '', 0, 0, 0, '', 'pictofixedwidth'); @@ -604,6 +605,16 @@ if ($mysoc->country_code) { } print '
'; +print '
'; +print ''; +print '
'; @@ -714,16 +725,6 @@ if ($langs->transcountry("ProfId10", $mysoc->country_code) != '-') { print '
'; -print ''; -print '
'; -print '
'; print '
'; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index ffabe10d68d..360488a2410 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -8,7 +8,7 @@ * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2023 Alexandre Spangaro + * Copyright (C) 2011-2024 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019-2024 Frédéric France @@ -723,10 +723,8 @@ if ($id == DICT_TYPE_CONTACT) { 'supplier_proposal' => img_picto('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans('SupplierProposal'), 'order_supplier' => img_picto('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans('SupplierOrder'), 'invoice_supplier' => img_picto('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans('SupplierBill'), + 'conferenceorbooth' => img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'), ); - if (getDolGlobalString('MAIN_FEATURES_LEVEL') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { - $elementList['conferenceorbooth'] = img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'); - } complete_elementList_with_modules($elementList); diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index b296f65a876..51422388cd4 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -195,8 +195,11 @@ if ($action == 'set') { dolibarr_set_const($db, "SUPPLIER_PROPOSAL_ADDON", $value, 'chaine', 0, '', $conf->entity); } elseif (preg_match('/set_(.*)/', $action, $reg)) { $code = $reg[1]; - $value = (GETPOST($code) ? GETPOST($code) : 1); - + if ($code == "SUPPLIER_PROPOSAL_FREE_TEXT") { + $value = (GETPOST($code, 'restricthtml') ? GETPOST($code, 'restricthtml') : 1); + } else { + $value = (GETPOST($code) ? GETPOST($code) : 1); + } $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 584f6c36a7f..4de7133c9e6 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 Frédéric 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 @@ -57,6 +58,7 @@ class Documentation * Constructor * * @param DoliDB $db Database handler + * @return void */ public function __construct(DoliDB $db) { @@ -75,7 +77,6 @@ class Documentation */ private function setMenu() { - global $hookmanager; @@ -223,7 +224,8 @@ class Documentation } /** - * Output sidebar + * Output sidebar + * * @return void */ public function showSidebar() @@ -312,7 +314,8 @@ class Documentation } /** - * Output summary + * Output summary + * * @param int $showsubmenu Show Sub menus: 0 = No, 1 = Yes * @param int $showsubmenu_summary Show summary of sub menus: 0 = No, 1 = Yes * @return void @@ -320,6 +323,7 @@ class Documentation public function showSummary($showsubmenu = 1, $showsubmenu_summary = 1) { $i = 0; + $menu_entry = []; if (!empty($this->view)) : // On se place au bon niveau foreach ($this->view as $view) { @@ -384,16 +388,16 @@ class Documentation * Output a View Code area * * @param array $lines Lines of code to show + * @param string $option Source code language ('html', 'php' etc) * @return void */ - public function showCode($lines = array()) + public function showCode($lines = array(), $option = 'html') { - print '
';
-		if (!empty($lines)) {
-			foreach ($lines as $lineofcode) {
-				print dol_htmlentities($lineofcode).'
'; - } - } - print '
'; + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + print '
'; + $content = implode("\n", $lines) . "\n"; + $doleditor = new DolEditor(md5($content), $content, '', 0, 'Basic', 'In', true, false, 'ace', 0, '99%', 1); + print $doleditor->Create(1, '', false, '', $option); + print '
'; } } diff --git a/htdocs/admin/tools/ui/components/badges.php b/htdocs/admin/tools/ui/components/badges.php index e47b8090ce4..0d147b603be 100644 --- a/htdocs/admin/tools/ui/components/badges.php +++ b/htdocs/admin/tools/ui/components/badges.php @@ -1,36 +1,39 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -38,8 +41,13 @@ $langs->load('uxdocumentation'); // $documentation = new Documentation($db); +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('Badges'); +$documentation->docHeader('Badges', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -49,7 +57,7 @@ $documentation->view = array('Components','Badges'); $documentation->showSidebar(); ?>
- + showBreadCrumb(); ?>
@@ -310,4 +318,4 @@ $documentation->showSidebar(); ?> docFooter(); -?> \ No newline at end of file +?> diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index 1ad142730f0..0fe09e06d02 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -1,45 +1,52 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); // $documentation = new Documentation($db); - +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('Buttons'); +$documentation->docHeader('Buttons', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -128,7 +135,7 @@ $documentation->showSidebar(); ?> ' */', 'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?>
@@ -144,7 +151,7 @@ $documentation->showSidebar(); ?> $id = 'button-id-7'; $url = '#'.$id; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -170,7 +177,7 @@ $documentation->showSidebar(); ?> $id = 'button-id-9'; $url = '#'.$id; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); ?>
@@ -179,7 +186,7 @@ $documentation->showSidebar(); ?> ' true', + ' \'confirm\' => [],', ');', '', '// Custom parameters', @@ -189,13 +196,13 @@ $documentation->showSidebar(); ?> ' \'title\' => \'Your title to display\',', ' \'action-btn-label\' => \'Your confirm label\',', ' \'cancel-btn-label\' => \'Your cancel label\',', - ' \'content\' => \'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
\'', + ' \'content\' => \'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
\',', ' )', ');', '', 'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?>
@@ -214,13 +221,15 @@ $documentation->showSidebar(); ?> 'lang'=>'documentation@documentation', 'url'=> $submenu_url.'#'.$id, 'label' => 'My SubAction 1', - 'perm' => 1 + 'perm' => true, + 'enabled' => true, ), array( 'lang'=>'documentation@documentation', 'url'=> $submenu_url.'#'.$id, 'label' => 'My SubAction 2', - 'perm' => 0 + 'perm' => false, + 'enabled' => true, ), ); $params = array(); @@ -250,7 +259,7 @@ $documentation->showSidebar(); ?> ');', 'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);' ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -277,7 +286,7 @@ $documentation->showSidebar(); ?> 'print \' \';', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -313,18 +322,16 @@ $documentation->showSidebar(); ?> 'print dolGetButtonTitle($btnLabel, \'\', \'fa fa-file\', \'#\', \'\', $status);', ); - echo $documentation->showCode($lines); ?>
+ echo $documentation->showCode($lines, 'php'); ?>
trans('Label'); + $btnLabel = $langs->trans('Label', 'php'); print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 0, ['forcenohideoftext'=>1]); // Not Enough Permissions print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 1, ['forcenohideoftext'=>1]); // Active print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 2, ['forcenohideoftext'=>1]); // Active and selected print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', -1, ['forcenohideoftext'=>1]); // Functionality is disabled print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', -2, ['forcenohideoftext'=>1]); // Disabled without info - ?>
@@ -343,15 +350,9 @@ $documentation->showSidebar(); ?> '$status = -2; // Disabled without info', 'print dolGetButtonTitle($btnLabel, \'\', \'fa fa-download\', \'#\', \'\', $status, [\'forcenohideoftext\'=>1]);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?>
- - - - - - diff --git a/htdocs/admin/tools/ui/components/event-message.php b/htdocs/admin/tools/ui/components/event-message.php index 98e3080c7d3..f612f05a0c2 100644 --- a/htdocs/admin/tools/ui/components/event-message.php +++ b/htdocs/admin/tools/ui/components/event-message.php @@ -1,37 +1,39 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -55,9 +57,13 @@ if ($action == 'displayeventmessage') { // $documentation = new Documentation($db); - +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('SetEventMessages'); +$documentation->docHeader('SetEventMessages', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -121,7 +127,7 @@ $documentation->showSidebar(); ?> 'setEventMessages("message", null);', 'setEventMessages(null, messages[]);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -156,11 +162,12 @@ $documentation->showSidebar(); ?> showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> diff --git a/htdocs/admin/tools/ui/components/index.php b/htdocs/admin/tools/ui/components/index.php index 32af131fb91..409d96d22a7 100644 --- a/htdocs/admin/tools/ui/components/index.php +++ b/htdocs/admin/tools/ui/components/index.php @@ -1,36 +1,39 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -48,7 +51,7 @@ $documentation->view = array('Components'); $documentation->showSidebar(); ?>
- + showBreadCrumb(); ?>
@@ -56,11 +59,11 @@ $documentation->showSidebar(); ?>

trans('DocComponentsTitle'); ?>

trans('DocComponentsMainDescription'); ?>

- showSummary(); ?> + showSummary(); ?>
docFooter(); -?> \ No newline at end of file +?> diff --git a/htdocs/admin/tools/ui/components/progress-bars.php b/htdocs/admin/tools/ui/components/progress-bars.php index f860fabb579..fda0b0527fc 100644 --- a/htdocs/admin/tools/ui/components/progress-bars.php +++ b/htdocs/admin/tools/ui/components/progress-bars.php @@ -1,36 +1,39 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -38,8 +41,13 @@ $langs->load('uxdocumentation'); // $documentation = new Documentation($db); +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('Progress-bars'); +$documentation->docHeader('Progress-bars', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -247,6 +255,7 @@ $documentation->showSidebar(); ?> '
', '', '', + '', ); echo $documentation->showCode($lines); ?> diff --git a/htdocs/admin/tools/ui/components/test_arrays.php b/htdocs/admin/tools/ui/components/test_arrays.php index 8954e0cd7a3..0e02e1b8885 100644 --- a/htdocs/admin/tools/ui/components/test_arrays.php +++ b/htdocs/admin/tools/ui/components/test_arrays.php @@ -1,17 +1,43 @@ + * + * 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 . */ // Load Dolibarr environment -@include '../../main.inc.php'; +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + * + * @var int $dolibarr_main_prod + */ // Security if ($dolibarr_main_prod) { accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1'); } +// Protection if external user +if ($user->socid > 0) { + accessforbidden(); +} - +$optioncss = GETPOST('optioncsss', 'alpha'); /* * View @@ -19,7 +45,9 @@ if ($dolibarr_main_prod) { $form = new Form($db); -$usedolheader = 1; // 1 = Test inside a dolibarr page, 0 = Use hard coded header +// 1 = Test inside a dolibarr page, 0 = Use hard coded header +// Using a dolibarr constant avoid phpstan hardcoded value always true or false +$usedolheader = getDolGlobalInt('MAIN_TEST_UI_IN_DOLIBARR_PAGE', 1); // HEADER //-------- @@ -163,15 +191,14 @@ $productspecimen = new Product($db); $productspecimen->initAsSpecimen(); $object = $productspecimen; $param = ''; -$actioncode = ''; -$status = ''; -$filter = ''; -$filtert = ''; -$socid = 0; -$type = 0; -$usergroup = 0; - -$sortfield = 'aaa'; +$actioncode = getDolGlobalString('MAIN_TEST_UI_ACTION_CODE'); // '' by default +$status = getDolGlobalString('MAIN_TEST_UI_STATUS'); // '' by default; +$filter = getDolGlobalString('MAIN_TEST_UI_FILTER'); // '' by default; +$filtert = getDolGlobalString('MAIN_TEST_UI_FILTERT'); // '' by default; +$socid = getDolGlobalInt('MAIN_TEST_UI_SOCID', 0); // 0 by default; +$type = getDolGlobalInt('MAIN_TEST_UI_TYPE', 0); // 0 by default; +$usergroup = getDolGlobalInt('MAIN_TEST_UI_USERGROUP', 0); // 0 by default; +$sortfield = getDolGlobalString('MAIN_TEST_UI_SORTFIELD', 'aaa'); // 'aaa' by default; $sortorder = 'ASC'; $tasksarray = array(1, 2, 3); // To force having several lines $tagidfortablednd = 'tablelines3'; @@ -242,18 +269,16 @@ $cate_arbo = array('field1' => 'value1d into the select list D', 'field2' => 'va $moreforfilter .= $form->selectarray('search_ddd', $cate_arbo, '', 1, 0, 0, '', 0, 0, 0, '', 'maxwidth300', 1); // List with js combo forced $moreforfilter .= ''; -if (!empty($moreforfilter)) { - print '
'; - print $moreforfilter; - $parameters = array(); - $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print '
'; -} +print '
'; +print $moreforfilter; +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +print '
'; ?> -" id="tablelines3"> +
" id="tablelines3"> trans('title1'), 0, $_SERVER["PHP_SELF"], 'aaa', '', '', 'align="left"', $sortfield, $sortorder); ?> diff --git a/htdocs/admin/tools/ui/components/test_buttons.php b/htdocs/admin/tools/ui/components/test_buttons.php index 8eef7aa0b6c..449196c25a2 100644 --- a/htdocs/admin/tools/ui/components/test_buttons.php +++ b/htdocs/admin/tools/ui/components/test_buttons.php @@ -1,4 +1,20 @@ + * + * 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 . + */ + if (!defined('NOREQUIRESOC')) { define('NOREQUIRESOC', '1'); } @@ -25,9 +41,18 @@ if (!defined('NOREQUIREMENU')) { } session_cache_limiter('public'); -require_once '../../main.inc.php'; +require '../../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + * + * @var int $dolibarr_main_prod + */ + // Security if ($dolibarr_main_prod) { accessforbidden(); @@ -129,7 +154,7 @@ llxHeader('', 'Documentation and examples for theme'); $url = '#'.$id; $userRight = 1; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -142,13 +167,13 @@ llxHeader('', 'Documentation and examples for theme'); $url = $_SERVER['PHP_SELF'] . '?token='.newToken().'#'.$id; $params = array( - 'confirm' => array( + 'confirm' => array( 'url' => 'your confirm action url', 'title' => 'Your title to display', 'action-btn-label' => 'Your confirm label', 'cancel-btn-label' => 'Your cancel label', - 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
' - ) + 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
', + ) ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -168,7 +193,7 @@ llxHeader('', 'Documentation and examples for theme'); $url = '#'.$id; $userRight = 0; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -181,13 +206,13 @@ llxHeader('', 'Documentation and examples for theme'); $url = $_SERVER['PHP_SELF'] . '?token='.newToken().'#'.$id; $params = array( - 'confirm' => array( + 'confirm' => array( 'url' => 'your confirm action url', 'title' => 'Your title to display', 'action-btn-label' => 'Your confirm label', 'cancel-btn-label' => 'Your cancel label', - 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
' - ) + 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
', + ) ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); diff --git a/htdocs/admin/tools/ui/components/test_forms.php b/htdocs/admin/tools/ui/components/test_forms.php index 60f351eb994..60c32389b0d 100644 --- a/htdocs/admin/tools/ui/components/test_forms.php +++ b/htdocs/admin/tools/ui/components/test_forms.php @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + define("NOCSRFCHECK", 1); // We accept to go on this page from external web site. //define("NOLOGIN",1); // This means this output page does not require to be logged. /*if (!defined('NOSESSION')) { @@ -21,9 +22,18 @@ define("NOCSRFCHECK", 1); // We accept to go on this page from external web site }*/ // Load Dolibarr environment -require '../../main.inc.php'; +require '../../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + * + * @var int $dolibarr_main_prod + */ + // Security if ($dolibarr_main_prod) { accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1'); diff --git a/htdocs/admin/tools/ui/content/tables.php b/htdocs/admin/tools/ui/content/tables.php index 00fd9bbf666..9ab70ba6f38 100644 --- a/htdocs/admin/tools/ui/content/tables.php +++ b/htdocs/admin/tools/ui/content/tables.php @@ -1,32 +1,31 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) { - $res=@include '../../main.inc.php'; -} -if (! $res && file_exists("../../../main.inc.php")) { - $res=@include '../../../main.inc.php'; -} -if (! $res && file_exists("../../../../main.inc.php")) { - $res=@include '../../../../main.inc.php'; -} +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user if ($user->socid > 0) { @@ -34,7 +33,7 @@ if ($user->socid > 0) { } // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); diff --git a/htdocs/admin/tools/ui/index.php b/htdocs/admin/tools/ui/index.php index 2e64da27e4e..76baca72436 100644 --- a/htdocs/admin/tools/ui/index.php +++ b/htdocs/admin/tools/ui/index.php @@ -1,36 +1,38 @@ + * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../main.inc.php")) : $res=@include '../main.inc.php'; -endif; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -48,7 +50,7 @@ $documentation->view = array('DocumentationHome'); $documentation->showSidebar(); ?>
- + showBreadCrumb(); ?>
@@ -61,4 +63,4 @@ $documentation->showSidebar(); ?> docFooter(); -?> \ No newline at end of file +?> diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index 52275a3f80b..8979ee62e67 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -456,6 +456,8 @@ if ($id) { print '
'; print ''; + + print '
'; print '
'; // Form to add a new line @@ -471,12 +473,12 @@ if ($id) { // dans les dictionnaires de donnees $valuetoshow = ucfirst($fieldlist[$field]); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate - $align = ''; + $css = ''; if ($fieldlist[$field] == 'lang') { $valuetoshow = $langs->trans("Language"); } if ($valuetoshow != '') { - print '
'; + print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { @@ -523,6 +525,8 @@ if ($id) { } print '
'; + print ''; + print ''; @@ -631,15 +635,24 @@ if ($id) { foreach ($fieldlist as $field => $value) { $showfield = 1; $fieldname = $fieldlist[$field]; - $align = "left"; + $css = ""; + if ($fieldlist[$field] == 'description') { + $css .= ' tdoverflowmax300'; + } if (in_array($fieldname, array('pageviews_total', 'pageviews_previous_month'))) { - $align = 'right'; + $css = 'right'; + } + if ($fieldlist[$field] == 'date_creation') { + $css .= ' nowraponall'; + } + if ($fieldlist[$field] == 'lastaccess') { + $css .= ' nowraponall'; } $valuetoshow = $obj->$fieldname; // Show value for field if ($showfield) { - print ''.$valuetoshow.''; + print ''.$valuetoshow.''; } } } diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 7d1ffa9e609..702c0f68e9b 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -585,7 +585,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $tmparray = $object->product->getSellPrice($mysoc, $mysoc); $manufacturedvalued = $tmparray['pu_ht'] * $object->qty; } - print ''.$langs->trans("ManufacturingGeneratedValue").''.price($manufacturedvalued).''; + print ''.$langs->trans("ManufacturingGeneratedValue").''.price($manufacturedvalued).''; // Other attributes include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index e7f8a9b1139..010f405e549 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1546,8 +1546,8 @@ if ($action == 'create') { $listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing } } - print '
'; - print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid); + print '
'; + print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid); print '
'; print ''; @@ -1811,7 +1811,7 @@ if ($action == 'create') { print "\n".''."\n"; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index a291083bf62..3e9aff3b1f1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -689,7 +689,7 @@ class Form $paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribute to put on td text tag } if ($tooltipon == 1 || $tooltipon == 3) { - $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" '; + $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ($tag != 'td' ? ' inline-block' : '') . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" '; if ($tooltiptrigger == '') { $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribute to put on td tag to store tooltip } else { @@ -1149,15 +1149,16 @@ class Form * Return list of types of lines (product or service) * Example: 0=product, 1=service, 9=other (for external module) * - * @param string $selected Preselected type - * @param string $htmlname Name of field in html form - * @param int<0,1>|string $showempty Add an empty field - * @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select) - * @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service') - * @param string $morecss More css + * @param string $selected Preselected type + * @param string $htmlname Name of field in html form + * @param int<0,1>|string $showempty Add an empty field + * @param int $hidetext Do not show label 'Type' before combo box (used only if there is at least 2 choices to select) + * @param integer $forceall 1=Force to show products and services in combo list, whatever are activated modules, 0=No force, 2=Force to show only Products, 3=Force to show only services, -1=Force none (and set hidden field to 'service') + * @param string $morecss More css + * @param int $useajaxcombo 1=Use ajaxcombo * @return void */ - public function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0, $morecss = "") + public function select_type_of_lines($selected = '', $htmlname = 'type', $showempty = 0, $hidetext = 0, $forceall = 0, $morecss = "", $useajaxcombo = 1) { // phpcs:enable global $langs; @@ -1166,11 +1167,11 @@ class Form if ($forceall == 1 || (empty($forceall) && isModEnabled("product") && isModEnabled("service")) || (empty($forceall) && !isModEnabled('product') && !isModEnabled('service'))) { if (empty($hidetext)) { - print $langs->trans("Type") . ': '; + print $langs->trans("Type").'...'; } print ''; - print ajax_combobox('select_' . $htmlname); + + if ($useajaxcombo) { + print ajax_combobox('select_' . $htmlname); + } //if ($user->admin) print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"),1); } if ((empty($forceall) && !isModEnabled('product') && isModEnabled("service")) || $forceall == 3) { @@ -1482,7 +1486,7 @@ class Form * If you need parenthesis, use the Universal Filter Syntax, example: '(s.client:in:1,3)' * Do not use a filter coming from input of users. * @param string|int<0,1> $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') - * @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier) + * @param int<0,1> $showtype Show third party nature in combolist (customer, prospect or supplier) * @param int $forcecombo Force to use standard HTML select component without beautification * @param array}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param string $filterkey Filter on key value @@ -1502,6 +1506,8 @@ class Form global $user, $langs; global $hookmanager; + $langs->loadLangs(array("companies", "suppliers")); + $out = ''; $num = 0; $outarray = array(); @@ -2228,7 +2234,17 @@ class Form $sql .= " AND u.fk_soc IS NULL"; } if (!empty($morefilter)) { - $sql .= " " . $morefilter; + $errormessage = ''; + $sql .= forgeSQLFromUniversalSearchCriteria($morefilter, $errormessage); + if ($errormessage) { + $this->errors[] = $errormessage; + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + if ($outputmode == 0) { + return 'Error bad param $morefilter'; + } else { + return array(); + } + } } //Add hook to filter on user (for example on usergroup define in custom modules) @@ -2425,28 +2441,29 @@ class Form * Return select list of users. Selected users are stored into session. * List of users are provided into $_SESSION['assignedtouser']. * - * @param string $action Value for $action - * @param string $htmlname Field name in form - * @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value - * @param int[] $exclude Array list of users id to exclude - * @param int<0,1> $disabled If select list must be disabled - * @param int[]|string $include Array list of users id to include or 'hierarchy' to have only supervised users - * @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled - * @param string $force_entity '0' or Ids of environment to force - * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status - * @param string $morefilter Add more filters into sql request - * @param int $showproperties Show properties of each attendees - * @param int[] $listofuserid Array with properties of each user - * @param int[] $listofcontactid Array with properties of each contact - * @param int[] $listofotherid Array with properties of each other contact - * @return string HTML select string + * @param string $action Value for $action + * @param string $htmlname Field name in form + * @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value + * @param int[] $exclude Array list of users id to exclude + * @param int<0,1> $disabled If select list must be disabled + * @param int[]|''|'hierarchy'|'hierarchyme' $include Array list of users id to include or 'hierarchy' to have only supervised users + * @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled + * @param string $force_entity '0' or Ids of environment to force + * @param int $maxlength Maximum length of string into list (0=no limit) + * @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param string $morefilter Add more filters into sql request (Example: '(employee:=:1)'). This value must not come from user input. + * @param int $showproperties Show properties of each attendees + * @param int[] $listofuserid Array with properties of each user + * @param int[] $listofcontactid Array with properties of each contact + * @param int[] $listofotherid Array with properties of each other contact + * @param int $canremoveowner 1 if we can remove owner, 0=no way + * @return string HTML select string * @see select_dolgroups() */ - public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array()) + public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array(), $canremoveowner = 1) { // phpcs:enable - global $langs; + global $langs, $user; $userstatic = new User($this->db); $out = ''; @@ -2479,8 +2496,25 @@ class Form $ownerid = $value['id']; $out .= ' (' . $langs->trans("Owner") . ')'; } + // Add picto to delete owner/assignee if ($nbassignetouser > 1 && $action != 'view') { - $out .= ' '; + $canremoveassignee = 1; + if ($i == 0) { + // We are on the owner of the event + if (!$canremoveowner) { + $canremoveassignee = 0; + } + if (!$user->hasRight('agenda', 'allactions', 'create')) { + $canremoveassignee = 0; // Can't remove the owner + } + } else { + // We are not on the owner of the event but on a secondary assignee + } + if ($canremoveassignee) { + // If user has all permission, he should be ableto remove a assignee. + // If user has not all permission, he can onlyremove assignee of other (he can't remove itself) + $out .= ' '; + } } // Show my availability if ($showproperties) { @@ -5096,7 +5130,7 @@ class Form $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { if ($showempty) { - $return .= ''; + $return .= ''; } while ($res = $this->db->fetch_object($resql)) { @@ -5112,6 +5146,8 @@ class Form } } $return .= ''; + + $return .= ajax_combobox($htmlname); } return $return; } @@ -7404,6 +7440,7 @@ class Form $hourend = $hourstart; } } + // Show hour $retstring .= ''; if ($emptyhours) { @@ -7426,7 +7463,7 @@ class Form if ($m) { // Show minutes - $retstring .= ''; + $retstring .= ''; $texte .= ''; $texte .= ''; - $texte .= ''; + $texte .= '
'; $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Product"), $langs->transnoentities("Product")); $tooltip .= $langs->trans("GenericMaskCodes3"); @@ -97,16 +97,16 @@ class mod_codeproduct_elephant extends ModeleProductCode //$tooltip .= '
'.$langs->trans("GenericMaskCodes5b"); // Parametrage du prefix customers - $texte .= ''; - $texte .= ''; + $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; // Parametrage du prefix suppliers - $texte .= ''; - $texte .= ''; + $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= '
'.$langs->trans("Mask").' ('.$langs->trans("ProductCodeModel").'):'.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'.$langs->trans("ProductCodeModel").''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").' ('.$langs->trans("ServiceCodeModel").'):'.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'.$langs->trans("ServiceCodeModel").''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'; @@ -171,7 +171,7 @@ class mod_codeproduct_elephant extends ModeleProductCode */ public function getNextValue($objproduct = null, $type = -1) { - global $db, $conf; + global $db; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; @@ -203,7 +203,7 @@ class mod_codeproduct_elephant extends ModeleProductCode $now = dol_now(); if (getDolGlobalString('PRODUCT_ELEPHANT_ADD_WHERE')) { - $where = ' AND ('.dol_string_nospecial(dol_string_unaccent($conf->global->PRODUCT_ELEPHANT_ADD_WHERE), '_', array(',', '@', '"', "|", ";", ":")).')'; + $where = ' AND ('.dol_string_nospecial(dol_string_unaccent(getDolGlobalString('PRODUCT_ELEPHANT_ADD_WHERE')), '_', array(',', '@', '"', "|", ";", ":")).')'; } $numFinal = get_next_value($db, $mask, 'product', $field, $where, '', $now); @@ -268,10 +268,10 @@ class mod_codeproduct_elephant extends ModeleProductCode // Get Mask value $mask = ''; if ($type == 0) { - $mask = !getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT') ? '' : $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT; + $mask = getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT'); } if ($type == 1) { - $mask = !getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE') ? '' : $conf->global->PRODUCT_ELEPHANT_MASK_SERVICE; + $mask = getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE'); } if (!$mask) { $this->error = 'NotConfigured'; diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 077f7d4aeb1..7b9029cf6b8 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -3,6 +3,7 @@ * Copyright (C) 2011-2022 Laurent Destailleur * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 Charlene Benke * * 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 @@ -281,11 +282,12 @@ if ($disablenofollow) {
"> +file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
- + " name="username" class="flat input-icon-user minwidth150" value="" tabindex="1" autofocus="autofocus" autocapitalize="off" autocomplete="on" spellcheck="false" autocorrect="off" /> @@ -293,7 +295,6 @@ if ($disablenofollow) {
-file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
'/core/modules/security/captcha/'), is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); + $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), (isset($conf->modules_parts['captcha']) && is_array($conf->modules_parts['captcha'])) ? $conf->modules_parts['captcha'] : array()); $fullpathclassfile = ''; foreach ($dirModCaptcha as $dir) { $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2); @@ -334,7 +335,7 @@ if (!empty($captcha)) { $classname = "modCaptcha".ucfirst($captcha); if (class_exists($classname)) { /** @var ModeleCaptcha $captchaobj */ - $captchaobj = new $classname($db, $conf, $langs, $user); + $captchaobj = new $classname($db, $conf, $langs, null); '@phan-var-force ModeleCaptcha $captchaobj'; if (is_object($captchaobj) && method_exists($captchaobj, 'getCaptchaCodeForForm')) { diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index be49279b2ef..96cfc189c13 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -204,7 +204,7 @@ if ($nolinesbefore) { } } - // Free line + // Select type of free line $labelforempty = 1; print ''; // Show radio for the non predefined product @@ -215,10 +215,8 @@ if ($nolinesbefore) { print((GETPOST('prod_entry_mode', 'alpha') == 'free' || getDolGlobalString('MAIN_FREE_PRODUCT_CHECKED_BY_DEFAULT')) ? ' checked' : ''); print '> '; // Show type selector - //print ''.$langs->trans("FreeLineOfType").''; - $labelforempty = $langs->trans("FreeLineOfType"); + $labelforempty = $langs->trans("FreeLineOfType").'...'; print ''; - //print ' '; } else { echo ''; // Show type selector @@ -228,11 +226,10 @@ if ($nolinesbefore) { } else { $labelforempty = $langs->trans("FreeLineOfType"); } - //print ' '; } } - $form->select_type_of_lines(GETPOSTISSET("type") ? GETPOST("type", 'alpha', 2) : -1, 'type', $labelforempty, 1, $forceall, 'minwidth200'); + $form->select_type_of_lines(GETPOSTISSET("type") ? GETPOST("type", 'alpha', 2) : -1, 'type', $labelforempty, 1, $forceall, 'minwidth200', 0); print ''; } // Predefined product/service @@ -281,10 +278,10 @@ if ($nolinesbefore) { if (getDolGlobalString('MAIN_AUTO_OPEN_SELECT2_ON_FOCUS_FOR_CUSTOMER_PRODUCTS')) { ?> '; +//print 'Click'; + print "\n"; diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 9e34f4ba39f..93bc95c0a12 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -52,6 +52,8 @@ * @var Translate $langs * @var User $user * + * @var string $action + * @var int $i * @var 0|1 $forceall * @var int $num * @var 0|1 $senderissupplier diff --git a/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php index 87fd49d1f0e..d6ed6a6383f 100644 --- a/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php @@ -224,7 +224,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers case 'ORDER_CLASSIFY_BILLED': case 'ORDER_SETDRAFT': case 'LINEORDER_INSERT': - case 'LINEORDER_UPDATE': + case 'LINEORDER_MODIFY': case 'LINEORDER_DELETE': break; // Supplier orders @@ -239,7 +239,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'ORDER_SUPPLIER_RECEIVE': // case 'LINEORDER_SUPPLIER_DISPATCH': // case 'LINEORDER_SUPPLIER_CREATE': - // case 'LINEORDER_SUPPLIER_UPDATE': + // case 'LINEORDER_SUPPLIER_MODIFY': // Proposals // case 'PROPAL_CREATE': @@ -251,7 +251,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'PROPAL_CLOSE_REFUSED': // case 'PROPAL_DELETE': // case 'LINEPROPAL_INSERT': - // case 'LINEPROPAL_UPDATE': + // case 'LINEPROPAL_MODIFY': // case 'LINEPROPAL_DELETE': // SupplierProposal @@ -264,7 +264,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED': // case 'SUPPLIER_PROPOSAL_DELETE': // case 'LINESUPPLIER_PROPOSAL_INSERT': - // case 'LINESUPPLIER_PROPOSAL_UPDATE': + // case 'LINESUPPLIER_PROPOSAL_MODIFY': // case 'LINESUPPLIER_PROPOSAL_DELETE': // Contracts @@ -274,7 +274,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'CONTRACT_CLOSE': // case 'CONTRACT_DELETE': // case 'LINECONTRACT_INSERT': - // case 'LINECONTRACT_UPDATE': + // case 'LINECONTRACT_MODIFY': // case 'LINECONTRACT_DELETE': // Bills @@ -288,19 +288,19 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'BILL_DELETE': // case 'BILL_PAYED': // case 'LINEBILL_INSERT': - // case 'LINEBILL_UPDATE': + // case 'LINEBILL_MODIFY': // case 'LINEBILL_DELETE': //Supplier Bill // case 'BILL_SUPPLIER_CREATE': - // case 'BILL_SUPPLIER_UPDATE': + // case 'BILL_SUPPLIER_MODIFY': // case 'BILL_SUPPLIER_DELETE': // case 'BILL_SUPPLIER_PAYED': // case 'BILL_SUPPLIER_UNPAYED': // case 'BILL_SUPPLIER_VALIDATE': // case 'BILL_SUPPLIER_UNVALIDATE': // case 'LINEBILL_SUPPLIER_CREATE': - // case 'LINEBILL_SUPPLIER_UPDATE': + // case 'LINEBILL_SUPPLIER_MODIFY': // case 'LINEBILL_SUPPLIER_DELETE': // Payments @@ -316,7 +316,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // Donation // case 'DON_CREATE': - // case 'DON_UPDATE': + // case 'DON_MODIFY': // case 'DON_DELETE': // Interventions @@ -325,7 +325,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'FICHINTER_VALIDATE': // case 'FICHINTER_DELETE': // case 'LINEFICHINTER_CREATE': - // case 'LINEFICHINTER_UPDATE': + // case 'LINEFICHINTER_MODIFY': // case 'LINEFICHINTER_DELETE': // Members diff --git a/htdocs/datapolicy/admin/setup.php b/htdocs/datapolicy/admin/setup.php index ea3ae94a6d5..5351f256011 100644 --- a/htdocs/datapolicy/admin/setup.php +++ b/htdocs/datapolicy/admin/setup.php @@ -156,21 +156,37 @@ $head = datapolicyAdminPrepareHead(); print dol_get_fiche_head($head, 'settings', '', -1, ''); // Setup page goes here -print ''.$langs->trans("datapolicySetupPage").'
'; -// print $form->textwithpicto('', $langs->trans('DATAPOLICY_Tooltip_SETUP')); +print ''.$langs->trans("datapolicySetupPage").''; +print $form->textwithpicto('', $langs->trans('DATAPOLICY_Tooltip_SETUP', $langs->trans("DATAPOLICYJob"), $langs->transnoentities("CronList"))); +print '
'; +print '
'; print '
'; +// TODO Show the last date of execution of the job DATAPOLICYJob if ($action == 'edit') { print '
'; print ''; print ''; - print ''; - //print ''; + print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table + print '
'.$langs->trans("Parameter").'
'; + + print ''; + print ''; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + } + print ''; foreach ($arrayofparameters as $title => $tab) { - print ''; + print ''; + print ''; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + } + print ''; + foreach ($tab as $key => $val) { print ''; + print ''; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + } + + print ''; } } print '
'.$langs->trans("DelayForAnonymization").''.$langs->trans("DelayForDeletion").'
'.$langs->trans($title).'
'.$langs->trans($title).'
'; print $val['picto']; @@ -184,11 +200,19 @@ if ($action == 'edit') { } print ''; print ajax_combobox($key); - print '
'; + print $langs->trans("FeatureNotYetAvailable"); + print '
'; + print '
'; print $form->buttonsSaveCancel("Save", ''); @@ -196,7 +220,6 @@ if ($action == 'edit') { print '
'; } else { print ''; - //print ''; foreach ($arrayofparameters as $title => $tab) { print ''; diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php index 8421b84c924..21a19ae7ec6 100644 --- a/htdocs/datapolicy/class/datapolicy.class.php +++ b/htdocs/datapolicy/class/datapolicy.class.php @@ -21,6 +21,7 @@ * \file datapolicy/class/datapolicy.class.php * \ingroup datapolicy * \brief Class to manage feature of Data Policy module. + * This class file is not used. */ include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; @@ -61,7 +62,7 @@ class DataPolicy */ public function getAllContactNotInformed() { - global $langs, $conf, $db, $user; + global $langs, $conf, $db; $langs->load("companies"); @@ -69,9 +70,9 @@ class DataPolicy $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as spe ON spe.fk_object = c.rowid"; - $sql .= " WHERE (c.statut=1 AND c.no_email=0 AND (spe.datapolicy_consentement=0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement=0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection=0 OR spe.datapolicy_opposition_prospection IS NULL))"; + $sql .= " WHERE (c.statut = 1 AND c.no_email = 0 AND (spe.datapolicy_consentement = 0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement = 0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection = 0 OR spe.datapolicy_opposition_prospection IS NULL))"; $sql .= " AND spe.datapolicy_send IS NULL"; - $sql .= " AND c.entity=".$conf->entity; + $sql .= " AND c.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -99,16 +100,16 @@ class DataPolicy */ public function getAllCompaniesNotInformed() { - global $langs, $conf, $db, $user; + global $langs, $conf, $db; $langs->load("companies"); $sql = "SELECT s.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields as se ON se.fk_object = s.rowid"; - $sql .= " WHERE s.statut=0 AND (se.datapolicy_consentement=0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement=0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection=0 OR se.datapolicy_opposition_prospection IS NULL)"; + $sql .= " WHERE s.statut = 0 AND (se.datapolicy_consentement = 0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement = 0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection = 0 OR se.datapolicy_opposition_prospection IS NULL)"; $sql .= " AND se.datapolicy_send IS NULL"; - $sql .= " AND s.entity=".$conf->entity; + $sql .= " AND s.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -136,16 +137,16 @@ class DataPolicy */ public function getAllAdherentsNotInformed() { - global $langs, $conf, $db, $user; + global $langs, $conf, $db; $langs->load("adherent"); $sql = "SELECT a.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent_extrafields as ae ON ae.fk_object = a.rowid"; - $sql .= " WHERE a.statut=0 AND (ae.datapolicy_consentement=0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)"; + $sql .= " WHERE a.statut = 0 AND (ae.datapolicy_consentement = 0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)"; $sql .= " AND ae.datapolicy_send IS NULL"; - $sql .= " AND a.entity=".$conf->entity; + $sql .= " AND a.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -174,7 +175,7 @@ class DataPolicy */ public static function sendMailDataPolicyContact($contact) { - global $langs, $conf, $db, $user; + global $langs, $db, $user; $error = 0; @@ -252,7 +253,7 @@ class DataPolicy */ public static function sendMailDataPolicyCompany($societe) { - global $langs, $conf, $db, $user; + global $langs, $db, $user; $error = 0; @@ -327,7 +328,7 @@ class DataPolicy */ public static function sendMailDataPolicyAdherent($adherent) { - global $langs, $conf, $db, $user; + global $langs, $db, $user; $error = 0; diff --git a/htdocs/datapolicy/class/datapolicycron.class.php b/htdocs/datapolicy/class/datapolicycron.class.php index d2b8d88a1fa..6b588eda92c 100644 --- a/htdocs/datapolicy/class/datapolicycron.class.php +++ b/htdocs/datapolicy/class/datapolicycron.class.php @@ -468,6 +468,7 @@ class DataPolicyCron $this->db->begin(); + // Loop on each type of data foreach ($arrayofparameters as $key => $params) { if (getDolGlobalInt($key) > 0) { // @phan-suppress-next-line PhanPluginPrintfVariableFormatString @@ -488,10 +489,12 @@ class DataPolicyCron $object->fetch($obj->rowid); $object->id = $obj->rowid; - $action = 'anonymize'; // TODO Offer also action "delete" in setup of module + $action = 'anonymize'; // TODO Offer also action "delete" in the setup of the module + // Manage action 'anonymize' if ($action == 'anonymize') { - if ($object->isObjectUsed($obj->rowid) == 0) { // If object to clean is used + if ($object->isObjectUsed($obj->rowid) == 0) { // If object to clean is not used + // Loop on each field to anonymize foreach ($params['fields_anonym'] as $field => $val) { if ($val == 'MAKEANONYMOUS') { $object->$field = $field.'-anonymous-'.$obj->rowid; // @phpstan-ignore-line @@ -499,7 +502,10 @@ class DataPolicyCron $object->$field = $val; } } + + // Update record $result = $object->update($obj->rowid, $user); + if ($result > 0) { $errormsg = $object->error; $error++; @@ -508,6 +514,7 @@ class DataPolicyCron } } + // Manage action 'deletion' if ($action == 'delete') { // If object to clean is not used $result = $object->delete($user); if ($result < 0) { diff --git a/htdocs/datapolicy/lib/datapolicy.lib.php b/htdocs/datapolicy/lib/datapolicy.lib.php index 5d24333e0e4..a11e4bcbfbc 100644 --- a/htdocs/datapolicy/lib/datapolicy.lib.php +++ b/htdocs/datapolicy/lib/datapolicy.lib.php @@ -38,7 +38,7 @@ function datapolicyAdminPrepareHead() $head = array(); $head[$h][0] = DOL_URL_ROOT."/datapolicy/admin/setup.php"; - $head[$h][1] = $langs->trans("Deletion"); + $head[$h][1] = $langs->trans("DataAnonymization"); $head[$h][2] = 'settings'; $h++; diff --git a/htdocs/document.php b/htdocs/document.php index 67141c2eece..067eac0d7bb 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -129,7 +129,7 @@ $original_file = GETPOST('file', 'alphanohtml'); $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'alpha'); $urlsource = GETPOST('urlsource', 'alpha'); -$entity = GETPOSTINT('entity', $conf->entity); +$entity = GETPOSTINT('entity'); // Security check if (empty($modulepart) && empty($hashp)) { diff --git a/htdocs/don/index.php b/htdocs/don/index.php index 6775c5263e1..2df4cdbdcfe 100644 --- a/htdocs/don/index.php +++ b/htdocs/don/index.php @@ -257,7 +257,7 @@ if ($resql) { print ''; // Date - print ''; + print ''; print ''; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 2fe1ac92ddd..56d300c9b8f 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1875,7 +1875,7 @@ if ($action == 'create') { print ''; } - if ($object->status == $object::STATUS_CLOSED) { + if ($object->status == ExpenseReport::STATUS_CLOSED) { /* TODO this fields are not yet filled print ''; print ''; @@ -2615,12 +2615,12 @@ if ($action == 'create') { // Unit price net print ''; // Unit price with tax print ''; // Quantity diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index f9757c4f779..b502bfe6ad7 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1943,7 +1943,7 @@ class ExpenseReport extends CommonObject dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG); - if ($this->status == self::STATUS_DRAFT) { + if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) { if (empty($qty)) { $qty = 0; } @@ -2037,7 +2037,7 @@ class ExpenseReport extends CommonObject } } else { dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR); - $this->error = 'ErrorExpenseNotDraft'; + $this->error = 'ErrorExpenseNotDraftAndNotRefused'; return -3; } } diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 61042abf3de..72d260e1525 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -474,7 +474,7 @@ if ($step == 1 || !$datatoexport) { // Affiche les modules d'exports print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table - print '
'.$langs->trans("Parameter").'
'.$langs->trans($title).'
'.dol_print_date($db->jdate($obj->datem), 'day').'jdate($obj->datem), 'day').'">'.dol_print_date($db->jdate($obj->datem), 'day').''.$donation_static->LibStatut($obj->fk_statut, 5).'
'.$langs->trans("AUTHORPAIEMENT").''; - print ''; + print ''; print ''; - print ''; + print ''; print '
'; + print '
'; print ''; print ''; print ''; @@ -486,16 +486,17 @@ if ($step == 1 || !$datatoexport) { //var_dump($objexport->array_export_code_for_sort); //$sortedarrayofmodules = dol_sort_array($objexport->array_export_module, 'module_position', 'asc', 0, 0, 1); foreach ($objexport->array_export_code_for_sort as $key => $value) { - print '
'.$langs->trans("Module").''.$langs->trans("ExportableDatas").'
'; - //print img_object($objexport->array_export_module[$key]->getName(),$export->array_export_module[$key]->picto).' '; - print $objexport->array_export_module[$key]->getName(); + $titleofmodule = $objexport->array_export_module[$key]->getName(); + print '
'; + print dolPrintHTML($titleofmodule); print ''; $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[$key]); $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); $label = $objexport->array_export_label[$key]; - //print $value.'-'.$icon.'-'.$label."
"; - print img_object($objexport->array_export_module[$key]->getName(), $entityicon).' '; - print $label; + print '
'; + print img_object($objexport->array_export_module[$key]->getName(), $entityicon, 'class="pictofixedwidth"'); + print dolPrintHTML($label); + print '
'; print '
'; if ($objexport->array_export_perms[$key]) { print ''.img_picto($langs->trans("NewExport"), 'next', 'class="fa-15"').''; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 5a259070df1..f76e2ce690f 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -1025,7 +1025,7 @@ class ProductFournisseur extends Product } } - if ($fourn_unitprice < $min || $min == -1) { + if ($fourn_unitprice_with_discount < $min || $min == -1) { $this->id = $prodid; $this->product_fourn_price_id = $record["product_fourn_price_id"]; $this->ref_supplier = $record["ref_fourn"]; @@ -1050,7 +1050,7 @@ class ProductFournisseur extends Product $this->fourn_multicurrency_id = $record["fk_multicurrency"]; $this->fourn_multicurrency_code = $record["multicurrency_code"]; - $min = $fourn_unitprice; + $min = $fourn_unitprice_with_discount; } } } @@ -1133,8 +1133,8 @@ class ProductFournisseur extends Product $out = ''; $langs->load("suppliers"); if (count($productFournList) > 0) { - $out .= ''; - $out .= ''; + $out .= '
'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').'
'; + $out .= ''; $out .= ''; $out .= ''; $out .= ''; @@ -1142,7 +1142,7 @@ class ProductFournisseur extends Product $out .= ''; $out .= ''; $out .= ''; - $out .= ''; + $out .= ''; } $out .= '
'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').''.($showunitprice ? $langs->trans("QtyMin") : '').''.$langs->trans("Supplier").''.$langs->trans("SupplierRef").'
'.($showunitprice ? price($productFourn->fourn_unitprice * (1 - $productFourn->fourn_remise_percent / 100) - $productFourn->fourn_remise) : '').''.($showunitprice ? $productFourn->fourn_qty : '').''.$productFourn->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).''.$productFourn->fourn_ref.'
'.dolPrintHTML($productFourn->fourn_ref).'
'; } else { diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 34349e99a91..873a4a7b9a2 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -844,7 +844,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); $object->transport_mode_id = GETPOSTINT('transport_mode_id'); // Proprietes particulieres a facture de replacement @@ -1591,12 +1591,26 @@ if (empty($reshook)) { $idprod = GETPOSTINT('idprod'); } + $price_ht = ''; + $price_ht_devise = ''; + $price_ttc = ''; + $price_ttc_devise = ''; + + if (GETPOST('price_ht') !== '') { + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ht') !== '') { + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + } + if (GETPOST('price_ttc') !== '') { + $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ttc') !== '') { + $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); + } + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)' - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); - $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); - $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS'); $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0); @@ -1623,6 +1637,24 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } + + if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && (($price_ht < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht == '') && (($price_ht_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht_devise == '') && $price_ttc === '' && $price_ttc_devise === '' && $object->type != FactureFournisseur::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' + if (($price_ht < 0 || $price_ttc < 0) && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) { + $langs->load("errors"); + if ($object->type == $object::TYPE_DEPOSIT) { + // Using negative lines on deposit lead to headach and blocking problems when you want to consume them. + setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors'); + } else { + setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors'); + } + $error++; + } else { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); + $error++; + } + } + + if ($prod_entry_mode == 'free' && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not '' setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors'); $error++; @@ -4034,7 +4066,9 @@ if ($action == 'create') { } // Validate - if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT) { + if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT && count($object->lines) > 0 + && ((($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_PROFORMA || $object->type == FactureFournisseur::TYPE_SITUATION) && (getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) + || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { if (count($object->lines)) { if ($usercanvalidate) { print 'type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) { + if ($object->status != FactureFournisseur::STATUS_DRAFT && ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD)) { // For credit note only if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->status == 1 && $object->paid == 0) { if ($resteapayer == 0) { diff --git a/htdocs/holiday/card_group.php b/htdocs/holiday/card_group.php index 10b0d02d497..34b5f24109e 100644 --- a/htdocs/holiday/card_group.php +++ b/htdocs/holiday/card_group.php @@ -521,7 +521,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { $sql = 'SELECT u.rowid, u.lastname, u.firstname, u.login, u.photo FROM '.MAIN_DB_PREFIX.'user as u'; $sql .= ' WHERE 1 = 1'; - $sql .= !empty($morefilter) ? $morefilter : ''; + $sql .= empty($morefilter) ? '' : $morefilter; $userlist = array(); $userstatic = new User($db); diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 1e9d77989f4..b66cfc1f399 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -351,7 +351,7 @@ if ($step == 1 || !$datatoimport) { // Affiche les modules d'imports print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table - print ''; + print '
'; print ''; print ''; print ''; @@ -362,18 +362,21 @@ if ($step == 1 || !$datatoimport) { $sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1); foreach ($sortedarrayofmodules as $key => $value) { //var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]); - print '
'.$langs->trans("Module").''.$langs->trans("ImportableDatas").'
'; $titleofmodule = $objimport->array_import_module[$key]['module']->getName(); + print '
'; // Special case for import common to module/services if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) { $titleofmodule = $langs->trans("ProductOrService"); } - print $titleofmodule; + print dolPrintHTML($titleofmodule); print ''; $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]); $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); - print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon).' '; - print $objimport->array_import_label[$key]; + $label = $objimport->array_import_label[$key]; + print '
'; + print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"'); + print dolPrintHTML($label); + print '
'; print '
'; if ($objimport->array_import_perms[$key]) { print ''.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').''; diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/LICENSE b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/LICENSE similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/LICENSE rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/LICENSE diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/README.md b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/README.md similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/README.md rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/README.md diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.dolibarr b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.dolibarr similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.dolibarr rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.dolibarr diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.htaccess b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.htaccess similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.htaccess rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.htaccess diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/htmlheader.html b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/htmlheader.html similarity index 99% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/htmlheader.html rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/htmlheader.html index 0de0b36283f..6511ce086fd 100644 --- a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/htmlheader.html +++ b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/htmlheader.html @@ -3,4 +3,3 @@ - diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/javascript.js.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/javascript.js.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/javascript.js.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/javascript.js.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/manifest.json.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/manifest.json.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/manifest.json.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/manifest.json.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/robots.txt b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/robots.txt similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/robots.txt rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/robots.txt diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/styles.css.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/styles.css.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/styles.css.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/styles.css.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/wrapper.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/wrapper.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/wrapper.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/wrapper.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/article.png b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/article.png similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/article.png rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/article.png diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/bg.png b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/bg.png similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/bg.png rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/bg.png diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/happy-man.png b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/happy-man.png similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/happy-man.png rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/happy-man.png diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/website_pages.sql b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/website_pages.sql similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/website_pages.sql rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/website_pages.sql diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/LICENSE b/htdocs/install/doctemplates/websites/website_template-noimg_dev/LICENSE similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/LICENSE rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/LICENSE diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/README.md b/htdocs/install/doctemplates/websites/website_template-noimg_dev/README.md similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/README.md rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/README.md diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/.dolibarr b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.dolibarr similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/.dolibarr rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.dolibarr diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/.htaccess b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.htaccess similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/.htaccess rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.htaccess diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/htmlheader.html b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/htmlheader.html similarity index 99% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/htmlheader.html rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/htmlheader.html index a58ea695524..719eb1ebc61 100644 --- a/htdocs/install/doctemplates/websites/website_template-noimg/containers/htmlheader.html +++ b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/htmlheader.html @@ -3,4 +3,3 @@ --> - diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/javascript.js.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/javascript.js.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/javascript.js.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/javascript.js.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/manifest.json.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/manifest.json.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/manifest.json.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/manifest.json.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/robots.txt b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/robots.txt similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/robots.txt rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/robots.txt diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/styles.css.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/styles.css.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/styles.css.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/styles.css.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/wrapper.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/wrapper.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/wrapper.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/wrapper.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/website_pages.sql b/htdocs/install/doctemplates/websites/website_template-noimg_dev/website_pages.sql similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/website_pages.sql rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/website_pages.sql diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/LICENSE b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/LICENSE similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/LICENSE rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/LICENSE diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/README.md b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/README.md similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/README.md rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/README.md diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/.dolibarr b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.dolibarr similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/.dolibarr rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.dolibarr diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/.htaccess b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.htaccess similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/.htaccess rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.htaccess diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/htmlheader.html b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/htmlheader.html similarity index 99% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/htmlheader.html rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/htmlheader.html index 41e782b5934..94c8271c490 100644 --- a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/htmlheader.html +++ b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/htmlheader.html @@ -3,4 +3,3 @@ - diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/javascript.js.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/javascript.js.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/javascript.js.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/javascript.js.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/manifest.json.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/manifest.json.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/manifest.json.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/manifest.json.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/robots.txt b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/robots.txt similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/robots.txt rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/robots.txt diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/styles.css.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/styles.css.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/styles.css.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/styles.css.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/wrapper.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/wrapper.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/wrapper.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/wrapper.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/website_pages.sql b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/website_pages.sql similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/website_pages.sql rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/website_pages.sql diff --git a/htdocs/install/mysql/data/llx_c_type_contact.sql b/htdocs/install/mysql/data/llx_c_type_contact.sql index 50a952bbea1..39813dfb70f 100644 --- a/htdocs/install/mysql/data/llx_c_type_contact.sql +++ b/htdocs/install/mysql/data/llx_c_type_contact.sql @@ -125,4 +125,4 @@ insert into llx_c_type_contact (element, source, code, libelle, active ) values insert into llx_c_type_contact (element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'RESPONSIBLE', 'Booth responsible', 1); -- Thirdparty -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('societe', 'internal', 'SALESREPTHIRD', 'Sales Representative', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('societe', 'external', 'SALESREPTHIRD', 'Sales Representative', 1); diff --git a/htdocs/install/pgsql/functions/functions-bom.sql b/htdocs/install/pgsql/functions/functions-bom.sql new file mode 100644 index 00000000000..e31c64e170e --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-bom.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2024 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-mo.sql b/htdocs/install/pgsql/functions/functions-mo.sql new file mode 100644 index 00000000000..37b92ae5269 --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-mo.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2024 Laurent Destailleur +-- +-- 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 . +-- +-- ============================================================================ + + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions.sql b/htdocs/install/pgsql/functions/functions.sql index 1d3587c8e7c..5260a44a8c3 100644 --- a/htdocs/install/pgsql/functions/functions.sql +++ b/htdocs/install/pgsql/functions/functions.sql @@ -75,10 +75,6 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank_account FOR EAC CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank_account_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_blockedlog FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_blockedlog_authority FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bordereau_cheque FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_boxes_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_c_email_templates FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -127,10 +123,6 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinterdet_extrafi CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_delivery FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_localtax FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_menu FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index ad0813153e1..4bb38cda648 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -33,8 +33,8 @@ CountryIsInEEC=Country is inside the European Economic Community PriceFormatInCurrentLanguage=Price display format in the current language and currency ThirdPartyName=Third-party name ThirdPartyEmail=Third-party email -ThirdParty=Third-party -ThirdParties=Third-parties +ThirdParty=Third party +ThirdParties=Third parties ThirdPartyProspects=Prospects ThirdPartyProspectsStats=Prospects ThirdPartyCustomers=Customers @@ -383,8 +383,8 @@ ExportCardToFormat=Export card to format ContactNotLinkedToCompany=Contact not linked to any third party DolibarrLogin=Dolibarr login NoDolibarrAccess=No Dolibarr access -ExportDataset_company_1=Third-parties (companies/foundations/physical people) and their properties -ExportDataset_company_2=Contacts and their properties +ExportDataset_company_1=Third-parties (organizations/natural persons) and attributes +ExportDataset_company_2=Third-parties additional contacts/addresses and attributes ExportDataset_company_3=Third-parties payment modes (bank accounts) ImportDataset_company_1=Third-parties and their properties ImportDataset_company_2=Third-parties additional contacts/addresses and attributes diff --git a/htdocs/langs/en_US/datapolicy.lang b/htdocs/langs/en_US/datapolicy.lang index 7cbc85b7475..38a4f48f39f 100644 --- a/htdocs/langs/en_US/datapolicy.lang +++ b/htdocs/langs/en_US/datapolicy.lang @@ -17,8 +17,9 @@ Module4100Name = Data Privacy Policy Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR) # Administration page datapolicySetup = Module Data Privacy Policy Setup -Deletion = Deletion of data -datapolicySetupPage = Depending on the laws of your countries (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
The deletion will be done automatically after a certain duration without events (the duration which you will have indicated below). +DataDeletion=Deletion of data +DataAnonymization=Anonymization of data +datapolicySetupPage = Depending on the laws of your countries (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
This module will make an anonymization automatically after a certain duration without events (the duration which you will have indicated below) and if the object has no existing business object children. NB_MONTHS = %s months ONE_YEAR = 1 year NB_YEARS = %s years @@ -33,12 +34,14 @@ DATAPOLICY_CONTACT_PROSPECT_CLIENT = Prospect/Customer DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer DATAPOLICY_CONTACT_FOURNISSEUR = Supplier DATAPOLICY_ADHERENT = Member -DATAPOLICY_Tooltip_SETUP=Define the delay with no interaction after which you want the record to be automatically purged. +DATAPOLICY_Tooltip_SETUP=The anonymization is done by the scheduled job "%s" ran by the module "%s", so this module must be enabled and working correctly. SendAgreementText = You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button. SendAgreement = Send emails AllAgreementSend = All emails have been sent TXTLINKDATAPOLICYACCEPT = Text for the link "agreement" TXTLINKDATAPOLICYREFUSE = Text for the link "disagreement" +DelayForAnonymization=Delay for anonymization +DelayForDeletion=Delay for deletion # Extrafields DATAPOLICY_BLOCKCHECKBOX = GDPR : Processing of personal data DATAPOLICY_consentement = Consent obtained for the processing of personal data diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index 4ea49a160fa..9fd4ad9ce0e 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -125,6 +125,7 @@ Language_uk_UA=Ukrainian Language_ur_PK=Urdu Language_uz_UZ=Uzbek Language_vi_VN=Vietnamese +Language_wo_SN=Wolof Language_zh_CN=Chinese Language_zh_TW=Chinese (Taiwan) Language_zh_HK=Chinese (Hong Kong) diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 16db52a9770..73e7e6fd306 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -798,7 +798,7 @@ Notes=Notes AddNewLine=Add new line AddFile=Add file FreeZone=Free-text product -FreeLineOfType=Free-text item, type: +FreeLineOfType=Free-text item, type CloneMainAttributes=Clone object with its main attributes ReGeneratePDF=Re-generate PDF PDFMerge=PDF Merge @@ -1155,6 +1155,7 @@ ContactDefault_project_task=Task ContactDefault_propal=Proposal ContactDefault_supplier_proposal=Supplier Proposal ContactDefault_ticket=Ticket +ContactDefault_societe=Third party ContactAddedAutomatically=Contact added from third-party contact roles More=More ShowDetails=Show details diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 2d8d05e9761..ededc52cbfc 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -209,6 +209,7 @@ unitL=Liter unitT=ton unitKG=kg unitG=Gram +unitGAL=gallon unitMG=mg unitLB=pound unitOZ=ounce diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang index 202c88c7d18..2987021be4e 100644 --- a/htdocs/langs/en_US/salaries.lang +++ b/htdocs/langs/en_US/salaries.lang @@ -29,7 +29,6 @@ FillFieldFirst=Fill employee field first UpdateAmountWithLastSalary=Set amount of last salary MakeTransferRequest=Make transfer request VirementOrder=Credit transfer request -BankTransferAmount=Amount of credit transfer WithdrawalReceipt=Credit transfer order OrderWaiting=Pending order FillEndOfMonth=Fill with end of month diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index fc793f5cf2a..629d5a114cf 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -88,7 +88,7 @@ WebsiteAccount=Website account WebsiteAccounts=Website accounts AddWebsiteAccount=Create web site account BackToListForThirdParty=Back to list for the third parties -DisableSiteFirst=Disable website first +DisableSiteFirst=Put website offline first MyContainerTitle=My web site title AnotherContainer=This is how to include content of another page/container (you may have an error here if you enable dynamic code because the embedded subcontainer may not exists) SorryWebsiteIsCurrentlyOffLine=Sorry, this website is currently off line. Please comme back later... diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 53cdffdb145..d6e652922d9 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -12,7 +12,7 @@ * Copyright (C) 2014-2015 Marcos García * Copyright (C) 2015 Raphaël Doursenaud * Copyright (C) 2020 Demarest Maxime - * Copyright (C) 2020 Charlene Benke + * Copyright (C) 2020-2024 Charlene Benke * Copyright (C) 2021-2024 Frédéric France * Copyright (C) 2021 Alexandre Spangaro * Copyright (C) 2023 Joachim Küter @@ -854,7 +854,7 @@ if (!defined('NOLOGIN')) { $captcha = getDolGlobalString('MAIN_SECURITY_ENABLECAPTCHA_HANDLER', 'standard'); // List of directories where we can find captcha handlers - $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); + $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), isset($conf->modules_parts['captcha']) && is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); $fullpathclassfile = ''; foreach ($dirModCaptcha as $dir) { $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2); diff --git a/htdocs/margin/agentMargins.php b/htdocs/margin/agentMargins.php index a31ac92d1ed..95c4ba1ad06 100644 --- a/htdocs/margin/agentMargins.php +++ b/htdocs/margin/agentMargins.php @@ -259,7 +259,7 @@ if ($result) { $i = 0; print '
'; - print ''."\n"; + print '
'."\n"; print ''; if ($agentid > 0) { diff --git a/htdocs/margin/checkMargins.php b/htdocs/margin/checkMargins.php index d497b845c3d..8f71eb09bb9 100644 --- a/htdocs/margin/checkMargins.php +++ b/htdocs/margin/checkMargins.php @@ -279,29 +279,42 @@ if ($result) { $selectedfields = ''; print '
'; - print '
'."\n"; + print '
'."\n"; print ''; + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } print ''; print ''; print ''; print ''; print ''; print ''; - print ''; + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } print "\n"; print ''; + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); + } print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("UnitPriceHT", $_SERVER["PHP_SELF"], "d.subprice", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre($labelcostprice, $_SERVER["PHP_SELF"], "d.buy_price_ht", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("AmountTTC", $_SERVER["PHP_SELF"], "d.total_ht", "", $param, '', $sortfield, $sortorder, 'right '); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); + } print "\n"; $i = 0; @@ -309,6 +322,11 @@ if ($result) { $objp = $db->fetch_object($result); print ''; + + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } + print ''; - print ''; + + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } print "\n"; $i++; } + if ($num == 0) { + print ''; + } + print "
'; $result_inner = $invoicestatic->fetch($objp->invoiceid); if ($result_inner < 0) { @@ -349,13 +367,22 @@ if ($result) { print ''; print ''.price($objp->total_ht).''; print '
'; + print ''.$langs->trans("NoRecordFound").''; + print '
"; print "
"; diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index e9b3c3b2cf8..1ec4b367601 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -329,7 +329,7 @@ if ($result) { $i = 0; print '
'; - print ''."\n"; + print '
'."\n"; print ''; if (!empty($client)) { diff --git a/htdocs/margin/productMargins.php b/htdocs/margin/productMargins.php index 9dd60cfa769..dac098bf848 100644 --- a/htdocs/margin/productMargins.php +++ b/htdocs/margin/productMargins.php @@ -126,7 +126,7 @@ print '
'; // Product print ''; print ''; // Categories @@ -279,7 +279,7 @@ if ($result) { $i = 0; print '
'; - print '
'.$langs->trans('ProductOrService').''; -print img_picto('', 'product').$form->select_produits(($id > 0 ? $id : ''), 'id', '', 20, 0, 1, 2, '', 1, array(), 0, 'All', 0, '', 0, '', null, 1); +print img_picto('', 'product', 'class="pictofixedwidth"').$form->select_produits(($id > 0 ? $id : ''), 'id', '', 20, 0, 1, 2, '', 1, array(), 0, '', 0, '', 0, '', null, 1); print '
'."\n"; + print '
'."\n"; print ''; if ($id > 0) { diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index cd06cb211ef..ac31dc344dd 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -284,7 +284,9 @@ class MyObject extends CommonObject { $resultcreate = $this->createCommon($user, $notrigger); - //$resultvalidate = $this->validate($user, $notrigger); + // uncomment lines below if you want to validate object after creation + // $this->fetch($this->id); // needed to retrieve some fields (ie date_creation for masked ref) + // $resultcreate = $this->validate($user, $notrigger); return $resultcreate; } diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index 89e4ed53480..b9391aa6afa 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -143,7 +143,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'ORDER_CLASSIFY_UNBILLED': // TODO Replace it with ORDER_UNBILLED //case 'ORDER_SETDRAFT': //case 'LINEORDER_INSERT': - //case 'LINEORDER_UPDATE': + //case 'LINEORDER_MODIFY': //case 'LINEORDER_DELETE': // Supplier orders @@ -160,7 +160,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'ORDER_SUPPLIER_RECEIVE': //case 'LINEORDER_SUPPLIER_DISPATCH': //case 'LINEORDER_SUPPLIER_CREATE': - //case 'LINEORDER_SUPPLIER_UPDATE': + //case 'LINEORDER_SUPPLIER_MODIFY': //case 'LINEORDER_SUPPLIER_DELETE': // Proposals @@ -174,7 +174,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'PROPAL_CLOSE_REFUSED': //case 'PROPAL_DELETE': //case 'LINEPROPAL_INSERT': - //case 'LINEPROPAL_UPDATE': + //case 'LINEPROPAL_MODIFY': //case 'LINEPROPAL_DELETE': // SupplierProposal @@ -186,7 +186,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED': //case 'SUPPLIER_PROPOSAL_DELETE': //case 'LINESUPPLIER_PROPOSAL_INSERT': - //case 'LINESUPPLIER_PROPOSAL_UPDATE': + //case 'LINESUPPLIER_PROPOSAL_MODIFY': //case 'LINESUPPLIER_PROPOSAL_DELETE': // Contracts @@ -197,7 +197,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'CONTRACT_CLOSE': //case 'CONTRACT_DELETE': //case 'LINECONTRACT_INSERT': - //case 'LINECONTRACT_UPDATE': + //case 'LINECONTRACT_MODIFY': //case 'LINECONTRACT_DELETE': // Bills @@ -210,7 +210,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'BILL_DELETE': //case 'BILL_PAYED': //case 'LINEBILL_INSERT': - //case 'LINEBILL_UPDATE': + //case 'LINEBILL_MODIFY': //case 'LINEBILL_DELETE': // Recurring Bills @@ -222,14 +222,14 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //Supplier Bill //case 'BILL_SUPPLIER_CREATE': - //case 'BILL_SUPPLIER_UPDATE': + //case 'BILL_SUPPLIER_MODIFY': //case 'BILL_SUPPLIER_DELETE': //case 'BILL_SUPPLIER_PAYED': //case 'BILL_SUPPLIER_UNPAYED': //case 'BILL_SUPPLIER_VALIDATE': //case 'BILL_SUPPLIER_UNVALIDATE': //case 'LINEBILL_SUPPLIER_CREATE': - //case 'LINEBILL_SUPPLIER_UPDATE': + //case 'LINEBILL_SUPPLIER_MODIFY': //case 'LINEBILL_SUPPLIER_DELETE': // Payments @@ -245,7 +245,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers // Donation //case 'DON_CREATE': - //case 'DON_UPDATE': + //case 'DON_MODIFY': //case 'DON_DELETE': // Interventions @@ -256,7 +256,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'FICHINTER_CLASSIFY_UNBILLED': // TODO Replace it with FICHINTER_UNBILLED //case 'FICHINTER_DELETE': //case 'LINEFICHINTER_CREATE': - //case 'LINEFICHINTER_UPDATE': + //case 'LINEFICHINTER_MODIFY': //case 'LINEFICHINTER_DELETE': // Members diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index bd701a4cf99..13f5aca1700 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -1745,6 +1745,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $href = $_SERVER["PHP_SELF"]; $href .= '?id='.$object->id; $href .= '&action=deleteline'; + $href .= '&token='.newToken(); $href .= '&lineid='.$line->id; print ''; } print ''; @@ -708,7 +708,7 @@ print $form->selectarray( 0, 0, '', - 'minwidth100imp maxwidth400', + 'minwidth125imp maxwidth400', 1 ); print ''; diff --git a/htdocs/product/canvas/product/tpl/card_create.tpl.php b/htdocs/product/canvas/product/tpl/card_create.tpl.php index 5e4621b24c1..1f750f1108a 100644 --- a/htdocs/product/canvas/product/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_create.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2010-2018 Regis Houssin + * Copyright (C) 2024 Frédéric 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 @@ -16,10 +16,14 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var Form $form * @var Translate $langs * @var User $user + * + * @var string $canvas + * @var int $refalreadyexists */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/product/canvas/product/tpl/card_edit.tpl.php b/htdocs/product/canvas/product/tpl/card_edit.tpl.php index b6a95262e0d..12482210934 100644 --- a/htdocs/product/canvas/product/tpl/card_edit.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_edit.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/canvas/product/tpl/card_view.tpl.php b/htdocs/product/canvas/product/tpl/card_view.tpl.php index 3cf61f55d2f..e7b26f58762 100644 --- a/htdocs/product/canvas/product/tpl/card_view.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_view.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/canvas/service/tpl/card_create.tpl.php b/htdocs/product/canvas/service/tpl/card_create.tpl.php index 875b790e688..6266cdbda47 100644 --- a/htdocs/product/canvas/service/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_create.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -16,10 +16,14 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var Form $form * @var Translate $langs * @var User $user + * + * @var string $canvas + * @var int $refalreadyexists */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/product/canvas/service/tpl/card_edit.tpl.php b/htdocs/product/canvas/service/tpl/card_edit.tpl.php index eb40955a200..a95415aac72 100644 --- a/htdocs/product/canvas/service/tpl/card_edit.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_edit.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/canvas/service/tpl/card_view.tpl.php b/htdocs/product/canvas/service/tpl/card_view.tpl.php index 2b48f913b0e..b5fd7372b39 100644 --- a/htdocs/product/canvas/service/tpl/card_view.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_view.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index a94aa6d490a..e6618eff49f 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -82,9 +82,9 @@ class Product extends CommonObject 'contratdet' => array('name' => 'Contract', 'parent' => 'contrat', 'parentkey' => 'fk_contrat'), 'facture_fourn_det' => array('name' => 'SupplierInvoice', 'parent' => 'facture_fourn', 'parentkey' => 'fk_facture_fourn'), 'commande_fournisseurdet' => array('name' => 'SupplierOrder', 'parent' => 'commande_fournisseur', 'parentkey' => 'fk_commande'), - 'mrp_production' => array('name' => 'Mo', 'parent' => 'mrp_mo', 'parentkey' => 'fk_mo' ), - 'bom_bom' => array('name' => 'BOM'), - 'bom_bomline' => array('name' => 'BOMLine', 'parent' => 'bom_bom', 'parentkey' => 'fk_bom'), + 'mrp_production' => array('name' => 'Mo', 'parent' => 'mrp_mo', 'parentkey' => 'fk_mo', 'enabled' => 'isModEnabled("mrp")'), + 'bom_bom' => array('name' => 'BOM', 'enabled' => 'isModEnabled("bom")'), + 'bom_bomline' => array('name' => 'BOMLine', 'parent' => 'bom_bom', 'parentkey' => 'fk_bom', 'enabled' => 'isModEnabled("bom")'), ); /** @@ -1544,7 +1544,7 @@ class Product extends CommonObject $sql .= ", sell_or_eat_by_mandatory = ".((empty($this->sell_or_eat_by_mandatory) || $this->sell_or_eat_by_mandatory < 0) ? 0 : (int) $this->sell_or_eat_by_mandatory); $sql .= ", batch_mask = '".$this->db->escape($this->batch_mask)."'"; - $sql .= ", finished = ".((!isset($this->finished) || $this->finished < 0 || $this->finished == '') ? "null" : (int) $this->finished); + $sql .= ", finished = ".((!isset($this->finished) || $this->finished < 0 || $this->finished === '') ? "null" : (int) $this->finished); $sql .= ", fk_default_bom = ".((!isset($this->fk_default_bom) || $this->fk_default_bom < 0 || $this->fk_default_bom == '') ? "null" : (int) $this->fk_default_bom); $sql .= ", net_measure = ".($this->net_measure != '' ? "'".$this->db->escape($this->net_measure)."'" : 'null'); $sql .= ", net_measure_units = ".($this->net_measure_units != '' ? "'".$this->db->escape($this->net_measure_units)."'" : 'null'); @@ -3078,7 +3078,7 @@ class Product extends CommonObject // Load multiprices array if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_AND_MULTIPRICES')) && empty($ignore_price_load)) { // prices per segment - $produit_multiprices_limit = getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'); + $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); for ($i = 1; $i <= $produit_multiprices_limit; $i++) { $sql = "SELECT price, price_ttc, price_min, price_min_ttc,"; $sql .= " price_base_type, tva_tx, default_vat_code, tosell, price_by_qty, rowid, recuperableonly"; @@ -3195,7 +3195,7 @@ class Product extends CommonObject return -1; } } elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') && empty($ignore_price_load)) { // prices per customer and quantity - $produit_multiprices_limit = getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'); + $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); for ($i = 1; $i <= $produit_multiprices_limit; $i++) { $sql = "SELECT price, price_ttc, price_min, price_min_ttc,"; $sql .= " price_base_type, tva_tx, default_vat_code, tosell, price_by_qty, rowid, recuperableonly"; diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 0f7d57db40c..895e804968e 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -119,7 +119,7 @@ $search_accountancy_code_buy_intra = GETPOST("search_accountancy_code_buy_intra" $search_accountancy_code_buy_export = GETPOST("search_accountancy_code_buy_export", 'alpha'); $search_import_key = GETPOST("search_import_key", 'alpha'); $search_finished = GETPOST("search_finished"); -$search_units = GETPOST('search_units', 'alpha'); +$search_units = GETPOST('search_units', 'int'); $type = GETPOST("type", 'alpha'); // Show/hide child product variants @@ -583,6 +583,7 @@ if ($search_vatrate) { if (dol_strlen($canvas) > 0) { $sql .= " AND p.canvas = '".$db->escape($canvas)."'"; } + // Search for tag/category ($searchCategoryProductList is an array of ID) if (!empty($searchCategoryProductList)) { $searchCategoryProductSqlList = array(); @@ -641,9 +642,10 @@ if ($search_accountancy_code_buy_intra) { if ($search_accountancy_code_buy_export) { $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_export', clean_account($search_accountancy_code_buy_export)); } -if (getDolGlobalString('PRODUCT_USE_UNITS') && $search_units) { +if (getDolGlobalString('PRODUCT_USE_UNITS') && $search_units && $search_units != '-1') { $sql .= natural_search('cu.rowid', $search_units); } + // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks @@ -2031,7 +2033,7 @@ while ($i < $imaxinloop) { } } - // Number of buy prices + // Number of buy prices - Vendor prices if (!empty($arrayfields['p.numbuyprice']['checked'])) { print '\n"; // Ref - print '\n"; // Product and qty on stock movement diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 9170ba31ed3..77eda021f11 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -256,12 +256,12 @@ foreach ($object->fields as $key => $val) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; // Add non object fields to fields for list -$arrayfields['s.nom'] = array('label' => $langs->trans("ThirdParty"), 'checked' => 1, 'position' => 21, 'enabled' => (!isModEnabled('societe') ? 0 : 1)); +$arrayfields['s.nom'] = array('label' => "ThirdParty", 'checked' => 1, 'position' => 21, 'enabled' => (!isModEnabled('societe') ? 0 : 1)); $arrayfields['s.name_alias'] = array('label' => "AliasNameShort", 'checked' => 0, 'position' => 22); $arrayfields['co.country_code'] = array('label' => "Country", 'checked' => -1, 'position' => 23); -$arrayfields['commercial'] = array('label' => $langs->trans("SaleRepresentativesOfThirdParty"), 'checked' => 0, 'position' => 25); -$arrayfields['c.assigned'] = array('label' => $langs->trans("AssignedTo"), 'checked' => 1, 'position' => 120); -$arrayfields['opp_weighted_amount'] = array('label' => $langs->trans('OpportunityWeightedAmountShort'), 'checked' => 0, 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? 0 : 1), 'position' => 106); +$arrayfields['commercial'] = array('label' => "SaleRepresentativesOfThirdParty", 'checked' => 0, 'position' => 25); +$arrayfields['c.assigned'] = array('label' => "AssignedTo", 'checked' => 1, 'position' => 120); +$arrayfields['opp_weighted_amount'] = array('label' => 'OpportunityWeightedAmountShort', 'checked' => 0, 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? 0 : 1), 'position' => 106); $arrayfields['u.login'] = array('label' => "Author", 'checked' => -1, 'position' => 165); // Force some fields according to search_usage filter... if (GETPOST('search_usage_opportunity')) { diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 3ad6cbb59fa..94c1ae17167 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -1561,9 +1561,8 @@ if ($source == 'member' || $source == 'membersubscription') { $member = new Adherent($db); $adht = new AdherentType($db); - $subscription = new Subscription($db); - $result = $member->fetch(0, $ref); + $result = $member->fetch(0, $ref, 0, '', true, true); // This fetch also ->last_subscription_amount if ($result <= 0) { $mesg = $member->error; $error++; @@ -1575,7 +1574,7 @@ if ($source == 'member' || $source == 'membersubscription') { $object = $member; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment - $amount = $subscription->total_ttc; + $amount = $member->last_subscription_amount; if (GETPOST("amount", 'alpha')) { $amount = price2num(GETPOST("amount", 'alpha'), 'MT', 2); } @@ -1712,6 +1711,10 @@ if ($source == 'member' || $source == 'membersubscription') { if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) { $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT'); } + // - If an amount was posted from the form (for example from page with types of membership) + if ($caneditamount && GETPOSTISSET('amount') && GETPOSTFLOAT('amount', 'MT') > 0) { + $amount = GETPOSTFLOAT('amount', 'MT'); + } // - If a new amount was posted from the form if ($caneditamount && GETPOSTISSET('newamount') && GETPOSTFLOAT('newamount', 'MT') > 0) { $amount = GETPOSTFLOAT('newamount', 'MT'); diff --git a/htdocs/public/payment/paymentko.php b/htdocs/public/payment/paymentko.php index a8ae18fb64d..3f6f7c8a7c9 100644 --- a/htdocs/public/payment/paymentko.php +++ b/htdocs/public/payment/paymentko.php @@ -110,6 +110,7 @@ if (empty($paymentmethod)) { } // Detect $ws +$reg_ws = array(); $ws = preg_match('/WS=([^\.]+)/', $FULLTAG, $reg_ws) ? $reg_ws[1] : 0; if ($ws) { dol_syslog("Paymentko.php page is invoked from a website with ref ".$ws.". It performs actions and then redirects back to this website. A page with ref paymentko must be created for this website.", LOG_DEBUG, 0, '_payment'); diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 972c78675ba..eb08a8a8279 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -133,6 +133,7 @@ if (empty($paymentmethod)) { dol_syslog("***** paymentok.php is called paymentmethod=".$paymentmethod." FULLTAG=".$FULLTAG." REQUEST_URI=".$_SERVER["REQUEST_URI"], LOG_DEBUG, 0, '_payment'); // Detect $ws +$reg_ws = array(); $ws = preg_match('/WS=([^\.]+)/', $FULLTAG, $reg_ws) ? $reg_ws[1] : 0; if ($ws) { dol_syslog("Paymentok.php page is invoked from a website with ref ".$ws.". It performs actions and then redirects back to this website. A page with ref paymentok must be created for this website.", LOG_DEBUG, 0, '_payment'); diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 03dba86959a..c835bdd1cf2 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -98,7 +98,6 @@ if (!isModEnabled('ticket')) { } - /* * Actions */ diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 86e8d046ff9..9cc8d48b56b 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -647,8 +647,7 @@ class Reception extends CommonObject if (intval($result) < 0) { $error++; - $this->errors[] = $mouvS->error; - $this->errors = array_merge($this->errors, $mouvS->errors); + $this->setErrorsFromObject($mouvS); break; } } else { @@ -661,8 +660,7 @@ class Reception extends CommonObject if (intval($result) < 0) { $error++; - $this->errors[] = $mouvS->error; - $this->errors = array_merge($this->errors, $mouvS->errors); + $this->setErrorsFromObject($mouvS); break; } } @@ -809,8 +807,7 @@ class Reception extends CommonObject $ret = $supplierorderdispatch->fetchAll('', '', 0, 0, $filter); if ($ret < 0) { - $this->error = $supplierorderdispatch->error; - $this->errors = $supplierorderdispatch->errors; + $this->setErrorsFromObject($supplierorderdispatch); return $ret; } else { // build array with quantity received by product in all supplier orders (origin) @@ -895,8 +892,7 @@ class Reception extends CommonObject $supplierorderline = new CommandeFournisseurLigne($this->db); $result = $supplierorderline->fetch($id); if ($result <= 0) { - $this->error = $supplierorderline->error; - $this->errors = $supplierorderline->errors; + $this->setErrorsFromObject($supplierorderline); return -1; } @@ -1116,7 +1112,9 @@ class Reception extends CommonObject $this->db->begin(); // Stock control - if (isModEnabled('stock') && !getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->statut > 0) { + if (isModEnabled('stock') && ((getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->status > Reception::STATUS_DRAFT) + || (getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION_CLOSE') && $this->status == Reception::STATUS_CLOSED)) + ) { require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"; $langs->load("agenda"); @@ -1140,7 +1138,7 @@ class Reception extends CommonObject // we do not log origin because it will be deleted $mouvS->origin = null; - $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), '', $obj->eatby, $obj->sellby, $obj->batch); // Price is set to 0, because we don't want to see WAP changed + $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), '', $obj->eatby ? $this->db->jdate($obj->eatby) : null, $obj->sellby ? $this->db->jdate($obj->sellby) : null, $obj->batch); // Price is set to 0, because we don't want to see WAP changed if ($result < 0) { $error++; $this->error = $mouvS->error; diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 0e5a14e12ea..bb64a3ccb34 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -552,20 +552,12 @@ class RecruitmentJobPosition extends CommonObject return 0; } - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->create)) - || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->recruitmentjobposition_advance->validate)))) - { - $this->error='NotEnoughPermissions'; - dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); - return -1; - }*/ - $now = dol_now(); $this->db->begin(); // Define new ref - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + if (/* !$error && */ (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life $num = $this->getNextNumRef(); } else { $num = $this->ref; @@ -765,14 +757,12 @@ class RecruitmentJobPosition extends CommonObject $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - if (!$error) { - $this->oldcopy = clone $this; - $this->status = $status; - $this->date_cloture = $now; - $this->note_private = $newprivatenote; - } + $this->oldcopy = clone $this; + $this->status = $status; + $this->date_cloture = $now; + $this->note_private = $newprivatenote; - if (!$notrigger && empty($error)) { + if (!$notrigger /* && empty($error) */) { // Call trigger $result = $this->call_trigger($triggerName, $user); if ($result < 0) { diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 475cb21f216..7402190de2b 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -210,8 +210,9 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio // Load translation files required by the page $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + global $outputlangsbis; + $outputlangsbis = null; if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) { - global $outputlangsbis; $outputlangsbis = new Translate('', $conf); $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')); $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); diff --git a/htdocs/salaries/card.php b/htdocs/salaries/card.php index f395d0011d6..9bbf3f4b97c 100644 --- a/htdocs/salaries/card.php +++ b/htdocs/salaries/card.php @@ -467,6 +467,8 @@ if ($action == "update_extras" && $permissiontoadd) { $object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, 'alpha'); } + $triggermodname = 'SALARY_MODIFY'; + $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); @@ -477,6 +479,7 @@ if ($action == "update_extras" && $permissiontoadd) { } } + /* * View */ @@ -577,7 +580,7 @@ if ($action == 'create' && $permissiontoadd) { print ''; // Label @@ -909,12 +912,12 @@ if ($id > 0) { print '
'; print ''; diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 3d7e56c8de8..aecd2477b21 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -675,11 +675,11 @@ if (empty($conf->use_javascript_ajax)) { print ''; $arrval = array( '0' => $langs->trans("No"), - '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', - '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', - '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', + '1' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 1).'', + '2' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 2).'', + '3' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 3).'', ); - print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); + print $form->selectarray("activate_usesearchtoselectproduct", $arrval, getDolGlobalInt('PRODUIT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth125imp maxwidth400'); print '
'; if ($product_static->status_buy && $usercancreadprice) { diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 6f3e138c587..f4ffea34d18 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1324,10 +1324,11 @@ foreach ($listofreferent as $key => $value) { print "'; + print ''; if ($tablename == 'expensereport_det') { print $expensereport->getNomUrl(1); } else { + print ''; + + print '
'; // Show ref with link if ($element instanceof Task) { print $element->getNomUrl(1, 'withproject', 'time'); @@ -1363,6 +1364,10 @@ foreach ($listofreferent as $key => $value) { } print ''; + print ''; + // Show supplier ref if (!empty($element->ref_supplier)) { print ' - '.$element->ref_supplier; @@ -1375,6 +1380,8 @@ foreach ($listofreferent as $key => $value) { if (empty($element->ref_customer) && !empty($element->ref_client)) { print ' - '.$element->ref_client; } + + print '
'; } print "
'; print $form->editfieldkey('Employee', 'fk_user', '', $object, 0, 'string', '', 1).''; $noactive = 0; // We keep active and unactive users - print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(GETPOSTINT('fk_user'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'AND employee=1', 0, '', 'maxwidth300', $noactive); + print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(GETPOSTINT('fk_user'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'employee:=:1', 0, '', 'maxwidth300', $noactive); print '
'; if ($action == 'edit') { - print '"; } else { print ""; - print ''; } diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index a70fce80e07..e0d3abf655c 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -120,6 +120,7 @@ class Salary extends CommonObject /** * @var int + * @deprecated see $accountid * @see $accountid */ public $fk_account; @@ -154,7 +155,7 @@ class Salary extends CommonObject const STATUS_PAID = 1; /** - * @var string + * @var float amount remain to pay */ public $resteapayer; diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index c26a609536b..f72c3a4512f 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -193,8 +193,8 @@ if ($massaction == 'withdrawrequest') { $objecttmp = new Salary($db); $result = $objecttmp->fetch($toselectid); if ($result > 0) { - $totalpaid = $objecttmp->getSommePaiement(); - $objecttmp->resteapayer = price2num((float) $objecttmp->amount - $totalpaid, 'MT'); + $totalpaid = (float) $objecttmp->getSommePaiement(); + $objecttmp->resteapayer = (float) price2num((float) $objecttmp->amount - $totalpaid, 'MT'); // hook to finalize the remaining amount, considering e.g. cash discount agreements $parameters = array('remaintopay' => $objecttmp->resteapayer); @@ -211,7 +211,7 @@ if ($massaction == 'withdrawrequest') { if ($objecttmp->status == Salary::STATUS_PAID || $objecttmp->resteapayer == 0) { $error++; setEventMessages($langs->trans("Salary").' '.$objecttmp->ref.' : '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors'); - } elseif ($resteapayer < 0) { + } elseif ($objecttmp->resteapayer < 0) { $error++; setEventMessages($langs->trans("Salary").' '.$objecttmp->ref.' : '.$langs->trans("AmountMustBePositive"), $objecttmp->errors, 'errors'); } diff --git a/htdocs/salaries/paiement_salary.php b/htdocs/salaries/paiement_salary.php index fcb4cb9ad53..f084e5e1a07 100644 --- a/htdocs/salaries/paiement_salary.php +++ b/htdocs/salaries/paiement_salary.php @@ -167,6 +167,7 @@ $help_url = ''; llxHeader('', '', $help_url); $salary = $object; +$sumpaid = 0.0; // Formulaire de creation d'un paiement de charge if ($action == 'create') { @@ -214,7 +215,7 @@ if ($action == 'create') { $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - $sumpaid = $obj->total; + $sumpaid = (float) $obj->total; $db->free($resql); } /*print ''; diff --git a/htdocs/salaries/virement_request.php b/htdocs/salaries/virement_request.php index 71adbc34e3b..de001535e3f 100644 --- a/htdocs/salaries/virement_request.php +++ b/htdocs/salaries/virement_request.php @@ -276,12 +276,12 @@ print '
'; print '
'.$langs->trans("DateStartPeriod").""; + print '
'.$langs->trans("DateStartPeriod").""; print $form->selectDate($object->datesp, 'datesp', 0, 0, 0, 'datesp', 1); print "
' . $langs->trans("DateStartPeriod") . ''; + print '' . $langs->trans("DateStartPeriod") . ''; print dol_print_date($object->datesp, 'day'); print '
'.$langs->trans("AlreadyPaid").''.price($sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
'; if ($action == 'edit') { - print '"; } else { print ""; - print ''; } diff --git a/htdocs/societe/admin/societe.php b/htdocs/societe/admin/societe.php index 7daf29d6ca7..8d2af81cabb 100644 --- a/htdocs/societe/admin/societe.php +++ b/htdocs/societe/admin/societe.php @@ -837,11 +837,11 @@ if (!$conf->use_javascript_ajax) { } else { print '"; @@ -858,11 +858,11 @@ if (!$conf->use_javascript_ajax) { } else { print '"; diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index 36d7a284d74..51f33f87f6f 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -44,6 +44,7 @@ if (!defined('NOREQUIRESOC')) { // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + /** * @var Conf $conf * @var DoliDB $db diff --git a/htdocs/societe/canvas/company/tpl/card_create.tpl.php b/htdocs/societe/canvas/company/tpl/card_create.tpl.php index 379abf2e8cc..dc2ef93fc6f 100644 --- a/htdocs/societe/canvas/company/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_create.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2010-2012 Laurent Destailleur +/* Copyright (C) 2010 Regis Houssin + * Copyright (C) 2010-2012 Laurent Destailleur * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -18,10 +18,13 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php index 5143b84ea73..03a353f7eb8 100644 --- a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php @@ -18,10 +18,12 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/company/tpl/card_view.tpl.php b/htdocs/societe/canvas/company/tpl/card_view.tpl.php index 82191b9faa0..f1246e4bb66 100644 --- a/htdocs/societe/canvas/company/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_view.tpl.php @@ -16,10 +16,13 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { @@ -37,17 +40,16 @@ $head = societe_prepare_head($soc); print dol_get_fiche_head($head, 'card', $langs->trans("ThirdParty"), 0, 'company'); -?> - -control->tpl['error']) { +if ($this->control->tpl['error']) { echo $this->control->tpl['error']; -} ?> -control->tpl['action_delete']) { +} +if ($this->control->tpl['action_delete']) { echo $this->control->tpl['action_delete']; -} ?> -control->tpl['js_checkVatPopup']) { +} +if ($this->control->tpl['js_checkVatPopup']) { echo $this->control->tpl['js_checkVatPopup']; -} ?> +} +?>
'.$langs->trans("DateStartPeriod").""; + print '
'.$langs->trans("DateStartPeriod").""; print $form->selectDate($object->datesp, 'datesp', 0, 0, 0, 'datesp', 1); print "
' . $langs->trans("DateStartPeriod") . ''; + print '' . $langs->trans("DateStartPeriod") . ''; print dol_print_date($object->datesp, 'day'); print '
'; $arrval = array('0' => $langs->trans("No"), - '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', - '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', - '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', + '1' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 1).'', + '2' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 2).'', + '3' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 3).'', ); - print $form->selectarray("activate_COMPANY_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('COMPANY_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp'); + print $form->selectarray("activate_COMPANY_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('COMPANY_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp maxwidth400'); print ''; print ''; print "'; $arrval = array('0' => $langs->trans("No"), - '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', - '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', - '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', + '1' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 1).'', + '2' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 2).'', + '3' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 3).'', ); - print $form->selectarray("activate_CONTACT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp'); + print $form->selectarray("activate_CONTACT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp maxwidth400'); print ''; print ''; print "
diff --git a/htdocs/societe/canvas/individual/tpl/card_create.tpl.php b/htdocs/societe/canvas/individual/tpl/card_create.tpl.php index ebd3dcb6e01..0620678fc02 100644 --- a/htdocs/societe/canvas/individual/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_create.tpl.php @@ -18,12 +18,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php b/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php index d21880eb303..3964a8a7491 100644 --- a/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php @@ -18,12 +18,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php index 2c0a6277ac4..07e2afc2ae0 100644 --- a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php @@ -17,12 +17,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index e4a3c6c47d5..12675e6d369 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -17,6 +17,7 @@ * Copyright (C) 2023 Nick Fragoulis * Copyright (C) 2023 Alexandre Janniaux * Copyright (C) 2024 MDW + * Copyright (C) 2024 Charlene Benke * * 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 @@ -1071,7 +1072,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio $object->firstname = GETPOST('firstname', 'alphanohtml'); $object->particulier = $private; $object->prefix_comm = GETPOST('prefix_comm', 'alphanohtml'); - $object->client = GETPOSTINT('client') ? GETPOSTINT('client') : $object->client; + //$object->client = GETPOSTINT('client') ? GETPOSTINT('client') : $object->client; if (empty($duplicate_code_error)) { $object->code_client = GETPOST('customer_code', 'alpha'); @@ -1960,7 +1961,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print ''; print ''; print ''; print ''; } +if (!empty($arrayfields['s.ref_ext']['checked'])) { + print ''; +} // Barcode if (!empty($arrayfields['s.barcode']['checked'])) { print '\n"; + if (!$i) { + $totalarray['nbfield']++; + } + } // Barcode if (!empty($arrayfields['s.barcode']['checked'])) { print ''; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index adab42af0fa..5b55fe39776 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -748,8 +748,12 @@ input:-webkit-autofill { /* CSS for placeholder */ .placeholder { color: #ccc; } +select.placeholder { color: #ccc; } ::-webkit-input-placeholder { color: #ccc; } input:-moz-placeholder { color: #ccc; } +select.placeholder option:not(.opacitymediumbycolor):not(.opacitymedium) { + color: var(--colortext); +} input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; } fieldset { @@ -766,6 +770,7 @@ input#onlinepaymenturl, input#directdownloadlink { opacity: 0.7; } + .formconsumeproduce { background: #f3f3f3; padding: 20px 0px 0px 0px; @@ -1712,7 +1717,7 @@ select.flat.selectlimit { -webkit-line-clamp: 2; overflow: hidden; } -.twolinesmax { +.twolinesmax, .twolinesmax-normallineheight { /* To be used into a
into a td for example */ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; @@ -1720,6 +1725,9 @@ select.flat.selectlimit { height: auto !important; word-break: break-word; } +.twolinesmax-normallineheight { + line-height: normal; +} .tenlinesmax { display: -webkit-box; -webkit-box-orient: vertical; @@ -4404,10 +4412,12 @@ table.liste tr:last-child th:last-child { border-bottom-right-radius: px; } -table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:first-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-left-radius: px; } -table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:last-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-right-radius: px; } @@ -4481,8 +4491,8 @@ table.tableforfield td, .tagtr.table-border-row .tagtd { } table.liste td, table.noborder td, div.noborder form div, table.tableforservicepart1 td, table.tableforservicepart2 td { padding: 6px 10px 6px 12px; /* t r b l */ - /* line-height: 22px; This create trouble on cell login on list of last events of a contract*/ - height: 30px; + /* line-height: 22px; This create trouble on cell login on list of last events of a contract */ + height: 32px; } table.liste tr.trkanban td { padding: 12px 15px 12px 15px; /* t r b l */ @@ -5605,7 +5615,7 @@ table.table-fiche-title .col-title div.titre > span:not(.print-barre-liste) { } table.table-fiche-title, div.fiche>table.table-fiche-title { - margin-bottom: 18px; + margin-bottom: 12px; } .table-list-of-attached-files, .table-list-of-links { margin-bottom: 0 !important; diff --git a/htdocs/theme/md/main_menu_fa_icons.inc.php b/htdocs/theme/md/main_menu_fa_icons.inc.php index d5373467280..a08b85c27c1 100644 --- a/htdocs/theme/md/main_menu_fa_icons.inc.php +++ b/htdocs/theme/md/main_menu_fa_icons.inc.php @@ -107,14 +107,15 @@ div.mainmenu.generic4::before { text-align: center; } -.menu_titre .em092 { + +.em092 { font-size: 0.92em; } -.menu_titre .em088 { +.em088 { font-size: 0.88em; } -.menu_titre .em080 { +.em080 { font-size: 0.80em; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c1c1ff04592..621f27e1090 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -933,11 +933,15 @@ input[type=checkbox], input[type=radio] { /* CSS for placeholder */ .placeholder { color: #ccc; } +select.placeholder { color: #ccc; } ::-webkit-input-placeholder { color:#ccc; } :-moz-placeholder { color:#bbb; } /* firefox 18- */ ::-moz-placeholder { color:#bbb; } /* firefox 19+ */ :-ms-input-placeholder { color:#ccc; } /* ie */ input:-moz-placeholder { color:#ccc; } +select.placeholder option:not(.opacitymediumbycolor):not(.opacitymedium) { + color: var(--colortext); +} input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; } fieldset { @@ -1863,7 +1867,7 @@ select.flat.selectlimit { -webkit-line-clamp: 2; overflow: hidden; } -.twolinesmax { +.twolinesmax, .twolinesmax-normallineheight { /* To be used into a
into a td for example */ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; @@ -1871,6 +1875,9 @@ select.flat.selectlimit { height: auto !important; word-break: break-word; } +.twolinesmax-normallineheight { + line-height: normal; +} .tenlinesmax { display: -webkit-box; -webkit-box-orient: vertical; @@ -4471,10 +4478,12 @@ table.liste tr:last-child th:last-child { border-bottom-right-radius: px; } -table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:first-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-left-radius: px; } -table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:last-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-right-radius: px; } @@ -4487,7 +4496,7 @@ tr.liste_titre_filter td.liste_titre { padding-top: 4px; padding-bottom: 3px; } -.liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd +.liste_titre_create td:not(.linecoldescription), .liste_titre_create th, .liste_titre_create .tagtd { border-top-width: 1px; border-top-color: var(--colortopbordertitle1); @@ -4509,13 +4518,17 @@ tr#trlinefordates td { border-top-style: solid; } +td.linecoldescription { + padding: 6px 10px 6px 12px !important; /* t r b l */ +} + table.liste th, table.noborder th, table.noborder tr.liste_titre td, table.noborder tr.box_titre td { padding: 8px 8px 8px 10px; /* t r b l */ } table.liste td, table.noborder td, div.noborder form div, table.tableforservicepart1 td, table.tableforservicepart2 td { padding: 4px 8px 4px 10px; /* t r b l */ - height: 22px; + height: 28px; } table.liste tr.trkanban td { padding: 12px 15px 12px 15px; /* t r b l */ diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 9121d0ec032..e0da84aa3d9 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -3192,7 +3192,7 @@ class Ticket extends CommonObject while ($obj = $this->db->fetch_object($resql)) { $response->nbtodo++; if ($mode == 'opened') { - $datelimit = $this->db->jdate($obj->datec) + $delay_warning; + $datelimit = (int) $this->db->jdate($obj->datec) + (int) $delay_warning; if ($datelimit < $now) { //$response->nbtodolate++; } diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index adc2322e526..b7c9d5e3c45 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -550,13 +550,13 @@ class ProductCombination // MultiPrix if (getDolGlobalString('PRODUIT_MULTIPRICES')) { - $produit_multiprices_limit = getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'); + $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); for ($i = 1; $i <= $produit_multiprices_limit; $i++) { if ($parent->multiprices[$i] != '' || isset($this->combination_price_levels[$i]->variation_price)) { $new_type = empty($parent->multiprices_base_type[$i]) ? 'HT' : $parent->multiprices_base_type[$i]; $new_min_price = $parent->multiprices_min[$i]; $variation_price = (float) (!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price); - $variation_price_percentage = (float) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); + $variation_price_percentage = (bool) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); if ($parent->prices_by_qty_list[$i]) { $new_psq = 1; @@ -867,14 +867,14 @@ class ProductCombination $newproduct->description .= ''.$prodattr->label.': '.$prodattrval->value; } - $newcomb->variation_price_percentage = $price_var_percent[1]; + $newcomb->variation_price_percentage = (bool) $price_var_percent[1]; $newcomb->variation_price = $price_impact[1]; $newcomb->variation_weight = $weight_impact; $newcomb->variation_ref_ext = $this->db->escape($ref_ext); // Init price level if (getDolGlobalString('PRODUIT_MULTIPRICES')) { - $produit_multiprices_limit = getDolGlobalString('PRODUIT_MULTIPRICES_LIMIT'); + $produit_multiprices_limit = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); for ($i = 1; $i <= $produit_multiprices_limit; $i++) { $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fk_product_attribute_combination = $newcomb->id; @@ -882,7 +882,7 @@ class ProductCombination $productCombinationLevel->variation_price = $price_impact[$i]; if (is_array($price_var_percent)) { - $productCombinationLevel->variation_price_percentage = (empty($price_var_percent[$i]) ? false : $price_var_percent[$i]); + $productCombinationLevel->variation_price_percentage = (bool) $price_var_percent[$i] ; } else { $productCombinationLevel->variation_price_percentage = $price_var_percent; } diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index 0e31f37cba9..e32143113c6 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -302,7 +302,8 @@ if (($action == 'add' || $action == 'create') && $usercancreate && empty($massac if (getDolGlobalString('PRODUIT_MULTIPRICES')) { $prodcomb->combination_price_levels = array(); - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + $maxi = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); + for ($i = 1; $i <= $maxi; $i++) { $productCombinationLevel = new ProductCombinationLevel($db); $productCombinationLevel->fk_product_attribute_combination = $prodcomb->id; $productCombinationLevel->fk_price_level = $i; @@ -723,14 +724,16 @@ if (!empty($id) || !empty($ref)) {
fetchCombinationPriceLevels(); - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + $maxi = getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); + for ($i = 1; $i <= $maxi; $i++) { $keyforlabel = 'PRODUIT_MULTIPRICES_LABEL'.$i; $text = $langs->trans('ImpactOnPriceLevel', $i).' - '.getDolGlobalString($keyforlabel); print ''; @@ -740,7 +743,7 @@ if (!empty($id) || !empty($ref)) { } print ''; print ''; print ''; @@ -767,7 +770,7 @@ if (!empty($id) || !empty($ref)) { let priceImpact = $( "#level_price_impact_1" ).val(); let priceImpactPrecent = $( "#level_price_impact_percent_1" ).prop("checked"); - var multipricelimit = global->PRODUIT_MULTIPRICES_LIMIT); ?> + let multipricelimit = for (let i = 2; i <= multipricelimit; i++) { $( "#level_price_impact_" + i ).val(priceImpact); diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index c8c6c71ee3e..7ebe585c1f9 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1245,15 +1245,17 @@ class Website extends CommonObject dol_mkdir($conf->website->dir_temp.'/'.$object->ref); $filename = basename($pathtofile); + $reg = array(); if (!preg_match('/^website_(.*)-(.*)$/', $filename, $reg)) { $this->errors[] = 'Bad format for filename '.$filename.'. Must be website_XXX-VERSION.'; return -3; } + // Uncompress the zip $result = dol_uncompress($pathtofile, $conf->website->dir_temp.'/'.$object->ref); if (!empty($result['error'])) { - $this->errors[] = 'Failed to unzip file '.$pathtofile.'.'; + $this->errors[] = 'Failed to unzip file '.$pathtofile; return -4; } @@ -1820,6 +1822,8 @@ class Website extends CommonObject */ public function setTemplateName($name_template) { + $this->db->begin(); + $sql = "UPDATE ".$this->db->prefix()."website SET"; $sql .= " name_template = '".$this->db->escape($name_template)."'"; $sql .= " WHERE rowid = ".(int) $this->id; diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 81dcb2f1dab..46d428bac93 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -454,6 +454,11 @@ if ($action == 'setwebsiteoffline' && $usercanedit) { exit; } if ($action == 'seteditinline') { // Test on permission not required here + if (!getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) { + // Show warning for feature not yet ready + setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings'); + } + dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 1); //dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 0); // Force disable of 'Include dynamic content' header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('pageid')); @@ -3544,8 +3549,10 @@ if (!GETPOST('hide_websitemenu')) { isEditingEnabled = true; // Trigger the function when clicking outside the elements with contenteditable=true attribute + // so we can save the change. $(document).on(\'click\', function(e) { var target = $(e.target); + // Check if the click is outside the elements with contenteditable=true attribute if (!target.closest(\'[contenteditable="true"]\').length) { // Repeat through the elements with contenteditable="true" attribute @@ -3553,6 +3560,7 @@ if (!GETPOST('hide_websitemenu')) { var idToUse = $(this).attr(\'id\'); var elementType = $(this).prop("tagName").toLowerCase(); // Get the tag name (div, section, footer...) var instance = CKEDITOR.instances[idToUse]; + // Check if the element has been modified if ($(this).hasClass(\'modified\')) { var content = instance.getData(); @@ -3561,13 +3569,18 @@ if (!GETPOST('hide_websitemenu')) { // Retrieving the content and ID of the element var elementId = $(this).attr(\'id\'); - // Sending data via AJAX + '; + if (getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) { + print ' + console.log("A change has been detected, we send new content for update with ajax"); + + // Sending data via AJAX to update section $.ajax({ type: \'POST\', url: \'' . DOL_URL_ROOT . '/core/ajax/editinline.php\', data: { - website_ref: \''.$website->ref.'\', - page_id: \'' . $websitepage->id . '\', + website_ref: \''.dol_escape_js($website->ref).'\', + page_id: \'' . ((int) $websitepage->id) . '\', content: content, element_id: elementId, element_type: elementType, @@ -3598,6 +3611,11 @@ if (!GETPOST('hide_websitemenu')) { }, 2000); } }); + '; + } else { + print 'console.log("A change has been detected, but saving is not enabled by option WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT, so no ajax update is done");'; + } + print ' $(this).removeClass(\'modified\'); } @@ -4216,6 +4234,7 @@ if ($action == 'createsite') { print '
'; } +// Page view to import a website template if ($action == 'importsite') { print ''; print '
'; @@ -4895,8 +4914,6 @@ if ($action == 'preview') { if ($action == 'editfile' || $action == 'file_manager' || $action == 'convertimgwebp' || $action == 'confirmconvertimgwebp') { print ''."\n"; print '

'; - //print '
'.$langs->trans("FeatureNotYetAvailable").''; - $module = 'medias'; $formalreadyopen = 2; // So the form to submit a new file will not be open another time inside the core/tpl/filemanager.tpl.php diff --git a/phpstan.neon.dist b/phpstan.neon.dist index de1271a36e1..a21273cea08 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -19,7 +19,6 @@ parameters: - scripts excludePaths: analyseAndScan: - - htdocs/admin/tools/ui/* - htdocs/custom/* - htdocs/documents/* - htdocs/install/doctemplates/* diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index d7ee2915281..c636f9e129a 100755 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -43,10 +43,9 @@ if (substr($sapi_type, 0, 3) == 'cgi') { require_once $path."../../htdocs/master.inc.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/functionscli.lib.php'; // After this $db is an opened handler to database. We close it at end of file. -require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"; -require_once DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice2.lib.php'; + /** * @var Conf $conf * @var DoliDB $db @@ -83,12 +82,15 @@ if (!empty($dolibarr_main_db_readonly)) { exit(1); } -$diroutputpdf = $conf->invoice->dir_output.'/temp'; + $newlangid = 'en_EN'; // To force a new lang id $filter = array(); $regenerate = ''; // Ask regenerate (contains name of model to use) $option = ''; $fileprefix = 'mergedpdf'; +$nomerge = 0; +$mode = 'invoice'; + $dateafterdate = ''; $datebeforedate = ''; $paymentdateafter = ''; @@ -113,6 +115,14 @@ foreach ($argv as $key => $value) { print 'Use prefix for filename '.$fileprefix.".\n"; } + if (preg_match('/^mode=/i', $value)) { + $found = true; + $valarray = explode('=', $value); + $mode = $valarray[1]; + print 'Use mode '.$fileprefix.".\n"; + } + + $reg = array(); if (preg_match('/^regenerate=(.*)/i', $value, $reg)) { if (!in_array($reg[1], array('', '0', 'no'))) { $found = true; @@ -120,6 +130,14 @@ foreach ($argv as $key => $value) { print 'Regeneration of PDF is requested with template '.$regenerate."\n"; } } + if (preg_match('/^regeneratenomerge=(.*)/i', $value, $reg)) { + if (!in_array($reg[1], array('', '0', 'no'))) { + $found = true; + $regenerate = $reg[1]; + $nomerge = 1; + print 'Regeneration (without merge) of PDF is requested with template '.$regenerate."\n"; + } + } if ($value == 'filter=all') { $found = true; @@ -136,7 +154,7 @@ foreach ($argv as $key => $value) { $dateafterdate = dol_stringtotime($argv[$key + 1]); $datebeforedate = dol_stringtotime($argv[$key + 2]); - print 'Rebuild PDF for invoices validated between '.dol_print_date($dateafterdate, 'day', 'gmt')." and ".dol_print_date($datebeforedate, 'day', 'gmt').".\n"; + print 'Rebuild PDF for documents validated between '.dol_print_date($dateafterdate, 'day', 'gmt')." and ".dol_print_date($datebeforedate, 'day', 'gmt').".\n"; } if ($value == 'filter=payments') { @@ -150,7 +168,7 @@ foreach ($argv as $key => $value) { print 'Error: Bad date format or value'."\n"; exit(1); } - print 'Rebuild PDF for invoices with at least one payment between '.dol_print_date($paymentdateafter, 'day', 'gmt')." and ".dol_print_date($paymentdatebefore, 'day', 'gmt').".\n"; + print 'Rebuild PDF for ivoices with at least one payment between '.dol_print_date($paymentdateafter, 'day', 'gmt')." and ".dol_print_date($paymentdatebefore, 'day', 'gmt').".\n"; } if ($value == 'filter=nopayment') { @@ -158,7 +176,7 @@ foreach ($argv as $key => $value) { $option .= (empty($option) ? '' : '_').'nopayment'; $filter[] = 'nopayment'; - print 'Rebuild PDF for invoices with no payment done yet.'."\n"; + print 'Rebuild PDF for ivoices with no payment done yet.'."\n"; } if ($value == 'filter=bank') { @@ -242,9 +260,11 @@ if (in_array('bank', $filter) && in_array('nopayment', $filter)) { exit(1); } +$diroutputpdf = 'auto'; + // Define SQL and SQL request to select invoices // Use $filter, $dateafterdate, datebeforedate, $paymentdateafter, $paymentdatebefore -$result = rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option, (string) $paymentonbankid, $thirdpartiesid, $fileprefix); +$result = rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option, (string) $paymentonbankid, $thirdpartiesid, $fileprefix, $nomerge, $mode); // -------------------- END OF YOUR CODE -------------------- @@ -269,29 +289,29 @@ function rebuild_merge_pdf_usage() { global $script_file; - print "Rebuild PDF files for some invoices and merge PDF files into one.\n"; + print "Rebuild PDF files for some invoices/orders/proposals and/or merge PDF files into one.\n"; print "\n"; - print "To build/merge PDF for invoices in a date range:\n"; - print "Usage: ".$script_file." filter=date dateafter datebefore\n"; + print "To build/merge PDF for all documents, use filter=all\n"; + print "Usage: ".$script_file." mode=invoice filter=all\n"; + print "To build/merge PDF for documents in a date range:\n"; + print "Usage: ".$script_file." mode=invoice filter=date dateafter datebefore\n"; print "To build/merge PDF for invoices with at least one payment in a date range:\n"; - print "Usage: ".$script_file." filter=payments dateafter datebefore\n"; + print "Usage: ".$script_file." mode=invoice filter=payments dateafter datebefore\n"; print "To build/merge PDF for invoices with at least one payment onto a bank account:\n"; - print "Usage: ".$script_file." filter=bank bankref\n"; - print "To build/merge PDF for all invoices, use filter=all\n"; - print "Usage: ".$script_file." filter=all\n"; + print "Usage: ".$script_file." mode=invoice filter=bank bankref\n"; print "To build/merge PDF for invoices with no payments, use filter=nopayment\n"; - print "Usage: ".$script_file." filter=nopayment\n"; + print "Usage: ".$script_file." mode=invoice filter=nopayment\n"; print "To exclude credit notes, use filter=nocreditnote\n"; print "To exclude replacement invoices, use filter=noreplacement\n"; print "To exclude deposit invoices, use filter=nodeposit\n"; print "To exclude some thirdparties, use filter=excludethirdparties id1,id2...\n"; print "To limit to some thirdparties, use filter=onlythirdparties id1,id2...\n"; - print "To regenerate existing PDF, use regenerate=templatename\n"; - print "To generate invoices in a language, use lang=xx_XX\n"; + print "To regenerate existing PDF, use regenerate=templatename or regeneratenomerge=templatename\n"; + print "To generate documents in a given language, use lang=xx_XX\n"; print "To set prefix of generated file name, use prefix=myfileprefix\n"; print "\n"; - print "Example: ".$script_file." filter=payments 20080101 20081231 lang=fr_FR regenerate=crabe\n"; - print "Example: ".$script_file." filter=all lang=en_US\n"; + print "Example: ".$script_file." mode=invoice filter=payments 20080101 20081231 lang=fr_FR regenerate=crabe\n"; + print "Example: ".$script_file." mode=invoice filter=all lang=en_US\n"; print "\n"; print "Note that some filters can be cumulated.\n"; } diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 12e58357aa4..ae5b2c03595 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -134,6 +134,8 @@ class AllTests $suite->addTestSuite('SecurityTest'); require_once dirname(__FILE__).'/SecurityGETPOSTTest.php'; $suite->addTestSuite('SecurityGETPOSTTest'); + require_once dirname(__FILE__).'/SecurityLoginTest.php'; + $suite->addTestSuite('SecurityLoginTest'); require_once dirname(__FILE__).'/UserTest.php'; $suite->addTestSuite('UserTest'); diff --git a/test/phpunit/SecurityLoginTest.php b/test/phpunit/SecurityLoginTest.php new file mode 100644 index 00000000000..2e4d190567c --- /dev/null +++ b/test/phpunit/SecurityLoginTest.php @@ -0,0 +1,106 @@ + + * Copyright (C) 2023 Alexandre Janniaux + * Copyright (C) 2024 Frédéric 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 . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/SecurityTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; + +if (! defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +if (! defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', '1'); +} +if (! defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); +} +if (! defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); // If there is no menu to show +} +if (! defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +} +if (! defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (! defined("NOLOGIN")) { + define("NOLOGIN", '1'); // If this page is public (can be called outside logged session) +} +if (! defined("NOSESSION")) { + define("NOSESSION", '1'); +} + +require_once dirname(__FILE__).'/../../htdocs/main.inc.php'; // We force include of main.inc.php instead of master.inc.php even if we are in CLI mode because it contains a lot of security components we want to test. +require_once dirname(__FILE__).'/../../htdocs/core/lib/security.lib.php'; +require_once dirname(__FILE__).'/../../htdocs/core/lib/security2.lib.php'; +require_once dirname(__FILE__).'/CommonClassTest.class.php'; + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->loadRights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS = 1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class SecurityLoginTest extends CommonClassTest +{ + /** + * testCheckLoginPassEntity + * + * @return void + */ + public function testCheckLoginPassEntity() + { + $login = checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, ''); + + $login = checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, ''); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, 'admin'); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('forceuser')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals('', $login, 'Error'); // Expected '' because should failed because login 'auto' does not exists + } +} diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 294d1596fec..743b6d33c8e 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -623,54 +623,83 @@ class SecurityTest extends CommonClassTest $s = '(($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : \'Parent project not found\''; $result = (string) dol_eval($s, 1, 1, '2'); print "result4 = ".$result."\n"; - $this->assertEquals('Parent project not found', $result); + $this->assertEquals('Parent project not found', $result, 'Test 4'); + + $s = '4 < 5'; + $result = (string) dol_eval($s, 1, 1, '2'); + print "result5 = ".$result."\n"; + $this->assertEquals('1', $result, 'Test 5'); + + + /* not allowed. Not a one line eval string + $result = (string) dol_eval('if ($a == 1) { }', 1, 1); + print "result4b = ".$result."\n"; + $this->assertEquals('aaa', $result); + */ + + // Now string not allowed + + $s = '4 <5'; + $result = (string) dol_eval($s, 1, 1, '2'); // in mode 2, char < is allowed only if followed by a space + print "result = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 4 <5 - The string was not detected as evil'); + + $s = '4 < 5'; + $result = (string) dol_eval($s, 1, 1, '1'); // in mode 1, char < is always forbidden + print "result = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 4 < 5 - The string was not detected as evil'); $s = 'new abc->invoke(\'whoami\')'; $result = (string) dol_eval($s, 1, 1, '2'); print "result = ".$result."\n"; - $this->assertEquals('Bad string syntax to evaluate: new abc__forbiddenstring__(\'whoami\')', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $s = 'new ReflectionFunction(\'abc\')'; $result = (string) dol_eval($s, 1, 1, '2'); print "result = ".$result."\n"; - $this->assertEquals('Bad string syntax to evaluate: new __forbiddenstring__(\'abc\')', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); + $result = dol_eval('$a=function() { }; $a', 1, 1, '0'); // result of dol_eval may be an object Closure + print "result5 = ".json_encode($result)."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'The string was not detected as evil'); - $result = (string) dol_eval('$a=function() { }; $a;', 1, 1, '0'); - print "result5 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); - - $result = (string) dol_eval('$a=function() { }; $a;', 1, 1, '1'); - print "result6 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $result = dol_eval('$a=function() { }; $a();', 1, 1, '1'); + print "result6 = ".json_encode($result)."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'The string was not detected as evil'); $result = (string) dol_eval('$a=exec("ls");', 1, 1); print "result7 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval('$a=exec ("ls")', 1, 1); print "result8 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); + + $result = (string) dol_eval("strrev('metsys') ('whoami')", 1, 1); + print "result8b = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval('$a="test"; $$a;', 1, 0); print "result9 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval('`ls`', 1, 0); print "result10 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval("('ex'.'ec')('echo abc')", 1, 0); print "result11 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0); print "result12 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = dol_eval("90402.38+267678+0", 1, 1, 1); print "result13 = ".$result."\n"; - $this->assertEquals('358080.38', $result); + $this->assertEquals('358080.38', $result, 'The string was not detected as evil'); + + // Must be allowed global $leftmenu; // Used into strings to eval @@ -706,23 +735,29 @@ class SecurityTest extends CommonClassTest print "result18 = ".$result."\n"; $this->assertFalse($result); + // Not allowed + $a = 'ab'; $result = (string) dol_eval("(\$a.'s')", 1, 0); print "result19 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 19'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 19 - The string was not detected as evil'); $leftmenu = 'abs'; $result = (string) dol_eval('$leftmenu(-5)', 1, 0); print "result20 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 20'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 20 - The string was not detected as evil'); $result = (string) dol_eval('str_replace("z","e","zxzc")("whoami");', 1, 0); print "result21 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 21'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 21 - The string was not detected as evil'); $result = (string) dol_eval('($a = "ex") && ($b = "ec") && ($cmd = "$a$b") && $cmd ("curl localhost:5555")', 1, 0); print "result22 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 22'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 22 - The string was not detected as evil'); + + $result = (string) dol_eval('\'exec\'("aaa")', 1, 0); + print "result23 = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'Test 23 - The string was not detected as evil - Can\'t find the string Bad string syntax when i should'); } /** @@ -966,33 +1001,4 @@ class SecurityTest extends CommonClassTest return 0; } - - - /** - * testCheckLoginPassEntity - * - * @return void - */ - public function testCheckLoginPassEntity() - { - $login = checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, ''); - - $login = checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, ''); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin'); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('forceuser')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals('', $login, 'Error'); // Expected '' because should failed because login 'auto' does not exists - } } diff --git a/test/phpunit/WebsiteTest.php b/test/phpunit/WebsiteTest.php index 6ccccb17b23..0bdfdb5ca44 100644 --- a/test/phpunit/WebsiteTest.php +++ b/test/phpunit/WebsiteTest.php @@ -65,11 +65,11 @@ if (empty($user->id)) { print "Load permissions for admin user nb 1\n"; $user->fetch(1); $user->loadRights(); - - if (empty($user->rights->website)) { - $user->rights->website = new stdClass(); - } } +if (empty($user->rights->website)) { + $user->rights->website = new stdClass(); +} + $conf->global->MAIN_DISABLE_ALL_MAILS = 1; @@ -132,22 +132,67 @@ class WebsiteTest extends CommonClassTest */ public function testCheckPHPCode() { - global $user; + global $conf, $user; // Force permission so this is not the permission that will affect result of checkPHPCode $user->rights->website->writephp = 1; + // Legitimate + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode detect string as dangerous when it is legitimate'); + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode detect string as dangerous when it is legitimate'); + + + // Dangerous + $t = ''; $s = ''; $result = checkPHPCode($t, $s); print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; $s = ';").($_^"/"); ?>'; $result = checkPHPCode($t, $s); print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + // Dangerous but legitimate due to option WEBSITE_PHP_ALLOW_EXEC + + $conf->global->WEBSITE_PHP_ALLOW_EXEC = 1; + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode did not accept the exec. it should when WEBSITE_PHP_ALLOW_EXEC is set.'); } /**
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; // TODO Use select_doluser in multiselect mode - $userlist = $form->select_dolusers($selected, '', 0, null, 0, '', '', '0', 0, 0, 'AND u.statut = 1', 0, '', '', 0, 2); + $userlist = $form->select_dolusers($selected, '', 0, null, 0, '', '', '0', 0, 0, 'u.statut:=:1', 0, '', '', 0, 2); // Note: If user has no right to "see all thirdparties", we force selection of sale representative to him, so after creation he can see the record. $selected = (GETPOSTISARRAY('commercial') ? GETPOST('commercial', 'array:int') : (GETPOSTINT('commercial') > 0 ? array(GETPOSTINT('commercial')) : array($user->id))); print img_picto('', 'user').$form->multiselectarray('commercial', $userlist, $selected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); @@ -2812,7 +2813,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print '
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; - $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); + $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'u.statut:=:1', 0, '', '', 0, 1); $arrayselected = GETPOST('commercial', 'array'); if (empty($arrayselected)) { $arrayselected = $object->getSalesRepresentatives($user, 1); @@ -2887,7 +2888,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio 'name' => 'soc_origin', 'label' => $langs->trans('MergeOriginThirdparty'), 'type' => 'other', - 'value' => $form->select_company('', 'soc_origin', '', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth200', '', '', 1, array(), false, array($object->id)) + 'value' => $form->select_company('', 'soc_origin', '', 'SelectThirdParty', 1, 0, array(), 0, 'minwidth200', '', '', 1, array(), false, array($object->id)) ) ); diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 0af1d485070..365d2968f0b 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2024 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -194,9 +194,6 @@ class Contacts extends DolibarrApi $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t"; - if ($category > 0) { - $sql .= ", ".MAIN_DB_PREFIX."categorie_contact as c"; - } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as te ON te.fk_object = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON t.fk_soc = s.rowid"; $sql .= ' WHERE t.entity IN ('.getEntity('contact').')'; @@ -213,8 +210,37 @@ class Contacts extends DolibarrApi } // Select contacts of given category if ($category > 0) { - $sql .= " AND c.fk_categorie = ".((int) $category); - $sql .= " AND c.fk_socpeople = t.rowid "; + // Search Contact Categories + $searchCategoryContactList = $category ? array($category) : array(); + // $searchCategoryContactOperator = 0; + // Search for tag/category ($searchCategoryContactList is an array of ID) + if (!empty($searchCategoryContactList)) { + $searchCategoryContactSqlList = array(); + // $listofcategoryid = ''; + foreach ($searchCategoryContactList as $searchCategoryContact) { + if (intval($searchCategoryContact) == -2) { + $searchCategoryContactSqlList[] = "NOT EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople)"; + } elseif (intval($searchCategoryContact) > 0) { + // if ($searchCategoryContactOperator == 0) { + $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")"; + // } else { + // $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact); + // } + } + } + // if ($listofcategoryid) { + // $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$this->db->sanitize($listofcategoryid)."))"; + // } + // if ($searchCategoryContactOperator == 1) { + // if (!empty($searchCategoryContactSqlList)) { + // $sql .= " AND (".implode(' OR ', $searchCategoryContactSqlList).")"; + // } + // } else { + if (!empty($searchCategoryContactSqlList)) { + $sql .= " AND (".implode(' AND ', $searchCategoryContactSqlList).")"; + } + // } + } } // Add sql filters diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 6a81aeede43..70fe8a2f34f 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -85,6 +85,7 @@ $search_id = GETPOST("search_id", 'int'); $search_nom = trim(GETPOST("search_nom", 'restricthtml')); $search_alias = trim(GETPOST("search_alias", 'restricthtml')); $search_nom_only = trim(GETPOST("search_nom_only", 'restricthtml')); +$search_ref_ext = trim(GETPOST("search_ref_ext", 'restricthtml')); $search_barcode = trim(GETPOST("search_barcode", 'alpha')); $search_customer_code = trim(GETPOST('search_customer_code', 'alpha')); $search_supplier_code = trim(GETPOST('search_supplier_code', 'alpha')); @@ -287,7 +288,8 @@ $arrayfields = array( 's.rowid' => array('label' => "TechnicalID", 'position' => 1, 'checked' => -1, 'enabled' => 1), 's.nom' => array('label' => "ThirdPartyName", 'position' => 2, 'checked' => 1), 's.name_alias' => array('label' => "AliasNameShort", 'position' => 3, 'checked' => 1), - 's.barcode' => array('label' => "Gencod", 'position' => 5, 'checked' => 1, 'enabled' => (isModEnabled('barcode'))), + 's.ref_ext' => array('label' => "RefExt", 'position' => 4, 'checked' => -1, 'enabled' => getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT')), + 's.barcode' => array('label' => "Gencod", 'position' => 5, 'checked' => 1, 'enabled' => isModEnabled('barcode')), 's.code_client' => array('label' => "CustomerCodeShort", 'position' => 10, 'checked' => $checkedcustomercode), 's.code_fournisseur' => array('label' => "SupplierCodeShort", 'position' => 11, 'checked' => $checkedsuppliercode, 'enabled' => (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), 's.code_compta' => array('label' => "CustomerAccountancyCodeShort", 'position' => 13, 'checked' => $checkedcustomeraccountcode), @@ -411,6 +413,7 @@ if (empty($reshook)) { $search_id = ''; $search_nom = ''; $search_alias = ''; + $search_ref_ext = ''; $search_categ_cus = 0; $search_categ_sup = 0; $searchCategoryCustomerOperator = 0; @@ -562,7 +565,7 @@ if ($resql) { // Build and execute select // -------------------------------------------------------------------- -$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.barcode, s.address, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; +$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.ref_ext, s.barcode, s.address, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; $sql .= " s.entity,"; $sql .= " st.libelle as stcomm, st.picto as stcomm_picto, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status, s.note_private, s.note_public,"; $sql .= " s.email, s.phone, s.phone_mobile, s.fax, s.url, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4 as idprof4, s.idprof5 as idprof5, s.idprof6 as idprof6, s.tva_intra, s.fk_pays,"; @@ -715,6 +718,9 @@ if (empty($arrayfields['s.name_alias']['checked']) && $search_nom) { if ($search_nom_only) { $sql .= natural_search("s.nom", $search_nom_only); } +if ($search_ref_ext) { + $sql .= natural_search("s.ref_ext", $search_ref_ext); +} if ($search_customer_code) { $sql .= natural_search("s.code_client", $search_customer_code); } @@ -970,6 +976,9 @@ if ($search_nom != '') { if ($search_alias != '') { $param .= "&search_alias=".urlencode($search_alias); } +if ($search_ref_ext != '') { + $param .= "&search_ref_ext=".urlencode($search_ref_ext); +} if ($search_address != '') { $param .= '&search_address='.urlencode($search_address); } @@ -1281,7 +1290,7 @@ if (empty($type) || $type == 'f') { } // If the user can view prospects other than his' -$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); +$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'u.statut:=:1', 0, '', '', 0, 1); $userlist[-2] = $langs->trans("NoSalesRepresentativeAffected"); if ($user->hasRight("societe", "client", "voir") || $socid) { $moreforfilter .= '
'; @@ -1335,6 +1344,11 @@ if (!empty($arrayfields['s.name_alias']['checked'])) { print ''; print '
'; + print ''; + print ''; @@ -1619,6 +1633,11 @@ if (!empty($arrayfields['s.name_alias']['checked'])) { print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER["PHP_SELF"], "s.name_alias", "", $param, "", $sortfield, $sortorder); $totalarray['nbfield']++; } +if (!empty($arrayfields['s.ref_ext']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset + print_liste_field_titre($arrayfields['s.ref_ext']['label'], $_SERVER["PHP_SELF"], "s.ref_ext", "", $param, "", $sortfield, $sortorder); + $totalarray['nbfield']++; +} if (!empty($arrayfields['s.barcode']['checked'])) { print_liste_field_titre($arrayfields['s.barcode']['label'], $_SERVER["PHP_SELF"], "s.barcode", $param, '', '', $sortfield, $sortorder); $totalarray['nbfield']++; @@ -1807,6 +1826,7 @@ while ($i < $imaxinloop) { $companystatic->id = $obj->rowid; $companystatic->name = $obj->name; $companystatic->name_alias = $obj->name_alias; + $companystatic->ref_ext = $obj->ref_ext; $companystatic->logo = $obj->logo; $companystatic->barcode = $obj->barcode; $companystatic->canvas = $obj->canvas; @@ -1899,6 +1919,15 @@ while ($i < $imaxinloop) { $totalarray['nbfield']++; } } + // Ref ext + if (!empty($arrayfields['s.ref_ext']['checked'])) { + print ''; + print dol_escape_htmltag($companystatic->ref_ext); + print "'.dol_escape_htmltag($companystatic->barcode).'
- > + + >
'; - print 'combination_price_levels[$i]->variation_price_percentage) ? ' checked' : '').'> '; + print 'combination_price_levels[$i]->variation_price_percentage ? ' checked' : '').'> '; print '