Przeglądaj źródła

Merge remote-tracking branch 'upstream/develop' into Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword

Frédéric FRANCE 5 lat temu
rodzic
commit
2085ac73e7

+ 2 - 2
build/docker/Dockerfile

@@ -3,7 +3,7 @@ FROM php:7.2-apache
 ENV HOST_USER_ID 33
 ENV PHP_INI_DATE_TIMEZONE 'UTC'
 
-RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev libldap2-dev libzip-dev zlib1g-dev libicu-dev g++\
+RUN apt-get update && apt-get install -y libpng16-16 libpng-dev libjpeg62-turbo libjpeg62-turbo-dev libldap2-dev zlib1g-dev libicu-dev g++\
 	&& rm -rf /var/lib/apt/lists/* \
 	&& docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
 	&& docker-php-ext-install gd \
@@ -14,7 +14,7 @@ RUN apt-get update && apt-get install -y libpng-dev libjpeg-dev libldap2-dev lib
         && docker-php-ext-install calendar \
         && docker-php-ext-configure intl \
         && docker-php-ext-install intl \
-        && apt-get autoremove --purge -y libjpeg-dev libldap2-dev zlib1g-dev libicu-dev g++
+        && apt-get autoremove --purge -y libpng-dev libjpeg62-turbo-dev libldap2-dev zlib1g-dev libicu-dev g++
 
 RUN mkdir /var/documents
 RUN chown www-data /var/documents

+ 7 - 0
build/docker/docker-compose.yml

@@ -21,5 +21,12 @@ web:
         - ../../htdocs:/var/www/html
     links:
         - mariadb
+        - mail
     ports:
         - "80:80"
+
+mail:
+    image: maildev/maildev
+    ports:
+        - "8081:80"
+        - "25:25"

+ 1 - 1
htdocs/bom/bom_card.php

@@ -519,7 +519,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
 	$keyforbreak = 'duration';
 	include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
 
-	print '<tr><td>'.$langs->trans("TotalCost").'</td><td>'.price($object->total_cost).'</td></tr>';
+	print '<tr><td>'.$form->textwithpicto($langs->trans("TotalCost"), $langs->trans("BOMTotalCost")).'</td><td>'.price($object->total_cost).'</td></tr>';
 	print '<tr><td>'.$langs->trans("UnitCost").'</td><td>'.price($object->unit_cost).'</td></tr>';
 
 	// Other attributes

+ 10 - 1
htdocs/bom/class/bom.class.php

@@ -997,11 +997,20 @@ class BOM extends CommonObject
 		$this->unit_cost = 0;
 		$this->total_cost = 0;
 
+		require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
+		$productFournisseur = new ProductFournisseur($this->db);
+
 		foreach ($this->lines as &$line) {
 			$tmpproduct = new Product($this->db);
 			$tmpproduct->fetch($line->fk_product);
+			$line->unit_cost = price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
+			if (empty($line->unit_cost)) {
+				if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0)
+				{
+					$line->unit_cost = $productFournisseur->fourn_unitprice;
+				}
+			}
 
-			$line->unit_cost = (!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp; // TODO : add option to work with cost_price or pmp
 			$line->total_cost = price2num($line->qty * $line->unit_cost, 'MT');
 			$this->total_cost += $line->total_cost;
 		}

+ 42 - 0
htdocs/comm/action/class/actioncomm.class.php

@@ -337,6 +337,20 @@ class ActionComm extends CommonObject
      */
     public $errors_to;
 
+	/**
+	 * Typical value for a event that is in a todo state
+	 */
+	const EVENT_TODO = 0;
+
+	/**
+	 * Typical value for a event that is in a progress state
+	 */
+	const EVENT_IN_PROGRESS = 50;
+
+	/**
+	 * Typical value for a event that is in a finished state
+	 */
+	const EVENT_FINISHED = 100;
 
     /**
      *      Constructor
@@ -1961,4 +1975,32 @@ class ActionComm extends CommonObject
 
         return $error;
     }
+
+	/**
+	 * Udpate the percent value of a event with the given id
+	 *
+	 * @param int		$id			The id of the event
+	 * @param int		$percent	The new percent value for the event
+	 * @return int					1 when update of the event was suscessfull, otherwise -1
+	 */
+	public function updatePercent($id, $percent)
+	{
+		$this->db->begin();
+
+		$sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm ";
+		$sql .= " SET percent = ".(int) $percent;
+		$sql .= " WHERE id=".$id;
+
+		if ($this->db->query($sql))
+		{
+			$this->db->commit();
+			return 1;
+		}
+		else
+		{
+			$this->db->rollback();
+			$this->error = $this->db->lasterror();
+			return -1;
+		}
+	}
 }

+ 58 - 2
htdocs/comm/action/list.php

@@ -5,6 +5,7 @@
  * Copyright (C) 2005-2012 Regis Houssin        <regis.houssin@inodbox.com>
  * Copyright (C) 2017      Open-DSI             <support@open-dsi.fr>
  * Copyright (C) 2018       Frédéric France         <frederic.france@netlogic.fr>
+ * Copyright (C) 2020		Tobias Sekan		<tobias.sekan@startmail.com>
  *
  * 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
@@ -40,6 +41,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
 $langs->loadLangs(array("users", "companies", "agenda", "commercial", "other"));
 
 $action = GETPOST('action', 'alpha');
+$massaction = GETPOST('massaction', 'alpha');
 $contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'actioncommlist'; // To manage different context of search
 $resourceid = GETPOST("search_resourceid", "int") ?GETPOST("search_resourceid", "int") : GETPOST("resourceid", "int");
 $pid = GETPOST("search_projectid", 'int', 3) ?GETPOST("search_projectid", 'int', 3) : GETPOST("projectid", 'int', 3);
@@ -49,6 +51,8 @@ $optioncss = GETPOST('optioncss', 'alpha');
 $year = GETPOST("year", 'int');
 $month = GETPOST("month", 'int');
 $day = GETPOST("day", 'int');
