Merge remote-tracking branch 'origin/3.7' into develop

Conflicts:
	build/debian/changelog
	htdocs/filefunc.inc.php
	htdocs/install/mysql/migration/3.6.0-3.7.0.sql
This commit is contained in:
Laurent Destailleur 2015-06-05 18:31:53 +02:00
commit 43ed48896a
14 changed files with 277 additions and 62 deletions

View File

@ -43,14 +43,31 @@ Dolibarr better:
- All fields "fk_societe" were renamed into "fk_soc".
***** ChangeLog for 3.7.1 compared to 3.7.* *****
- Fix: Bug in the new photo system
- Fix: Error management
- Fix: [ Bug #2714 ] Members -> Memberxy-> Agenda -> technical Error
- Fix: [ Bug #2713 ] 3.7.0 mailing-unsubscribe.php not unsubscribe
FIX Bug in the new photo system
FIX Error management
FIX [ Bug #2714 ] Members -> Memberxy-> Agenda -> technical Error
FIX [ Bug #2713 ] 3.7.0 mailing-unsubscribe.php not unsubscribe
FIX #2901
FIX when we create an agenda event with "Not applicable" status, it is automatically saved with "To do" status
FIX check the user status during authentication
FIX top links menu have target attribute with wrong value
FIX extrafields required on thirdparty
FIX create contact with extrafield is null when it is require
FIX width multiselect
FIX "script" tag with wrong syntax
Fix bug debian 786479
FIX update usergroup name
Fix facturestats was not filtering on invoice type
FIX #2856 : Wrong table design
FIX button create payment hide if tax amount is less than 1
FIX event for restricted user was restricted if company null
FIX send mail, copy sendto don't read the list of contact
FIX Properly escape untrusted data to prevent HTML injection.
FIX send mail, copy sendto don't read the list of contact
- Path to save photos of products was moved in 3.7.0 to match path of other attached files. If you had loose
your photo on the photo tab of products, you can set the constant "PRODUCT_USE_OLD_PATH_FOR_PHOTO" to
restore old path.
Path to save photos of products was moved in 3.7.0 to match path of other attached files. If you had loose
your photo on the photo tab of products, you can set the constant "PRODUCT_USE_OLD_PATH_FOR_PHOTO" to
restore old path.
WARNING:
@ -236,8 +253,8 @@ Dolibarr better:
- Table llx_c_pays were renamed into llx_c_country.
- Triggers *_BUILDDOC are removed. Building a doc is not a business event. For action after
creation of a pdf or odt, hook "afterPDFCreation" or "afterODTCreation" must be used instead.
- A lot of pages called fiche.php were renamed into card.php
- A lot of pages called liste.php were renamed into list.php
- A lot of pages named fiche.php were renamed into card.php
- A lot of pages named liste.php were renamed into list.php
- If you used warehouse/stock module, recheck setup of stock increase/decrease rules of the
warehouse module and your Point Of Sale module setup if you use one.
- Replaced USER_UPDATE_SESSION trigger with an updateSession hook may break modules using it.

View File

@ -982,10 +982,10 @@ if ($nboftargetok) {
mkdir($DESTI.'/package_windows');
if (-d $DESTI.'/package_windows') { $NEWDESTI=$DESTI.'/package_windows'; }
print "Remove target $FILENAMEEXEDOLIWAMP.exe...\n";
print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe";
print "Check that in your Wine setup, you create a Z: drive that point to your /tmp directory.\n";
print "Check that in your Wine setup, you create a Z: drive that point to your / directory.\n";
$SOURCEBACK=$SOURCE;
$SOURCEBACK =~ s/\//\\/g;

View File

@ -421,7 +421,7 @@ class Mailing extends CommonObject
$resql=$this->db->query($sql);
if ($resql)
{
return 1;
return $this->delete_targets();
}
else
{
@ -429,6 +429,29 @@ class Mailing extends CommonObject
return -1;
}
}
/**
* Delete targets emailing
*
* @return int 1 if OK, 0 if error
*/
function delete_targets()
{
$sql = "DELETE FROM ".MAIN_DB_PREFIX."mailing_cibles";
$sql.= " WHERE fk_mailing = ".$this->id;
dol_syslog("Mailing::delete_targets", LOG_DEBUG);
$resql=$this->db->query($sql);
if ($resql)
{
return 1;
}
else
{
$this->error=$this->db->lasterror();
return 0;
}
}
/**

View File

@ -1061,8 +1061,10 @@ class Propal extends CommonObject
*/
function createFromClone($socid=0)
{
global $user,$langs,$conf,$hookmanager;
global $db, $user,$langs,$conf,$hookmanager;
dol_include_once('/projet/class.project.class.php');
$this->context['createfromclone']='createfromclone';
$error=0;
@ -1087,7 +1089,16 @@ class Propal extends CommonObject
$this->socid = $objsoc->id;
$this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
$this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
$this->fk_project = '';
$project = new Project($db);
if($objFrom->fk_project > 0 && $project->fetch($objFrom->fk_project)) {
if($project->socid <= 0) $this->fk_project = $objFrom->fk_project;
else $this->fk_project = '';
} else {
$this->fk_project = '';
}
$this->fk_delivery_address = '';
}

View File

@ -1039,7 +1039,9 @@ class Commande extends CommonOrder
*/
function createFromProposal($object)
{
global $conf,$user,$langs,$hookmanager;
global $db, $conf,$user,$langs,$hookmanager;
dol_include_once('/core/class/extrafields.class.php');
$error=0;
@ -1110,9 +1112,15 @@ class Commande extends CommonOrder
// get extrafields from original line
$object->fetch_optionals($object->id);
foreach($object->array_options as $options_key => $value)
$this->array_options[$options_key] = $value;
$e = new ExtraFields($db);
$element_extrafields = $e->fetch_name_optionals_label($this->element);
foreach($object->array_options as $options_key => $value) {
if(array_key_exists(str_replace('options_', '', $options_key), $element_extrafields)){
$this->array_options[$options_key] = $value;
}
}
// Possibility to add external linked objects with hooks
$this->linked_objects[$this->origin] = $this->origin_id;
if (is_array($object->other_linked_objects) && ! empty($object->other_linked_objects))
@ -1734,6 +1742,7 @@ class Commande extends CommonOrder
$i++;
}
$this->db->free($result);
return 1;

View File

@ -131,13 +131,15 @@ abstract class CommonObject
*/
static function isExistingObject($element, $id, $ref='', $ref_ext='')
{
global $db;
global $db,$conf;
$sql = "SELECT rowid, ref, ref_ext";
$sql.= " FROM ".MAIN_DB_PREFIX.$element;
if ($id > 0) $sql.= " WHERE rowid = ".$db->escape($id);
else if ($ref) $sql.= " WHERE ref = '".$db->escape($ref)."'";
else if ($ref_ext) $sql.= " WHERE ref_ext = '".$db->escape($ref_ext)."'";
$sql.= " WHERE entity IN (".getEntity($element).")" ;
if ($id > 0) $sql.= " AND rowid = ".$db->escape($id);
else if ($ref) $sql.= " AND ref = '".$db->escape($ref)."'";
else if ($ref_ext) $sql.= " AND ref_ext = '".$db->escape($ref_ext)."'";
else {
$error='ErrorWrongParameters';
dol_print_error(get_class()."::isExistingObject ".$error, LOG_ERR);

View File

@ -162,7 +162,7 @@ class modCategorie extends DolibarrModules
$this->export_enabled[$r]='$conf->adherent->enabled';
$this->export_permission[$r]=array(array("categorie","lire"),array("adherent","lire"));
$this->export_fields_array[$r]=array('u.rowid'=>"CategId",'u.label'=>"Label",'u.description'=>"Description",'p.rowid'=>'MemberId','p.lastname'=>'LastName','p.firstname'=>'Firstname');
$this->export_TypeFields_array[$r]=array('u.label'=>"Text",'u.description'=>"Text",'p.rowid'=>'List:adherent:nom','p.lastname'=>'Text','p.firstname'=>'Text');
$this->export_TypeFields_array[$r]=array('u.label'=>"Text",'u.description'=>"Text",'p.lastname'=>'Text','p.firstname'=>'Text');
$this->export_entities_array[$r]=array('p.rowid'=>'member','p.lastname'=>'member','p.firstname'=>'member'); // We define here only fields that use another picto
$this->export_sql_start[$r]='SELECT DISTINCT ';
$this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'categorie as u, '.MAIN_DB_PREFIX.'categorie_member as cp, '.MAIN_DB_PREFIX.'adherent as p';
@ -213,7 +213,6 @@ class modCategorie extends DolibarrModules
$this->export_TypeFields_array[$r] = array (
'u.label' => "Text",
'u.description' => "Text",
'p.rowid' => 'List:contact:lastname',
'p.lastname' => 'Text',
'p.firstname' => 'Text',
's.nom'=>"Text",

View File

@ -797,10 +797,11 @@ class Expedition extends CommonObject
$orderline = new OrderLine($this->db);
$orderline->fetch($id);
$fk_product = $orderline->fk_product;
if (! empty($orderline->fk_product))
if (! empty($conf->stock->enabled) && ! empty($orderline->fk_product))
{
$fk_product = $orderline->fk_product;
if (! ($entrepot_id > 0) && empty($conf->global->STOCK_WAREHOUSE_NOT_REQUIRED_FOR_SHIPMENTS))
{
$this->error=$langs->trans("ErrorWarehouseRequiredIntoShipmentLine");

View File

@ -41,6 +41,7 @@ print_titre($langs->trans('RelatedShippings'));
<td align="right"><?php echo $langs->trans("Status"); ?></td>
</tr>
<?php
$total=0;
$var=true;
foreach($linkedObjectBlock as $object)
{
@ -71,4 +72,4 @@ foreach($linkedObjectBlock as $object)
</tr>
</table>
<!-- END PHP TEMPLATE -->
<!-- END PHP TEMPLATE -->

View File

@ -165,6 +165,7 @@ class ProductFournisseur extends Product
function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0, $delivery_time_days=0)
{
global $conf, $langs;
//global $mysoc;
// Clean parameter
if (empty($qty)) $qty=0;

View File

@ -39,6 +39,7 @@ print_titre($langs->trans('RelatedSupplierOrders'));
<td align="right"><?php echo $langs->trans("Status"); ?></td>
</tr>
<?php
$total=0;
$var=true;
foreach($linkedObjectBlock as $object)
{
@ -68,4 +69,4 @@ foreach($linkedObjectBlock as $object)
</tr>
</table>
<!-- END PHP TEMPLATE -->
<!-- END PHP TEMPLATE -->

View File

@ -40,6 +40,7 @@ print_titre($langs->trans("RelatedSupplierInvoices"));
<td align="right"><?php echo $langs->trans("Status"); ?></td>
</tr>
<?php
$total=0;
$var=true;
foreach($linkedObjectBlock as $object)
{
@ -68,4 +69,4 @@ foreach($linkedObjectBlock as $object)
</tr>
</table>
<!-- END PHP TEMPLATE -->
<!-- END PHP TEMPLATE -->

View File

@ -98,36 +98,36 @@ ALTER TABLE llx_accountingaccount add column fk_user_author integer DEFAULT NULL
ALTER TABLE llx_accountingaccount add column fk_user_modif integer DEFAULT NULL AFTER fk_user_author;
-- Qual
UPDATE llx_const SET name = 'ACCOUNTING_MODE' WHERE name = 'COMPTA_MODE';
UPDATE llx_const SET name = 'ACCOUNTING_ACCOUNT_CUSTOMER' WHERE name = 'COMPTA_ACCOUNT_CUSTOMER';
UPDATE llx_const SET name = 'ACCOUNTING_ACCOUNT_SUPPLIER' WHERE name = 'COMPTA_ACCOUNT_SUPPLIER';
UPDATE llx_const SET name = 'ACCOUNTING_PRODUCT_BUY_ACCOUNT' WHERE name = 'COMPTA_PRODUCT_BUY_ACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_PRODUCT_SOLD_ACCOUNT' WHERE name = 'COMPTA_PRODUCT_SOLD_ACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_SERVICE_BUY_ACCOUNT' WHERE name = 'COMPTA_SERVICE_BUY_ACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_SERVICE_SOLD_ACCOUNT' WHERE name = 'COMPTA_SERVICE_SOLD_ACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_VAT_ACCOUNT' WHERE name = 'COMPTA_VAT_ACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_VAT_BUY_ACCOUNT' WHERE name = 'COMPTA_VAT_BUY_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_MODE')__ WHERE __DECRYPT('name')__ = 'COMPTA_MODE';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_ACCOUNT_CUSTOMER')__ WHERE __DECRYPT('name')__ = 'COMPTA_ACCOUNT_CUSTOMER';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_ACCOUNT_SUPPLIER')__ WHERE __DECRYPT('name')__ = 'COMPTA_ACCOUNT_SUPPLIER';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_PRODUCT_BUY_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'COMPTA_PRODUCT_BUY_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_PRODUCT_SOLD_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'COMPTA_PRODUCT_SOLD_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_SERVICE_BUY_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'COMPTA_SERVICE_BUY_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_SERVICE_SOLD_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'COMPTA_SERVICE_SOLD_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_VAT_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'COMPTA_VAT_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_VAT_BUY_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'COMPTA_VAT_BUY_ACCOUNT';
-- Compatibility with module Accounting Expert
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_MODELCSV' WHERE name = 'ACCOUNTINGEX_MODELCSV';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_SEPARATORCSV' WHERE name = 'ACCOUNTINGEX_SEPARATORCSV';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_DATE' WHERE name = 'ACCOUNTINGEX_EXP_DATE';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_PIECE' WHERE name = 'ACCOUNTINGEX_EXP_PIECE';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_GLOBAL_ACCOUNT' WHERE name = 'ACCOUNTINGEX_EXP_GLOBAL_ACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_LABEL' WHERE name = 'ACCOUNTINGEX_EXP_LABEL';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_AMOUNT' WHERE name = 'ACCOUNTINGEX_EXP_AMOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_EXPORT_DEVISE' WHERE name = 'ACCOUNTINGEX_EXP_DEVISE';
UPDATE llx_const SET name = 'ACCOUNTING_ACCOUNT_SUSPENSE' WHERE name = 'ACCOUNTINGEX_ACCOUNT_SUSPENSE';
UPDATE llx_const SET name = 'ACCOUNTING_SELL_JOURNAL' WHERE name = 'ACCOUNTINGEX_SELL_JOURNAL';
UPDATE llx_const SET name = 'ACCOUNTING_PURCHASE_JOURNAL' WHERE name = 'ACCOUNTINGEX_PURCHASE_JOURNAL';
UPDATE llx_const SET name = 'ACCOUNTING_SOCIAL_JOURNAL' WHERE name = 'ACCOUNTINGEX_SOCIAL_JOURNAL';
UPDATE llx_const SET name = 'ACCOUNTING_MISCELLANEOUS_JOURNAL' WHERE name = 'ACCOUNTINGEX_MISCELLANEOUS_JOURNAL';
UPDATE llx_const SET name = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH' WHERE name = 'ACCOUNTINGEX_ACCOUNT_TRANSFER_CASH';
UPDATE llx_const SET name = 'ACCOUNTING_LENGTH_GACCOUNT' WHERE name = 'ACCOUNTINGEX_LENGTH_GACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_LENGTH_AACCOUNT' WHERE name = 'ACCOUNTINGEX_LENGTH_AACCOUNT';
UPDATE llx_const SET name = 'ACCOUNTING_LIMIT_LIST_VENTILATION' WHERE name = 'ACCOUNTINGEX_LIMIT_LIST_VENTILATION';
UPDATE llx_const SET name = 'ACCOUNTING_LIST_SORT_VENTILATION_TODO' WHERE name = 'ACCOUNTINGEX_LIST_SORT_VENTILATION_TODO';
UPDATE llx_const SET name = 'ACCOUNTING_LIST_SORT_VENTILATION_DONE' WHERE name = 'ACCOUNTINGEX_LIST_SORT_VENTILATION_DONE';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_MODELCSV')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_MODELCSV';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_SEPARATORCSV')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_SEPARATORCSV';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_DATE')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_EXP_DATE';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_PIECE')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_EXP_PIECE';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_GLOBAL_ACCOUNT')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_EXP_GLOBAL_ACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_LABEL')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_EXP_LABEL';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_AMOUNT')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_EXP_AMOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_EXPORT_DEVISE')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_EXP_DEVISE';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_ACCOUNT_SUSPENSE')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_ACCOUNT_SUSPENSE';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_SELL_JOURNAL')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_SELL_JOURNAL';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_PURCHASE_JOURNAL')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_PURCHASE_JOURNAL';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_SOCIAL_JOURNAL')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_SOCIAL_JOURNAL';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_MISCELLANEOUS_JOURNAL')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_MISCELLANEOUS_JOURNAL';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_ACCOUNT_TRANSFER_CASH')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_ACCOUNT_TRANSFER_CASH';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_LENGTH_GACCOUNT')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_LENGTH_GACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_LENGTH_AACCOUNT')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_LENGTH_AACCOUNT';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_LIMIT_LIST_VENTILATION')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_LIMIT_LIST_VENTILATION';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_LIST_SORT_VENTILATION_TODO')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_LIST_SORT_VENTILATION_TODO';
UPDATE llx_const SET name = __ENCRYPT('ACCOUNTING_LIST_SORT_VENTILATION_DONE')__ WHERE __DECRYPT('name')__ = 'ACCOUNTINGEX_LIST_SORT_VENTILATION_DONE';
-- Drop old table
DROP TABLE llx_compta;
@ -1133,9 +1133,9 @@ ALTER TABLE llx_c_email_templates ADD UNIQUE INDEX uk_c_email_templates(entity,
ALTER TABLE llx_c_email_templates ADD INDEX idx_type(type_template);
-- Remove OSC module
DELETE FROM llx_const WHERE name = 'MAIN_MODULE_BOUTIQUE';
DELETE FROM llx_const WHERE name = 'OSC_DB_HOST';
DELETE FROM llx_menu WHERE module = 'boutique';
DELETE FROM llx_const WHERE __DECRYPT('name')__ = 'MAIN_MODULE_BOUTIQUE';
DELETE FROM llx_const WHERE __DECRYPT('name')__ = 'OSC_DB_HOST';
DELETE FROM llx_menu WHERE __DECRYPT('module')__ = 'boutique';
-- Add option always editable on extrafield
ALTER TABLE llx_extrafields ADD alwayseditable INTEGER DEFAULT 0 AFTER pos;
@ -1181,4 +1181,5 @@ insert into llx_c_tva(rowid,fk_pays,taux,recuperableonly,localtax1,localtax1_typ
ALTER TABLE llx_livraison MODIFY COLUMN date_delivery DATETIME NULL DEFAULT NULL;
INSERT INTO llx_const (name, value, type, note, visible, entity) SELECT 'PRODUCT_USE_OLD_PATH_FOR_PHOTO','1','chaine','Use old path for products images',0,1 FROM llx_const WHERE name='MAIN_VERSION_LAST_INSTALL' AND value < '3.7.0';
-- This constant is for compatibility if user come from 3.6 or lower. Must not be enabled on 3.7.0 or +
INSERT INTO llx_const (name, value, type, note, visible, entity) SELECT __ENCRYPT('PRODUCT_USE_OLD_PATH_FOR_PHOTO')__,__ENCRYPT('1')__,'chaine','Use old path for products images',1,0 FROM llx_const WHERE __DECRYPT('name')__ = 'MAIN_VERSION_LAST_INSTALL' AND __DECRYPT('value')__ < '3.7.0';

View File

@ -0,0 +1,148 @@
#!/usr/bin/php
<?php
/* Copyright (C) 2007-2013 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2015 Jean Heimburger <http://tiaris.eu>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/**
* \file scripts/product/migrate_picture_path.php
* \ingroup scripts
* \brief Migrate pictures from old system prior to 3.7 to new path for 3.7+
*
*/
$sapi_type = php_sapi_name();
$script_file = basename(__FILE__);
$path=dirname(__FILE__).'/';
// Test if batch mode
if (substr($sapi_type, 0, 3) == 'cgi') {
echo "Error: You are using PHP for CGI. To execute ".$script_file." from command line, you must use PHP for CLI mode.\n";
exit(-1);
}
@set_time_limit(0); // No timeout for this script
define('EVEN_IF_ONLY_LOGIN_ALLOWED',1); // Set this define to 0 if you want to lock your script when dolibarr setup is "locked to admin user only".
// Include and load Dolibarr environment variables
require_once($path."../../htdocs/master.inc.php");
require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php");
require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php");
// After this $db, $mysoc, $langs, $conf and $hookmanager are defined (Opened $db handler to database will be closed at end of file).
// $user is created but empty.
//$langs->setDefaultLang('en_US'); // To change default language of $langs
$langs->load("main"); // To load language file for default language
// Global variables
$version=DOL_VERSION;
$error=0;
$forcecommit=0;
print "***** ".$script_file." (".$version.") pid=".dol_getmypid()." *****\n";
dol_syslog($script_file." launched with arg ".join(',',$argv));
if (! isset($argv[1]) || $argv[1] != 'product') {
print "Usage: $script_file product\n";
exit(-1);
}
print '--- start'."\n";
// Case to migrate products path
if ($argv[1] == 'product')
{
$product = new Product($db);
$sql = "SELECT rowid as pid from ".MAIN_DB_PREFIX."product"; // Get list of all products
$resql = $db->query($sql);
if ($resql)
{
while ($obj = $db->fetch_object($resql))
{
$product->fetch($obj->pid);
print " migrating product id=".$product->id." ref=".$product->ref."\n";
migrate_product_photospath($product);
}
}
else
{
print "\n sql error ".$sql;
exit;
}
}
$db->close(); // Close $db database opened handler
exit($error);
/**
* Migrate file from old path to new one for product $product
*
* @param Product $product Object product
* @return void
*/
function migrate_product_photospath($product)
{
global $conf;
$dir = $conf->product->multidir_output[$product->entity];
$origin = $dir .'/'. get_exdir($product->id,2) . $product->id ."/photos";
$destin = $dir.'/'.dol_sanitizeFileName($product->ref);
$error = 0;
$origin_osencoded=dol_osencode($origin);
$destin_osencoded=dol_osencode($destin);
dol_mkdir($destin);
if (dol_is_dir($origin))
{
$handle=opendir($origin_osencoded);
if (is_resource($handle))
{
while (($file = readdir($handle)) != false)
{
if ($file != '.' && $file != '..' && is_dir($origin_osencoded.'/'.$file))
{
$thumbs = opendir($origin_osencoded.'/'.$file);
if (is_resource($thumbs))
{
dol_mkdir($destin.'/'.$file);
while (($thumb = readdir($thumbs)) != false)
{
dol_move($origin.'/'.$file.'/'.$thumb, $destin.'/'.$file.'/'.$thumb);
}
// dol_delete_dir($origin.'/'.$file);
}
}
else
{
if (dol_is_file($origin.'/'.$file) )
{
dol_move($origin.'/'.$file, $destin.'/'.$file);
}
}
}
}
}
}