+$toselect = GETPOST('toselect', 'array');
+
 // Set actioncode (this code must be same for setting actioncode into peruser, listacton and index)
 if (GETPOST('search_actioncode', 'array'))
 {
@@ -183,9 +187,42 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
     $datestart = '';
     $dateend = '';
     $search_status = '';
+	$toselect = '';
     $search_array_options = array();
 }
 
+if (empty($reshook) && !empty($massaction))
+{
+	unset($percent);
+
+	switch ($massaction)
+	{
+		case 'set_all_events_to_todo':
+			$percent = ActionComm::EVENT_TODO;
+			break;
+
+		case 'set_all_events_to_in_progress':
+			$percent = ActionComm::EVENT_IN_PROGRESS;
+			break;
+
+		case 'set_all_events_to_finished':
+			$percent = ActionComm::EVENT_FINISHED;
+			break;
+	}
+
+	if(isset($percent))
+	{
+		foreach ($toselect as $toselectid)
+		{
+			$result = $object->updatePercent($toselectid, $percent);
+			if($result < 0)
+			{
+				dol_print_error($db);
+				break;
+			}
+		}
+	}
+}
 
 /*
  *  View
@@ -237,6 +274,15 @@ if ($optioncss != '') $param .= '&optioncss='.urlencode($optioncss);
 // Add $param from extra fields
 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
 
+// List of mass actions available
+$arrayofmassactions = array(
+	'set_all_events_to_todo' => $langs->trans("SetAllEventsToTodo"),
+	'set_all_events_to_in_progress' => $langs->trans("SetAllEventsToInProgress"),
+	'set_all_events_to_finished' => $langs->trans("SetAllEventsToFinished"),
+);
+
+$massactionbutton = $form->selectMassAction('', $arrayofmassactions);
+
 $sql = "SELECT";
 if ($usergroup > 0) $sql .= " DISTINCT";
 $sql .= " s.nom as societe, s.rowid as socid, s.client, s.email as socemail,";
@@ -358,6 +404,8 @@ if ($resql)
 
 	$num = $db->num_rows($resql);
 
+	$arrayofselected = is_array($toselect) ? $toselect : array();
+
 	// Local calendar
 	$newtitle = '<div class="nowrap clear inline-block minheight20"><input type="checkbox" id="check_mytasks" name="check_mytasks" checked disabled> '.$langs->trans("LocalAgenda").' &nbsp; </div>';
 	//$newtitle=$langs->trans($title);
@@ -427,7 +475,7 @@ if ($resql)
         $newcardbutton .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/comm/action/card.php?action=create&datep='.sprintf("%04d%02d%02d", $tmpforcreatebutton['year'], $tmpforcreatebutton['mon'], $tmpforcreatebutton['mday']).$hourminsec.'&backtopage='.urlencode($_SERVER["PHP_SELF"].($newparam ? '?'.$newparam : '')));
     }
 
-    print_barre_liste($s, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, -1 * $nbtotalofrecords, '', 0, $nav.$newcardbutton, '', $limit, 0, 0, 1);
+    print_barre_liste($s, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, -1 * $nbtotalofrecords, '', 0, $nav.$newcardbutton, '', $limit, 0, 0, 1);
 
     $moreforfilter = '';
 
@@ -724,7 +772,15 @@ if ($resql)
 			$datep = $db->jdate($obj->datep);
 			print '<td align="center" class="nowrap">'.$actionstatic->LibStatut($obj->percent, 5, 0, $datep).'</td>';
 		}
-		print '<td></td>';
+		// Action column
+		print '<td class="nowrap center">';
+		if ($massactionbutton || $massaction)   // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined
+		{
+			$selected = 0;
+			if (in_array($obj->id, $arrayofselected)) $selected = 1;
+			print '<input id="cb'.$obj->id.'" class="flat checkforselect" type="checkbox" name="toselect[]" value="'.$obj->id.'"'.($selected ? ' checked="checked"' : '').'>';
+		}
+		print '</td>';
 
 		print "</tr>\n";
 		$i++;

+ 17 - 5
htdocs/compta/facture/card.php

@@ -987,7 +987,7 @@ if (empty($reshook))
 		// Replacement invoice
 		if ($_POST['type'] == Facture::TYPE_REPLACEMENT)
 		{
-			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			$dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 			if (empty($dateinvoice))
 			{
 				$error++;
@@ -1048,7 +1048,7 @@ if (empty($reshook))
 				$action = 'create';
 			}
 
-			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			$dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 			if (empty($dateinvoice))
 			{
 				$error++;
@@ -1229,7 +1229,7 @@ if (empty($reshook))
 		// Standard invoice or Deposit invoice, created from a Predefined template invoice
 		if (($_POST['type'] == Facture::TYPE_STANDARD || $_POST['type'] == Facture::TYPE_DEPOSIT) && GETPOST('fac_rec', 'int') > 0)
 		{
-			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			$dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 			if (empty($dateinvoice))
 			{
 				$error++;
@@ -1280,7 +1280,7 @@ if (empty($reshook))
 				$action = 'create';
 			}
 
-			$dateinvoice = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			$dateinvoice = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 			if (empty($dateinvoice))
 			{
 				$error++;
@@ -1699,7 +1699,7 @@ if (empty($reshook))
 		// Situation invoices
 		if (GETPOST('type') == Facture::TYPE_SITUATION && (!empty($_POST['situations'])))
 		{
-			$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+			$datefacture = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 			if (empty($datefacture)) {
 				$error++;
 				$mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date"));
@@ -2823,6 +2823,18 @@ if ($action == 'create')
 		if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code;
 	}
 
+	// when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value
+	if(empty($cond_reglement_id))
+	{
+		$cond_reglement_id = GETPOST("cond_reglement_id");
+	}
+
+	// when payment mode is empty (means not override by payment mode form a other object, like third-party), try to use default value
+	if(empty($mode_reglement_id))
+	{
+		$mode_reglement_id = GETPOST("mode_reglement_id");
+	}
+
 	if (!empty($soc->id)) $absolute_discount = $soc->getAvailableDiscounts();
 	$note_public = $object->getDefaultCreateValueFor('note_public', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && !empty($conf->global->FACTURE_REUSE_NOTES_ON_CREATE_FROM)) ? $objectsrc->note_public : null));
 	$note_private = $object->getDefaultCreateValueFor('note_private', ((!empty($origin) && !empty($originid) && is_object($objectsrc) && !empty($conf->global->FACTURE_REUSE_NOTES_ON_CREATE_FROM)) ? $objectsrc->note_private : null));

+ 0 - 1
htdocs/contact/list.php

@@ -354,7 +354,6 @@ if (strlen($search_fax))            $sql .= natural_search('p.fax', $search_fax)
 if (!empty($conf->socialnetworks->enabled)) {
 	foreach ($socialnetworks as $key => $value) {
 		if ($value['active'] && strlen($search_{$key})) {
-			//$sql.= natural_search("p.socialnetworks->'$.".$key."'", $search_{$key});
 			$sql .= ' AND p.socialnetworks LIKE \'%"'.$key.'":"'.$search_{$key}.'%\'';
 		}
 	}

+ 1 - 1
htdocs/core/antispamimage.php

@@ -43,7 +43,7 @@ $number = strlen($letters);
 $string = '';
 for ($i = 0; $i < $length; $i++)
 {
-	$string .= $letters{mt_rand(0, $number - 1)};
+	$string .= $letters[mt_rand(0, $number - 1)];
 }
 //print $string;
 

Plik diff jest za duży
+ 134 - 231
htdocs/core/class/lessc.class.php


+ 8 - 8
htdocs/core/lib/security2.lib.php

@@ -448,15 +448,15 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len
 		{
 			$max = strlen($lowercase) - 1;
 			for ($x = 0; $x < $nbofchar; $x++) {
-				$randomCode .= $lowercase{random_int(0, $max)};
+				$randomCode .= $lowercase[random_int(0, $max)];
 			}
 			$max = strlen($uppercase) - 1;
 			for ($x = 0; $x < $nbofchar; $x++) {
-				$randomCode .= $uppercase{random_int(0, $max)};
+				$randomCode .= $uppercase[random_int(0, $max)];
 			}
 			$max = strlen($numbers) - 1;
 			for ($x = 0; $x < $nbofcharlast; $x++) {
-				$randomCode .= $numbers{random_int(0, $max)};
+				$randomCode .= $numbers[random_int(0, $max)];
 			}
 
 			$generated_password = str_shuffle($randomCode);
@@ -464,15 +464,15 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len
 		{
 			$max = strlen($lowercase) - 1;
 			for ($x = 0; $x < $nbofchar; $x++) {
-				$randomCode .= $lowercase{mt_rand(0, $max)};
+				$randomCode .= $lowercase[mt_rand(0, $max)];
 			}
 			$max = strlen($uppercase) - 1;
 			for ($x = 0; $x < $nbofchar; $x++) {
-				$randomCode .= $uppercase{mt_rand(0, $max)};
+				$randomCode .= $uppercase[mt_rand(0, $max)];
 			}
 			$max = strlen($numbers) - 1;
 			for ($x = 0; $x < $nbofcharlast; $x++) {
-				$randomCode .= $numbers{mt_rand(0, $max)};
+				$randomCode .= $numbers[mt_rand(0, $max)];
 			}
 
 			$generated_password = str_shuffle($randomCode);
@@ -495,9 +495,9 @@ function getRandomPassword($generic = false, $replaceambiguouschars = null, $len
 		$max = strlen($numbers) - 1;
 		if (function_exists('random_int'))	// Cryptographic random
 		{
-			$generated_password = str_replace($replaceambiguouschars, $numbers{random_int(0, $max)}, $generated_password);
+			$generated_password = str_replace($replaceambiguouschars, $numbers[random_int(0, $max)], $generated_password);
 		} else {
-			$generated_password = str_replace($replaceambiguouschars, $numbers{mt_rand(0, $max)}, $generated_password);
+			$generated_password = str_replace($replaceambiguouschars, $numbers[mt_rand(0, $max)], $generated_password);
 		}
 	}
 

+ 32 - 22
htdocs/core/lib/website2.lib.php

@@ -228,11 +228,11 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage)
 
 
 /**
- * Save content of the index.php and wrapper.php page
+ * Save content of the index.php and/or wrapper.php page
  *
  * @param	string		$pathofwebsite			Path of website root
  * @param	string		$fileindex				Full path of file index.php
- * @param	string		$filetpl				File tpl to index.php page redirect to
+ * @param	string		$filetpl				File tpl the index.php page redirect to
  * @param	string		$filewrapper			Full path of file wrapper.php
  * @return	boolean								True if OK
  */
@@ -245,29 +245,39 @@ function dolSaveIndexPage($pathofwebsite, $fileindex, $filetpl, $filewrapper)
 
 	dol_mkdir($pathofwebsite);
 
-	dol_delete_file($fileindex);
-	$indexcontent = '<?php'."\n";
-	$indexcontent .= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
-	$indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
-	$indexcontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
-	$indexcontent .= 'if (! empty($_GET[\'pageref\']) || ! empty($_GET[\'pagealiasalt\']) || ! empty($_GET[\'pageid\'])) {'."\n";
-	$indexcontent .= "	require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
-	$indexcontent .= "	require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
-	$indexcontent .= '	redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);'."\n";
-	$indexcontent .= "}\n";
-	$indexcontent .= "include_once './".basename($filetpl)."'\n";
-	$indexcontent .= '// END PHP ?>'."\n";
-	$result1 = file_put_contents($fileindex, $indexcontent);
-	if (!empty($conf->global->MAIN_UMASK)) {
-		@chmod($fileindex, octdec($conf->global->MAIN_UMASK));
+	if ($fileindex) {
+		dol_delete_file($fileindex);
+		$indexcontent = '<?php'."\n";
+		$indexcontent .= "// BEGIN PHP File generated to provide an index.php as Home Page or alias redirector - DO NOT MODIFY - It is just a generated wrapper.\n";
+		$indexcontent .= '$websitekey=basename(__DIR__); if (empty($websitepagefile)) $websitepagefile=__FILE__;'."\n";
+		$indexcontent .= "if (! defined('USEDOLIBARRSERVER') && ! defined('USEDOLIBARREDITOR')) { require_once './master.inc.php'; } // Load master if not already loaded\n";
+		$indexcontent .= 'if (! empty($_GET[\'pageref\']) || ! empty($_GET[\'pagealiasalt\']) || ! empty($_GET[\'pageid\'])) {'."\n";
+		$indexcontent .= "	require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n";
+		$indexcontent .= "	require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n";
+		$indexcontent .= '	redirectToContainer($_GET[\'pageref\'], $_GET[\'pagealiasalt\'], $_GET[\'pageid\']);'."\n";
+		$indexcontent .= "}\n";
+		$indexcontent .= "include_once './".basename($filetpl)."'\n";
+		$indexcontent .= '// END PHP ?>'."\n";
+
+		$result1 = file_put_contents($fileindex, $indexcontent);
+		if (!empty($conf->global->MAIN_UMASK)) {
+			@chmod($fileindex, octdec($conf->global->MAIN_UMASK));
+		}
+	}
+	else {
+		$result1 = true;
 	}
-	dol_delete_file($filewrapper);
 
-	$wrappercontent = file_get_contents(DOL_DOCUMENT_ROOT.'/website/samples/wrapper.php');
+	if ($filewrapper) {
+		dol_delete_file($filewrapper);
+		$wrappercontent = file_get_contents(DOL_DOCUMENT_ROOT.'/website/samples/wrapper.php');
 
-	$result2 = file_put_contents($filewrapper, $wrappercontent);
-	if (!empty($conf->global->MAIN_UMASK)) {
-		@chmod($filewrapper, octdec($conf->global->MAIN_UMASK));
+		$result2 = file_put_contents($filewrapper, $wrappercontent);
+		if (!empty($conf->global->MAIN_UMASK)) {
+			@chmod($filewrapper, octdec($conf->global->MAIN_UMASK));
+		}
+	} else {
+		$result2 = true;
 	}
 
 	return ($result1 && $result2);

+ 5 - 2
htdocs/core/lib/xcal.lib.php

@@ -330,9 +330,10 @@ function build_calfile($format, $title, $desc, $events_array, $outputfile)
  *  @param      string	$outputfile         Output file
  *  @param      string	$filter             (optional) Filter
  *  @param		string	$url				Url (If empty, forge URL for agenda RSS export)
+ *  @param		string	$langcode			Language code to show in header
  *  @return     int                         < 0 if ko, Nb of events in file if ok
  */
-function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = '', $url = '')
+function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter = '', $url = '', $langcode = '')
 {
 	global $user, $conf, $langs;
 	global $dolibarr_main_url_root;
@@ -358,7 +359,9 @@ function build_rssfile($format, $title, $desc, $events_array, $outputfile, $filt
 		fwrite($fichier, '<rss version="2.0">');
 		fwrite($fichier, "\n");
 
-		fwrite($fichier, "<channel>\n<title>".$title."</title>\n");
+		fwrite($fichier, "<channel>\n");
+		fwrite($fichier, "<title>".$title."</title>\n");
+		if ($langcode) fwrite($fichier, "<language>".$langcode."</language>\n");
 
 		/*
         fwrite($fichier, "<description><![CDATA[".$desc.".]]></description>"."\n".

+ 2 - 2
htdocs/datapolicy/class/datapolicycron.class.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2018       Nicolas ZABOURI     <info@inovea-conseil.com>
- * Copyright (C) 2018       Frédéric France     <frederic.france@netlogic.fr>
+ * Copyright (C) 2018-2020  Frédéric France     <frederic.france@netlogic.fr>
  *
  * 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
@@ -482,7 +482,7 @@ class DataPolicyCron
 
                     while ($i < $num && !$error)
                     {
-                        $obj = $db->fetch_object($resql);
+                        $obj = $this->db->fetch_object($resql);
 
                         $object->fetch($obj->rowid);
                         $object->id = $obj->rowid;

+ 212 - 13
htdocs/fourn/commande/dispatch.php

@@ -8,7 +8,7 @@
  * Copyright (C) 2016      Florian Henry        <florian.henry@atm-consulting.fr>
  * Copyright (C) 2017      Ferran Marcet        <fmarcet@2byte.es>
  * Copyright (C) 2018      Frédéric France      <frederic.france@netlogic.fr>
- * Copyright (C) 2019      Christophe Battarel	<christophe@altairis.fr>
+ * Copyright (C) 2019-2020 Christophe Battarel	<christophe@altairis.fr>
  *
  * 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
@@ -38,6 +38,8 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php';
 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.dispatch.class.php';
 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
+require_once DOL_DOCUMENT_ROOT . '/product/stock/class/mouvementstock.class.php';
+
 if (!empty($conf->projet->enabled))
 	require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
 
@@ -53,6 +55,8 @@ $ref = GETPOST('ref');
 $lineid = GETPOST('lineid', 'int');
 $action = GETPOST('action', 'aZ09');
 $fk_default_warehouse = GETPOST('fk_default_warehouse', 'int');
+$cancel = GETPOST('cancel', 'alpha');
+$confirm = GETPOST('confirm', 'alpha');
 
 if ($user->socid)
 	$socid = $user->socid;
@@ -360,6 +364,126 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
 	}
 }
 
+// Remove a dispatched line
+if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->fournisseur->commande->receptionner)
+{
+	$db->begin();
+
+	$supplierorderdispatch = new CommandeFournisseurDispatch($db);
+	$result = $supplierorderdispatch->fetch($lineid);
+	if ($result > 0)
+	{
+		$qty = $supplierorderdispatch->qty;
+		$entrepot = $supplierorderdispatch->fk_entrepot;
+		$product = $supplierorderdispatch->fk_product;
+		$price = GETPOST('price');
+		$comment = $supplierorderdispatch->comment;
+		$eatby = $supplierorderdispatch->fk_product;
+		$sellby = $supplierorderdispatch->sellby;
+		$batch = $supplierorderdispatch->batch;
+
+		$result = $supplierorderdispatch->delete($user);
+	}
+	if ($result < 0)
+	{
+		$errors = $object->errors;
+		$error++;
+	}
+	else
+	{
+		// If module stock is enabled and the stock increase is done on purchase order dispatching
+		if ($entrepot > 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
+		{
+			$mouv = new MouvementStock($db);
+			if ($product > 0)
+			{
+				$mouv->origin = &$object;
+				$result=$mouv->livraison($user, $product, $entrepot, $qty, $price, $comment, '', $eatby, $sellby, $batch);
+				if ($result < 0)
+				{
+					$errors=$mouv->errors;
+					$error++;
+				}
+			}
+		}
+	}
+	if ($error > 0)
+	{
+		$db->rollback();
+		setEventMessages($error, $errors, 'errors');
+	}
+	else
+	{
+		$db->commit();
+	}
+}
+
+// Update a dispatched line
+if ($action == 'updateline' && $user->rights->fournisseur->commande->receptionner)
+{
+	$db->begin();
+	$error = 0;
+
+	$supplierorderdispatch = new CommandeFournisseurDispatch($db);
+	$result = $supplierorderdispatch->fetch($lineid);
+	if ($result > 0)
+	{
+		$qty = $supplierorderdispatch->qty;
+		$entrepot = $supplierorderdispatch->fk_entrepot;
+		$product = $supplierorderdispatch->fk_product;
+		$price = GETPOST('price');
+		$comment = $supplierorderdispatch->comment;
+		$eatby = $supplierorderdispatch->fk_product;
+		$sellby = $supplierorderdispatch->sellby;
+		$batch = $supplierorderdispatch->batch;
+
+		$supplierorderdispatch->qty = GETPOST('qty', 'int');
+		$supplierorderdispatch->fk_entrepot = GETPOST('fk_entrepot');
+		$result = $supplierorderdispatch->update($user);
+	}
+	if ($result < 0)
+	{
+		$error++;
+		$errors=$supplierorderdispatch->errors;
+	}
+	else
+	{
+		// If module stock is enabled and the stock increase is done on purchase order dispatching
+		if ($entrepot > 0 && ! empty($conf->stock->enabled) && ! empty($conf->global->STOCK_CALCULATE_ON_SUPPLIER_DISPATCH_ORDER))
+		{
+			$mouv = new MouvementStock($db);
+			if ($product > 0)
+			{
+				$mouv->origin = &$object;
+				$result=$mouv->livraison($user, $product, $entrepot, $qty, $price, $comment, '', $eatby, $sellby, $batch);
+				if ($result < 0)
+				{
+					$errors=$mouv->errors;
+					$error++;
+				}
+				else
+				{
+					$mouv->origin = &$object;
+					$result=$mouv->reception($user, $product, $supplierorderdispatch->fk_entrepot, $supplierorderdispatch->qty, $price, $comment, $eatby, $sellby, $batch);
+					if ($result < 0)
+					{
+						$errors=$mouv->errors;
+						$error++;
+					}
+				}
+			}
+		}
+	}
+	if ($error > 0)
+	{
+		$db->rollback();
+		setEventMessages($error, $errors, 'errors');
+	}
+	else
+	{
+		$db->commit();
+	}
+}
 
 /*
  * View
@@ -373,7 +497,7 @@ $warehouse_static = new Entrepot($db);
 $supplierorderdispatch = new CommandeFournisseurDispatch($db);
 
 $help_url = 'EN:Module_Suppliers_Orders|FR:CommandeFournisseur|ES:Módulo_Pedidos_a_proveedores';
-llxHeader('', $langs->trans("Order"), $help_url, '', 0, 0, array('/fourn/js/lib_dispatch.js.php'));
+llxHeader('', $langs->trans("OrderDispatch"), $help_url, '', 0, 0, array('/fourn/js/lib_dispatch.js.php'));
 
 if ($id > 0 || !empty($ref)) {
 	$soc = new Societe($db);
@@ -387,6 +511,23 @@ if ($id > 0 || !empty($ref)) {
 	$title = $langs->trans("SupplierOrder");
 	dol_fiche_head($head, 'dispatch', $title, -1, 'order');
 
+	$formconfirm='';
+
+	// Confirmation to delete line
+	if ($action == 'ask_deleteline')
+	{
+		$formconfirm=$form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
+	}
+
+	// Call Hook formConfirm
+	$parameters = array('lineid' => $lineid);
+	// Note that $action and $object may be modified by hook
+	$reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action);
+	if (empty($reshook)) $formconfirm.=$hookmanager->resPrint;
+	elseif ($reshook > 0) $formconfirm=$hookmanager->resPrint;
+
+	// Print form confirm
+	print $formconfirm;
 
 	// Supplier order card
 
@@ -487,6 +628,9 @@ if ($id > 0 || !empty($ref)) {
 		require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
 		$formproduct = new FormProduct($db);
 		$formproduct->loadWarehouses();
+		$entrepot = new Entrepot($db);
+		$listwarehouses=$entrepot->list_array(1);
+
 
 		if (empty($conf->reception->enabled))print '<form method="POST" action="dispatch.php?id='.$object->id.'">';
         else print '<form method="post" action="'.dol_buildpath('/reception/card.php', 1).'?originid='.$object->id.'&origin=supplierorder">';
@@ -561,8 +705,6 @@ if ($id > 0 || !empty($ref)) {
 			$i = 0;
 
 			if ($num) {
-				$entrepot = new Entrepot($db);
-				$listwarehouses = $entrepot->list_array(1);
 
 				print '<tr class="liste_titre">';
 
@@ -915,9 +1057,11 @@ if ($id > 0 || !empty($ref)) {
 	$sql = "SELECT p.ref, p.label,";
 	$sql .= " e.rowid as warehouse_id, e.ref as entrepot,";
 	$sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status, cfd.datec";
+	$sql.=" ,cd.rowid, cd.subprice";
 	if ($conf->reception->enabled)$sql .= " ,cfd.fk_reception, r.date_delivery";
 	$sql .= " FROM ".MAIN_DB_PREFIX."product as p,";
 	$sql .= " ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd";
+	$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "commande_fournisseurdet as cd ON cd.rowid = cfd.fk_commandefourndet";
 	$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."entrepot as e ON cfd.fk_entrepot = e.rowid";
 	if ($conf->reception->enabled)$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."reception as r ON cfd.fk_reception = r.rowid";
 	$sql .= " WHERE cfd.fk_commande = ".$object->id;
@@ -949,7 +1093,6 @@ if ($id > 0 || !empty($ref)) {
 				print '<td class="dispatch_dlc_title">'.$langs->trans("SellByDate").'</td>';
 			}
 			print '<td class="right">'.$langs->trans("QtyDispatched").'</td>';
-			print '<td></td>';
 			print '<td>'.$langs->trans("Warehouse").'</td>';
 			print '<td>'.$langs->trans("Comment").'</td>';
 
@@ -960,14 +1103,23 @@ if ($id > 0 || !empty($ref)) {
 				print '<td class="center"></td>';
 			}
 
-			print '<td class="center"></td>';
+			print '<td class="center" colspan="2"></td>';
 
 			print "</tr>\n";
 
 			while ($i < $num) {
 				$objp = $db->fetch_object($resql);
 
-				print "<tr ".$bc[$var].">";
+				if ($action == 'editline' && $lineid == $objp->dispatchlineid)
+				{
+					print '<form name="editdispatchedlines" id="editdispatchedlines" action="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '#line_' . GETPOST('lineid') . '" method="POST">
+					<input type="hidden" name="token" value="' . $_SESSION ['newtoken'] . '">
+					<input type="hidden" name="action" value="updateline">
+					<input type="hidden" name="mode" value="">
+					<input type="hidden" name="lineid" value="' . $objp->dispatchlineid . '">';
+				}
+
+				print '<tr ' . $bc[$var] . ' id="line_'.$objp->dispatchlineid.'" >';
 
 				if (!empty($conf->reception->enabled)) {
 					print '<td>';
@@ -994,14 +1146,37 @@ if ($id > 0 || !empty($ref)) {
 				}
 
 				// Qty
-				print '<td class="right">'.$objp->qty.'</td>';
-				print '<td>&nbsp;</td>';
+				print '<td class="right">';
+				if ($action == 'editline' && $lineid == $objp->dispatchlineid)
+				{
+					print '<input style="width: 50px;" type="number" min="1" name="qty" value="' . $objp->qty . '" />';
+				}
+				else
+				{
+					print $objp->qty;
+				}
+				print '<input type="hidden" name="price" value="'.$objp->subprice.'" />';
+				print '</td>';
 
 				// Warehouse
 				print '<td>';
-				$warehouse_static->id = $objp->warehouse_id;
-				$warehouse_static->libelle = $objp->entrepot;
-				print $warehouse_static->getNomUrl(1);
+				if ($action == 'editline' && $lineid == $objp->dispatchlineid)
+				{
+					if (count($listwarehouses) > 1) {
+						print $formproduct->selectWarehouses(GETPOST("fk_entrepot")?GETPOST("fk_entrepot"):($objp->warehouse_id?$objp->warehouse_id:''), "fk_entrepot", '', 1, 0, $objp->fk_product, '', 1, 1, null, 'csswarehouse');
+					} elseif (count($listwarehouses) == 1) {
+						print $formproduct->selectWarehouses(GETPOST("fk_entrepot")?GETPOST("fk_entrepot"):($objp->warehouse_id?$objp->warehouse_id:''), "fk_entrepot", '', 0, 0, $objp->fk_product, '', 1, 1, null, 'csswarehouse');
+					} else {
+						$langs->load("errors");
+						print $langs->trans("ErrorNoWarehouseDefined");
+					}
+				}
+				else
+				{
+					$warehouse_static->id = $objp->warehouse_id;
+					$warehouse_static->libelle = $objp->entrepot;
+					print $warehouse_static->getNomUrl(1);
+				}
 				print '</td>';
 
 				// Comment
@@ -1052,9 +1227,33 @@ if ($id > 0 || !empty($ref)) {
 					print '</td>';
 				}
 
-				print '<td class="center"></td>';
+				if ($action != 'editline' ||  && $lineid != $objp->dispatchlineid)
+				{
+					print '<td class="linecoledit center">';
+					print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=editline&amp;lineid=' . $objp->dispatchlineid .'#line_'. $objp->dispatchlineid . '">';
+					print img_edit();
+					print '</a>';
+					print '</td>';
+
+					print '<td class="linecoldelete center">';
+					print '<a href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&amp;action=ask_deleteline&amp;lineid=' . $objp->dispatchlineid . '#dispatch_received_products">';
+					print img_delete();
+					print '</a>';
+					print '</td>';
+				}
+				else
+				{
+					print '<td class="center valignmiddle">';
+					print '<input type="submit" class="button" id="savelinebutton" name="save" value="'.$langs->trans("Save").'" />';
+					print '</td>';
+					print '<td class="center valignmiddle">';
+					print '<input type="submit" class="button" id="cancellinebutton" name="cancel" value="'. $langs->trans("Cancel").'" />';
+					print '</td>';
+				}
+
 
 				print "</tr>\n";
+				if ($action == 'editline' && $lineid == $objp->dispatchlineid)  print '</form>';
 
 				$i++;
 			}

+ 15 - 3
htdocs/fourn/facture/card.php

@@ -621,7 +621,7 @@ if (empty($reshook))
 		$ret = $extrafields->setOptionalsFromPost(null, $object);
 		if ($ret < 0) $error++;
 
-		$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		$datefacture = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 		$datedue = dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear']);
 
 		// Replacement invoice
@@ -1695,7 +1695,7 @@ if ($action == 'create')
 			if (!empty($conf->global->MULTICURRENCY_USE_ORIGIN_TX) && !empty($objectsrc->multicurrency_tx))	$currency_tx = $objectsrc->multicurrency_tx;
 		}
 
-		$datetmp = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		$datetmp = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 		$dateinvoice = ($datetmp == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE) ?-1 : '') : $datetmp);
 		$datetmp = dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear']);
 		$datedue = ($datetmp == '' ?-1 : $datetmp);
@@ -1707,7 +1707,7 @@ if ($action == 'create')
 		$cond_reglement_id 	= $societe->cond_reglement_supplier_id;
 		$mode_reglement_id 	= $societe->mode_reglement_supplier_id;
 		$fk_account         = $societe->fk_account;
-		$datetmp = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
+		$datetmp = dol_mktime(12, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
 		$dateinvoice = ($datetmp == '' ? (empty($conf->global->MAIN_AUTOFILL_DATE) ?-1 : '') : $datetmp);
 		$datetmp = dol_mktime(12, 0, 0, $_POST['echmonth'], $_POST['echday'], $_POST['echyear']);
 		$datedue = ($datetmp == '' ?-1 : $datetmp);
@@ -1715,6 +1715,18 @@ if ($action == 'create')
 		if (!empty($conf->multicurrency->enabled) && !empty($soc->multicurrency_code)) $currency_code = $soc->multicurrency_code;
 	}
 
+	// when payment condition is empty (means not override by payment condition form a other object, like third-party), try to use default value
+	if(empty($cond_reglement_id))
+	{
+		$cond_reglement_id = GETPOST("cond_reglement_id");
+	}
+
+	// when payment mode is empty (means not override by payment condition form a other object, like third-party), try to use default value
+	if(empty($mode_reglement_id))
+	{
+		$mode_reglement_id = GETPOST("mode_reglement_id");
+	}
+
 	print '<form name="add" action="'.$_SERVER["PHP_SELF"].'" method="post">';
 	print '<input type="hidden" name="token" value="'.newToken().'">';
 	print '<input type="hidden" name="action" value="add">';

+ 3 - 0
htdocs/langs/en_US/agenda.lang

@@ -154,3 +154,6 @@ EveryMonth=Every month
 DayOfMonth=Day of month
 DayOfWeek=Day of week
 DateStartPlusOne=Date start + 1 hour
+SetAllEventsToTodo=Set all events to todo
+SetAllEventsToInProgress=Set all events to in progress
+SetAllEventsToFinished=Set all events to finished

+ 1 - 0
htdocs/langs/en_US/mrp.lang

@@ -74,3 +74,4 @@ ProductsToConsume=Products to consume
 ProductsToProduce=Products to produce
 UnitCost=Unit cost
 TotalCost=Total cost
+BOMTotalCost=The cost to produce this BOM based on cost of each quantity and product to consume (use Cost price if defined, else Average Weighted Price if defined, else the Best purchase price) 

+ 3 - 1
htdocs/langs/en_US/website.lang

@@ -127,4 +127,6 @@ OtherLanguages=Other languages
 UseManifest=Provide a manifest.json file
 PublicAuthorAlias=Public author alias
 AvailableLanguagesAreDefinedIntoWebsiteProperties=Available languages are defined into website properties
-ReplacementDoneInXPages=Replacement done in %s pages or containers
+ReplacementDoneInXPages=Replacement done in %s pages or containers
+RSSFeed=RSS Feed
+RSSFeedDesc=You can get a RSS feed of latest articles with type 'blogpost' using this URL  

+ 6 - 1
htdocs/loan/class/paymentloan.class.php

@@ -1,6 +1,6 @@
 <?php
 /* Copyright (C) 2014-2018  Alexandre Spangaro   <aspangaro@open-dsi.fr>
- * Copyright (C) 2015-2018  Frederic France      <frederic.france@netlogic.fr>
+ * Copyright (C) 2015-2020  Frederic France      <frederic.france@netlogic.fr>
  *
  * 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
@@ -40,6 +40,11 @@ class PaymentLoan extends CommonObject
 	 */
 	public $table_element = 'payment_loan';
 
+    /**
+     * @var string String with name of icon for PaymentLoan
+     */
+    public $picto = 'money-bill-alt';
+
     /**
      * @var int Loan ID
      */

+ 14 - 5
htdocs/variants/class/ProductCombination.class.php

@@ -326,11 +326,20 @@ class ProductCombination
 
 		$child = new Product($this->db);
 		$child->fetch($this->fk_product_child);
-		$child->price_autogen = $parent->price_autogen;
-		$child->weight = $parent->weight + $this->variation_weight;
-		$child->weight_units = $parent->weight_units;
-		$varlabel = $this->getCombinationLabel($this->fk_product_child);
-		$child->label = $parent->label.$varlabel;
+		
+    $child->price_autogen = $parent->price_autogen;
+		$child->weight = $parent->weight;
+		if ($this->variation_weight) {	// If we must add a delta on weight
+			$child->weight = ($child->weight ? $child->weight : 0) + $this->variation_weight;
+		}
+    $child->weight_units    = $parent->weight_units;
+
+    // Don't update the child label if the user has already modified it.
+    if ($child->label == $parent->label) {
+            // This will trigger only at variant creation time
+            $varlabel               = $this->getCombinationLabel($this->fk_product_child);
+            $child->label           = $parent->label.$varlabel;;
+    }
 
 		if ($child->update($child->id, $user) > 0) {
 			$new_vat = $parent->tva_tx;

+ 15 - 5
htdocs/website/index.php

@@ -196,6 +196,7 @@ $fileindex = $pathofwebsite.'/index.php';
 $filewrapper = $pathofwebsite.'/wrapper.php';
 $filemanifestjson = $pathofwebsite.'/manifest.json.php';
 $filereadme = $pathofwebsite.'/README.md';
+$filemaster = $pathofwebsite.'/master.inc.php';
 
 // Define $urlwithroot
 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
@@ -1177,8 +1178,6 @@ if ($action == 'updatecss')
 		if (!$error)
 		{
     		// Save master.inc.php file
-    		$filemaster = $pathofwebsite.'/master.inc.php';
-
     		dol_syslog("Save master file ".$filemaster);
 
     		dol_mkdir($pathofwebsite);
@@ -1372,6 +1371,10 @@ if ($action == 'updatecss')
        		}
 
 
+       		// Save wrapper.php
+			$result = dolSaveIndexPage($pathofwebsite, '', '', $filewrapper);
+
+
     		// Message if no error
     		if (!$error)
     		{
@@ -1704,10 +1707,9 @@ if (($action == 'updatesource' || $action == 'updatecontent' || $action == 'conf
 				$action = 'createpagefromclone';
 
 				$db->rollback();
-			}
-			else {
-				$fileindex = $pathofwebsitenew.'/index.php';
+			} else {
 				$filetpl = $pathofwebsitenew.'/page'.$resultpage->id.'.tpl.php';
+				$fileindex = $pathofwebsitenew.'/index.php';
 				$filewrapper = $pathofwebsitenew.'/wrapper.php';
 
 				//var_dump($pathofwebsitenew);
@@ -2922,6 +2924,14 @@ if ($action == 'editcss')
 
 	print '</td></tr>';
 
+	// RSS
+	print '<tr><td class="tdtop">';
+	$htmlhelp = $langs->trans('RSSFeedDesc');
+	print $form->textwithpicto($langs->trans('RSSFeed'), $htmlhelp, 1, 'help', '', 0, 2, '');
+	print '</td><td>';
+	print '/wrapper.php?rss=1[&l=XX][&limit=123]';
+	print '</td></tr>';
+
 	print '</table>';
 
 	dol_fiche_end();

+ 8 - 3
htdocs/website/samples/wrapper.php

@@ -12,6 +12,8 @@ $hashp = GETPOST('hashp', 'aZ09');
 $modulepart = GETPOST('modulepart', 'aZ09');
 $entity = GETPOST('entity', 'int') ?GETPOST('entity', 'int') : $conf->entity;
 $original_file = GETPOST("file", "alpha");
+$l = GETPOST('l', 'aZ09');
+$limit = GETPOST('limit', 'int');
 
 // Parameters for RSS
 $rss = GETPOST('rss', 'aZ09');
@@ -87,8 +89,8 @@ if ($rss) {
 	$type = '';
 	$cachedelay = 0;
 	$filename = $original_file;
-	$filters = array('type_container'=>'blogpost', 'lang'=>'en_US');
 	$dir_temp = $conf->website->dir_temp;
+
 	include_once DOL_DOCUMENT_ROOT.'/website/class/website.class.php';
 	include_once DOL_DOCUMENT_ROOT.'/website/class/websitepage.class.php';
 	$website = new Website($db);
@@ -96,7 +98,10 @@ if ($rss) {
 
 	$website->fetch('', $websitekey);
 
-	$MAXNEWS = 20;
+	$filters = array('type_container'=>'blogpost');
+	if ($l) $filters['lang'] = $l;
+
+	$MAXNEWS = ($limit ? $limit : 20);
 	$arrayofblogs = $websitepage->fetchAll($website->id, 'DESC', 'date_creation', $MAXNEWS, 0, $filters);
 	$eventarray = array();
 	if (is_array($arrayofblogs)) {
@@ -148,7 +153,7 @@ if ($rss) {
 		@chmod($outputfiletmp, octdec($conf->global->MAIN_UMASK));
 
 		// Write file
-		$result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp, '', $website->virtualhost.'/wrapper.php?rss=1');
+		$result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp, '', $website->virtualhost.'/wrapper.php?rss=1'.($l ? '&l='.$l : ''), $l);
 
 		if ($result >= 0)
 		{

+ 1 - 1
test/phpunit/AccountingAccountTest.php

@@ -204,7 +204,7 @@ class AccountingAccountTest extends PHPUnit\Framework\TestCase
         $localobject->label='New label';
         $result=$localobject->update($user);
 
-        print __METHOD__." id=".$id." result=".$result."\n";
+        print __METHOD__." id=".$localobject->id." result=".$result."\n";
         $this->assertLessThan($result, 0);
 
         return $localobject->id;

+ 1 - 1
test/phpunit/ActionCommTest.php

@@ -223,7 +223,7 @@ class ActionCommTest extends PHPUnit\Framework\TestCase
     	$result=$localobject->update($user);
 
     	$this->assertLessThan($result, 0);
-    	print __METHOD__." id=".$id." result=".$result."\n";
+    	print __METHOD__." id=".$localobject->id." result=".$result."\n";
     	return $localobject->id;
     }
 

+ 1 - 1
test/phpunit/CommandeTest.php

@@ -196,7 +196,7 @@ class CommandeTest extends PHPUnit\Framework\TestCase
     	$result=$localobject->update($user);
 
     	$this->assertLessThan($result, 0);
-    	print __METHOD__." id=".$id." result=".$result."\n";
+    	print __METHOD__." id=".$localobject->id." result=".$result."\n";
     	return $localobject;
     }
 

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików