From f4e58d71ed9e6ef549b0919ff5332010f63ab967 Mon Sep 17 00:00:00 2001 From: Grand Philippe Date: Tue, 9 Apr 2013 09:38:25 +0200 Subject: [PATCH 01/44] add supplier invoice extrafields and some fixes --- htdocs/admin/supplierinvoice_extrafields.php | 160 +++++++++++++++++++ htdocs/admin/supplierorder_extrafields.php | 4 +- htdocs/core/lib/fourn.lib.php | 9 +- htdocs/langs/fr_FR/admin.lang | 3 +- htdocs/langs/fr_FR/suppliers.lang | 1 + 5 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 htdocs/admin/supplierinvoice_extrafields.php diff --git a/htdocs/admin/supplierinvoice_extrafields.php b/htdocs/admin/supplierinvoice_extrafields.php new file mode 100644 index 00000000000..a95a61c98cf --- /dev/null +++ b/htdocs/admin/supplierinvoice_extrafields.php @@ -0,0 +1,160 @@ + + * Copyright (C) 2003 Jean-Louis Bergamo + * Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2012 Florian Henry + * Copyright (C) 2013 Philippe Grand + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/admin/supplierinvoice_extrafields.php + * \ingroup fourn + * \brief Page to setup extra fields of supplierinvoice + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; + + +if (!$user->admin) + accessforbidden(); + +$langs->load("admin"); +$langs->load("other"); +$langs->load("orders"); +$langs->load("suppliers"); + +$extrafields = new ExtraFields($db); +$form = new Form($db); + +// List of supported format +$tmptype2label=getStaticMember(get_class($extrafields),'type2label'); +$type2label=array(''); +foreach ($tmptype2label as $key => $val) $type2label[$key]=$langs->trans($val); + +$action=GETPOST('action', 'alpha'); +$attrname=GETPOST('attrname', 'alpha'); +$elementtype='commande_fournisseur'; + +if (!$user->admin) accessforbidden(); + + +/* + * Actions + */ + +require DOL_DOCUMENT_ROOT.'/core/admin_extrafields.inc.php'; + + + +/* + * View + */ + +$textobject=$langs->transnoentitiesnoconv("SuppliersInvoices"); + +llxHeader('',$langs->trans("SuppliersSetup")); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans("SuppliersSetup"),$linkback,'setup'); +print "
\n"; + +$head = supplierorder_admin_prepare_head(null); + +dol_fiche_head($head, 'supplierinvoice', $langs->trans("ModuleSetup"), 0, 'invoice'); + + +print $langs->trans("DefineHereComplementaryAttributes",$textobject).'
'."\n"; +print '
'; + +// Load attribute_label +$extrafields->fetch_name_optionals_label($elementtype); + +print ""; + +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "\n"; + +$var=True; +foreach($extrafields->attribute_type as $key => $value) +{ + $var=!$var; + print ""; + print "\n"; + print "\n"; + print "\n"; + print '\n"; + print '\n"; + print '\n"; + print '\n"; + print ""; +} + +print "
'.$langs->trans("Label").''.$langs->trans("AttributeCode").''.$langs->trans("Type").''.$langs->trans("Size").''.$langs->trans("Unique").''.$langs->trans("Required").' 
".$extrafields->attribute_label[$key]."".$key."".$type2label[$extrafields->attribute_type[$key]]."'.$extrafields->attribute_size[$key]."'.yn($extrafields->attribute_unique[$key])."'.yn($extrafields->attribute_required[$key])."'.img_edit().''; + print "  ".img_delete()."
"; + +dol_fiche_end(); + + +// Buttons +if ($action != 'create' && $action != 'edit') +{ + print '
'; + print "".$langs->trans("NewAttribute").""; + print "
"; +} + + +/* ************************************************************************** */ +/* */ +/* Creation d'un champ optionnel */ +/* */ +/* ************************************************************************** */ + +if ($action == 'create') +{ + print "
"; + print_titre($langs->trans('NewAttribute')); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_add.tpl.php'; +} + +/* ************************************************************************** */ +/* */ +/* Edition d'un champ optionnel */ +/* */ +/* ************************************************************************** */ +if ($action == 'edit' && ! empty($attrname)) +{ + print "
"; + print_titre($langs->trans("FieldEdition", $attrname)); + + require DOL_DOCUMENT_ROOT.'/core/tpl/admin_extrafields_edit.tpl.php'; +} + +llxFooter(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/admin/supplierorder_extrafields.php b/htdocs/admin/supplierorder_extrafields.php index 9322d034931..68747cf417c 100644 --- a/htdocs/admin/supplierorder_extrafields.php +++ b/htdocs/admin/supplierorder_extrafields.php @@ -65,7 +65,7 @@ require DOL_DOCUMENT_ROOT.'/core/admin_extrafields.inc.php'; * View */ -$textobject=$langs->transnoentitiesnoconv("SupplierOrder"); +$textobject=$langs->transnoentitiesnoconv("SuppliersOrders"); llxHeader('',$langs->trans("SuppliersSetup")); @@ -75,7 +75,7 @@ print "
\n"; $head = supplierorder_admin_prepare_head(null); -dol_fiche_head($head, 'attributes', $langs->trans("ModuleSetup"), 0, 'order'); +dol_fiche_head($head, 'supplierorder', $langs->trans("ModuleSetup"), 0, 'order'); print $langs->trans("DefineHereComplementaryAttributes",$textobject).'
'."\n"; diff --git a/htdocs/core/lib/fourn.lib.php b/htdocs/core/lib/fourn.lib.php index 4d3ebbb0b05..0ae8a67c60b 100644 --- a/htdocs/core/lib/fourn.lib.php +++ b/htdocs/core/lib/fourn.lib.php @@ -171,16 +171,19 @@ function supplierorder_admin_prepare_head($object) $head[$h][0] = DOL_URL_ROOT.'/admin/supplierorder_extrafields.php'; $head[$h][1] = $langs->trans("ExtraFieldsSupplierOrders"); - $head[$h][2] = 'attributes'; + $head[$h][2] = 'supplierorder'; $h++; - complete_head_from_modules($conf,$langs,$object,$head,$h,'supplierorder_admin'); - $head[$h][0] = DOL_URL_ROOT."/admin/supplier_invoice.php"; $head[$h][1] = $langs->trans("SuppliersInvoice"); $head[$h][2] = 'invoice'; $h++; + $head[$h][0] = DOL_URL_ROOT.'/admin/supplierinvoice_extrafields.php'; + $head[$h][1] = $langs->trans("ExtraFieldsSupplierInvoices"); + $head[$h][2] = 'supplierinvoice'; + $h++; + complete_head_from_modules($conf,$langs,$object,$head,$h,'supplierorder_admin','remove'); return $head; diff --git a/htdocs/langs/fr_FR/admin.lang b/htdocs/langs/fr_FR/admin.lang index 70dc7fe2555..0d1a2aaf5e0 100644 --- a/htdocs/langs/fr_FR/admin.lang +++ b/htdocs/langs/fr_FR/admin.lang @@ -953,7 +953,8 @@ ExtraFieldsContacts=Attributs supplémentaires (contacts/adresses) ExtraFieldsMember=Attributs supplémentaires (adhérents) ExtraFieldsMemberType=Attributs supplémentaires (type d'adhérents) ExtraFieldsCustomerInvoices=Attributs supplémentaires (factures clients) -ExtraFieldsSupplierOrders=Attributs supplémentaires (commandes fournisseurs) +ExtraFieldsSupplierOrders=Attributs supplémentaires (commandes) +ExtraFieldsSupplierInvoices=Attributs supplémentaires (factures) ExtraFieldHasWrongValue=L'attribut %s a une valeur incorrecte. AlphaNumOnlyCharsAndNoSpace=uniquement caractères alphanumériques sans espace SendingMailSetup=Configuration de l'envoi par mail diff --git a/htdocs/langs/fr_FR/suppliers.lang b/htdocs/langs/fr_FR/suppliers.lang index 932615ff181..dbe2edbe4ab 100644 --- a/htdocs/langs/fr_FR/suppliers.lang +++ b/htdocs/langs/fr_FR/suppliers.lang @@ -5,6 +5,7 @@ Supplier=Fournisseur AddSupplier=Ajouter un fournisseur SupplierRemoved=Fournisseur supprimé SuppliersInvoice=Facture fournisseur +SuppliersInvoices=Factures fournisseur NewSupplier=Nouveau fournisseur History=Historique ListOfSuppliers=Liste des fournisseurs From c6106e1a8cb8b6c2f96be130f150559bde707cbc Mon Sep 17 00:00:00 2001 From: Grand Philippe Date: Tue, 9 Apr 2013 12:03:49 +0200 Subject: [PATCH 02/44] fix: Champ e.fk_expedition_methode inconnu dans field list --- htdocs/expedition/class/expedition.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 9896eb50486..0dba342b5b6 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -339,7 +339,7 @@ class Expedition extends CommonObject $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut"; $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height"; $sql.= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery"; - $sql.= ", e.fk_expedition_methode, e.tracking_number"; + $sql.= ", e.fk_shipping_method, e.tracking_number"; $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->element."'"; From 275bf67bb7f936783afce8e6fffcfb1b5e77dfec Mon Sep 17 00:00:00 2001 From: fhenry Date: Tue, 9 Apr 2013 17:18:07 +0200 Subject: [PATCH 03/44] [ task #811 ] Uniformanize note field --- htdocs/comm/propal.php | 7 +- htdocs/comm/propal/class/propal.class.php | 15 +- htdocs/comm/propal/note.php | 5 +- htdocs/commande/class/commande.class.php | 11 +- htdocs/commande/fiche.php | 14 +- htdocs/commande/note.php | 5 +- .../deplacement/class/deplacement.class.php | 9 +- htdocs/compta/deplacement/fiche.php | 7 +- htdocs/compta/dons/class/don.class.php | 23 ++- htdocs/compta/dons/fiche.php | 14 +- htdocs/compta/facture.php | 35 ++-- .../facture/class/facture-rec.class.php | 14 +- htdocs/compta/facture/class/facture.class.php | 15 +- htdocs/compta/facture/fiche-rec.php | 7 +- htdocs/compta/facture/list.php | 5 +- htdocs/compta/facture/note.php | 5 +- htdocs/contact/class/contact.class.php | 16 +- htdocs/contact/fiche.php | 58 ++++-- htdocs/contrat/class/contrat.class.php | 13 +- htdocs/contrat/fiche.php | 29 ++- htdocs/contrat/note.php | 4 +- htdocs/core/class/commonobject.class.php | 55 ++++-- htdocs/core/lib/company.lib.php | 5 +- htdocs/core/lib/sendings.lib.php | 5 + .../doc/pdf_expedition_merou.modules.php | 22 +++ htdocs/core/tpl/notes.tpl.php | 17 +- htdocs/expedition/class/expedition.class.php | 20 +- htdocs/expedition/fiche.php | 20 +- htdocs/expedition/note.php | 160 ++++++++++++++++ htdocs/fichinter/fiche.php | 12 +- htdocs/fichinter/note.php | 3 +- .../class/fournisseur.commande.class.php | 9 +- .../fourn/class/fournisseur.facture.class.php | 13 +- htdocs/fourn/commande/fiche.php | 36 ++-- htdocs/fourn/facture/fiche.php | 28 ++- htdocs/fourn/facture/note.php | 171 +++++++++--------- htdocs/holiday/class/holiday.class.php | 5 +- .../install/mysql/migration/3.3.0-3.4.0.sql | 16 ++ htdocs/install/mysql/tables/llx_commande.sql | 2 +- .../mysql/tables/llx_commande_fournisseur.sql | 4 +- htdocs/install/mysql/tables/llx_contrat.sql | 2 +- .../install/mysql/tables/llx_deplacement.sql | 2 +- htdocs/install/mysql/tables/llx_don.sql | 2 +- .../install/mysql/tables/llx_expedition.sql | 3 +- htdocs/install/mysql/tables/llx_facture.sql | 2 +- .../mysql/tables/llx_facture_fourn.sql | 2 +- .../install/mysql/tables/llx_facture_rec.sql | 2 +- htdocs/install/mysql/tables/llx_holiday.sql | 4 +- htdocs/install/mysql/tables/llx_livraison.sql | 2 +- htdocs/install/mysql/tables/llx_propal.sql | 2 +- htdocs/install/mysql/tables/llx_societe.sql | 2 +- htdocs/install/mysql/tables/llx_socpeople.sql | 2 +- htdocs/livraison/class/livraison.class.php | 21 ++- htdocs/livraison/fiche.php | 20 +- htdocs/societe/class/societe.class.php | 15 +- htdocs/societe/note.php | 94 +++------- .../webservices/demo_wsclient_order.php-NORUN | 4 +- htdocs/webservices/server_invoice.php | 8 +- htdocs/webservices/server_order.php | 8 +- .../webservices/server_supplier_invoice.php | 6 +- htdocs/webservices/server_thirdparty.php | 13 +- test/phpunit/ContactTest.php | 17 +- test/phpunit/HolidayTest.php | 18 +- test/phpunit/SocieteTest.php | 17 +- 64 files changed, 776 insertions(+), 406 deletions(-) create mode 100644 htdocs/expedition/note.php diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 42bf3e5d084..b27609b6b28 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -8,7 +8,8 @@ * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand * Copyright (C) 2012 Christophe Battarel -* + * Copyright (C) 2013 Florian Henry + * * 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 @@ -237,9 +238,9 @@ else if ($action == 'setnote_public' && $user->rights->propal->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->propal->creer) +else if ($action == 'setnote_private' && $user->rights->propal->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 13d2e6e87a4..1c514dd679a 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -8,7 +8,8 @@ * Copyright (C) 2008 Raphael Bertrand * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2010-2011 Philippe Grand - * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2013 Florian Henry * * 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 @@ -673,7 +674,7 @@ class Propal extends CommonObject $sql.= ", datec"; $sql.= ", ref"; $sql.= ", fk_user_author"; - $sql.= ", note"; + $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", model_pdf"; $sql.= ", fin_validite"; @@ -698,7 +699,7 @@ class Propal extends CommonObject $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", '(PROV)'"; $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null"); - $sql.= ", '".$this->db->escape($this->note)."'"; + $sql.= ", '".$this->db->escape($this->note_private)."'"; $sql.= ", '".$this->db->escape($this->note_public)."'"; $sql.= ", '".$this->modelpdf."'"; $sql.= ", ".($this->fin_validite!=''?"'".$this->db->idate($this->fin_validite)."'":"null"); @@ -1000,7 +1001,7 @@ class Propal extends CommonObject $sql.= ", p.fin_validite as dfv"; $sql.= ", p.date_livraison as date_livraison"; $sql.= ", p.model_pdf, p.ref_client, p.extraparams"; - $sql.= ", p.note as note_private, p.note_public"; + $sql.= ", p.note_private, p.note_public"; $sql.= ", p.fk_projet, p.fk_statut"; $sql.= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture"; $sql.= ", p.fk_delivery_address"; @@ -1584,7 +1585,7 @@ class Propal extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_statut = ".$statut.", note = '".$this->db->escape($note)."', date_cloture=".$this->db->idate($now).", fk_user_cloture=".$user->id; + $sql.= " SET fk_statut = ".$statut.", note_private = '".$this->db->escape($note)."', date_cloture=".$this->db->idate($now).", fk_user_cloture=".$user->id; $sql.= " WHERE rowid = ".$this->id; $resql=$this->db->query($sql); @@ -1614,7 +1615,7 @@ class Propal extends CommonObject $this->db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET fk_statut = ".$statut.", note = '".$this->db->escape($note)."', date_cloture=".$this->db->idate($now).", fk_user_cloture=".$user->id; + $sql.= " SET fk_statut = ".$statut.", note_private = '".$this->db->escape($note)."', date_cloture=".$this->db->idate($now).", fk_user_cloture=".$user->id; $sql.= " WHERE rowid = ".$this->id; $resql=$this->db->query($sql); @@ -2322,7 +2323,7 @@ class Propal extends CommonObject $this->demand_reason_id = 1; $this->demand_reason_code = 'SRC_00'; $this->note_public='This is a comment (public)'; - $this->note='This is a comment (private)'; + $this->note_private='This is a comment (private)'; // Lines $nbp = 5; $xnbp = 0; diff --git a/htdocs/comm/propal/note.php b/htdocs/comm/propal/note.php index 4603bd82682..663530a92c9 100644 --- a/htdocs/comm/propal/note.php +++ b/htdocs/comm/propal/note.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -54,10 +55,10 @@ if ($action == 'setnote_public' && $user->rights->propale->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->propale->creer) +else if ($action == 'setnote_private' && $user->rights->propale->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index cab6e77be23..0270b0327dd 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2011 Jean Heimburger * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2013 Florian Henry * * 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 @@ -630,7 +631,7 @@ class Commande extends CommonOrder $this->db->begin(); $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande ("; - $sql.= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note, note_public, ref_client, ref_int"; + $sql.= " ref, fk_soc, date_creation, fk_user_author, fk_projet, date_commande, source, note_private, note_public, ref_client, ref_int"; $sql.= ", model_pdf, fk_cond_reglement, fk_mode_reglement, fk_availability, fk_input_reason, date_livraison, fk_delivery_address"; $sql.= ", remise_absolue, remise_percent"; $sql.= ", entity"; @@ -639,7 +640,7 @@ class Commande extends CommonOrder $sql.= ", ".($this->fk_project?$this->fk_project:"null"); $sql.= ", ".$this->db->idate($date); $sql.= ", ".($this->source>=0 && $this->source != '' ?$this->source:'null'); - $sql.= ", '".$this->db->escape($this->note)."'"; + $sql.= ", '".$this->db->escape($this->note_private)."'"; $sql.= ", '".$this->db->escape($this->note_public)."'"; $sql.= ", '".$this->db->escape($this->ref_client)."'"; $sql.= ", ".($this->ref_int?"'".$this->db->escape($this->ref_int)."'":"null"); @@ -952,7 +953,7 @@ class Commande extends CommonOrder $this->fk_delivery_address = $object->fk_delivery_address; $this->contact_id = $object->contactid; $this->ref_client = $object->ref_client; - $this->note = $object->note; + $this->note_private = $object->note_private; $this->note_public = $object->note_public; $this->origin = $object->element; @@ -1267,7 +1268,7 @@ class Commande extends CommonOrder $sql.= ', c.date_commande'; $sql.= ', c.date_livraison'; $sql.= ', c.fk_projet, c.remise_percent, c.remise, c.remise_absolue, c.source, c.facture as billed'; - $sql.= ', c.note as note_private, c.note_public, c.ref_client, c.ref_ext, c.ref_int, c.model_pdf, c.fk_delivery_address, c.extraparams'; + $sql.= ', c.note_private, c.note_public, c.ref_client, c.ref_ext, c.ref_int, c.model_pdf, c.fk_delivery_address, c.extraparams'; $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; $sql.= ', cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle, cr.libelle_facture as cond_reglement_libelle_doc'; $sql.= ', ca.code as availability_code'; @@ -2697,7 +2698,7 @@ class Commande extends CommonOrder $this->availability_code = 'DSP'; $this->demand_reason_code = 'SRC_00'; $this->note_public='This is a comment (public)'; - $this->note='This is a comment (private)'; + $this->note_private='This is a comment (private)'; // Lines $nbp = 5; $xnbp = 0; diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index 455eb698722..af01fcd87c0 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -45,6 +45,7 @@ if (! empty($conf->projet->enabled)) { require DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; require DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php'; } +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $langs->load('orders'); $langs->load('sendings'); @@ -225,7 +226,7 @@ else if ($action == 'add' && $user->rights->commande->creer) $db->begin(); $object->date_commande = $datecommande; - $object->note = GETPOST('note'); + $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); $object->source = GETPOST('source_id'); $object->fk_project = GETPOST('projectid'); @@ -538,9 +539,9 @@ else if ($action == 'setnote_public' && $user->rights->commande->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->commande->creer) +else if ($action == 'setnote_private' && $user->rights->commande->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_rivate(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } @@ -1411,9 +1412,6 @@ $formorder = new FormOrder($db); *********************************************************************/ if ($action == 'create' && $user->rights->commande->creer) { - //WYSIWYG Editor - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - print_fiche_titre($langs->trans('CreateOrder')); dol_htmloutput_mesg($mesg,$mesgs,'error'); @@ -1470,7 +1468,7 @@ if ($action == 'create' && $user->rights->commande->creer) $datedelivery = (!empty($objectsrc->date_livraison)?$objectsrc->date_livraison:''); - $note_private = (! empty($objectsrc->note) ? $objectsrc->note : (! empty($objectsrc->note_private) ? $objectsrc->note_private : '')); + $note_private = (! empty($objectsrc->note_private) ? $objectsrc->note_private : (! empty($objectsrc->note_private) ? $objectsrc->note_private : '')); $note_public = (! empty($objectsrc->note_public) ? $objectsrc->note_public : ''); // Object source contacts list @@ -1632,7 +1630,7 @@ if ($action == 'create' && $user->rights->commande->creer) print ''.$langs->trans('NotePrivate').''; print ''; - $doleditor=new DolEditor('note', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + $doleditor=new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); print $doleditor->Create(1); //print ''; print ''; diff --git a/htdocs/commande/note.php b/htdocs/commande/note.php index 194d7f5e91c..29078518237 100644 --- a/htdocs/commande/note.php +++ b/htdocs/commande/note.php @@ -2,6 +2,7 @@ /* Copyright (C) 2004 Rodolphe Quiedeville * Copyright (C) 2004-2007 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -61,10 +62,10 @@ if ($action == 'setnote_public' && $user->rights->commande->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->commande->creer) +else if ($action == 'setnote_private' && $user->rights->commande->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/compta/deplacement/class/deplacement.class.php b/htdocs/compta/deplacement/class/deplacement.class.php index 1c8820cbd2b..66644cde848 100644 --- a/htdocs/compta/deplacement/class/deplacement.class.php +++ b/htdocs/compta/deplacement/class/deplacement.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2003 Rodolphe Quiedeville * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -101,7 +102,7 @@ class Deplacement extends CommonObject $sql.= ", fk_user_author"; $sql.= ", fk_user"; $sql.= ", type"; - $sql.= ", note"; + $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", fk_projet"; $sql.= ", fk_soc"; @@ -195,7 +196,7 @@ class Deplacement extends CommonObject $sql .= " , fk_user = ".$this->fk_user; $sql .= " , fk_user_modif = ".$user->id; $sql .= " , fk_soc = ".($this->socid > 0?$this->socid:'null'); - $sql .= " , note = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); + $sql .= " , note_private = ".($this->note_private?"'".$this->db->escape($this->note_private)."'":"null"); $sql .= " , note_public = ".($this->note_public?"'".$this->db->escape($this->note_public)."'":"null"); $sql .= " , fk_projet = ".($this->fk_project>0?$this->fk_project:0); $sql .= " WHERE rowid = ".$this->id; @@ -223,7 +224,7 @@ class Deplacement extends CommonObject */ function fetch($id) { - $sql = "SELECT rowid, fk_user, type, fk_statut, km, fk_soc, dated, note, note_public, fk_projet, extraparams"; + $sql = "SELECT rowid, fk_user, type, fk_statut, km, fk_soc, dated, note_private, note_public, fk_projet, extraparams"; $sql.= " FROM ".MAIN_DB_PREFIX."deplacement"; $sql.= " WHERE rowid = ".$id; @@ -241,7 +242,7 @@ class Deplacement extends CommonObject $this->km = $obj->km; $this->type = $obj->type; $this->statut = $obj->fk_statut; - $this->note_private = $obj->note; + $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->fk_project = $obj->fk_projet; diff --git a/htdocs/compta/deplacement/fiche.php b/htdocs/compta/deplacement/fiche.php index 1e20d91c350..c7a7c6b7a2e 100644 --- a/htdocs/compta/deplacement/fiche.php +++ b/htdocs/compta/deplacement/fiche.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -234,13 +235,13 @@ else if ($action == 'setkm' && $user->rights->deplacement->creer) else if ($action == 'setnote_public' && $user->rights->deplacement->creer) { $object->fetch($id); - $result=$object->setValueFrom('note_public',GETPOST('note_public','alpha')); + $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); if ($result < 0) dol_print_error($db, $object->error); } -else if ($action == 'setnote' && $user->rights->deplacement->creer) +else if ($action == 'setnote_private' && $user->rights->deplacement->creer) { $object->fetch($id); - $result=$object->setValueFrom('note',GETPOST('note','alpha')); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db, $object->error); } diff --git a/htdocs/compta/dons/class/don.class.php b/htdocs/compta/dons/class/don.class.php index 9ca97617db6..f5d477de48f 100644 --- a/htdocs/compta/dons/class/don.class.php +++ b/htdocs/compta/dons/class/don.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2002 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2009 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -51,7 +52,8 @@ class Don extends CommonObject var $fk_project; var $modepaiement; var $modepaiementid; - var $note; + var $note_private; + var $note_public; var $statut; var $projet; @@ -191,7 +193,8 @@ class Don extends CommonObject $this->address = 'Twist road'; $this->zip = '99999'; $this->town = 'Town'; - $this->note_public='SPECIMEN'; + $this->note_private='Private note'; + $this->note_public='Public note'; $this->email='email@email.com'; $this->note=''; $this->statut=1; @@ -319,7 +322,8 @@ class Don extends CommonObject $sql.= ", country"; $sql.= ", public"; $sql.= ", fk_don_projet"; - $sql.= ", note"; + $sql.= ", note_private"; + $sql.= ", note_public"; $sql.= ", fk_user_author"; $sql.= ", fk_user_valid"; $sql.= ", datedon"; @@ -340,7 +344,8 @@ class Don extends CommonObject $sql.= ", '".$this->db->escape($this->country)."'"; // TODO use country_id $sql.= ", ".$this->public; $sql.= ", ".($this->fk_project > 0?$this->fk_project:"null"); - $sql.= ", '".$this->db->escape($this->note)."'"; + $sql.= ", ".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL"); + $sql.= ", ".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL"); $sql.= ", ".$user->id; $sql.= ", null"; $sql.= ", '".$this->db->idate($this->date)."'"; @@ -400,7 +405,8 @@ class Don extends CommonObject $sql .= ",country='".$this->db->escape($this->country)."'"; // TODO use country_id $sql .= ",public=".$this->public; $sql .= ",fk_don_projet=".($this->fk_project>0?$this->fk_project:'null'); - $sql .= ",note='".$this->db->escape($this->note)."'"; + $sql .= ",note_private=".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL"); + $sql .= ",note_public=".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL"); $sql .= ",datedon='".$this->db->idate($this->date)."'"; $sql .= ",email='".$this->email."'"; $sql .= ",phone='".$this->phone."'"; @@ -463,7 +469,9 @@ class Don extends CommonObject global $conf; $sql = "SELECT d.rowid, d.datec, d.tms as datem, d.datedon,"; - $sql.= " d.firstname, d.lastname, d.societe, d.amount, d.fk_statut, d.address, d.zip, d.town, d.country, d.public, d.amount, d.fk_paiement, d.note, cp.libelle, d.email, d.phone, d.phone_mobile, d.fk_don_projet,"; + $sql.= " d.firstname, d.lastname, d.societe, d.amount, d.fk_statut, d.address, d.zip, d.town, "; + $sql.= " d.country, d.public, d.amount, d.fk_paiement, d.note_private, d.note_public, cp.libelle, d.email, d.phone, "; + $sql.= " d.phone_mobile, d.fk_don_projet,"; $sql.= " p.title as project_label"; $sql.= " FROM ".MAIN_DB_PREFIX."don as d"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = d.fk_don_projet"; @@ -501,7 +509,8 @@ class Don extends CommonObject $this->modepaiementid = $obj->fk_paiement; $this->modepaiement = $obj->libelle; $this->amount = $obj->amount; - $this->note = $obj->note; + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; $this->commentaire = $obj->note; // deprecated } return 1; diff --git a/htdocs/compta/dons/fiche.php b/htdocs/compta/dons/fiche.php index 8c916b7c5f2..e04c6699848 100644 --- a/htdocs/compta/dons/fiche.php +++ b/htdocs/compta/dons/fiche.php @@ -2,6 +2,7 @@ /* Copyright (C) 2001-2002 Rodolphe Quiedeville * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -98,7 +99,8 @@ if ($action == 'update') $don->note = $_POST["note"]; $don->public = $_POST["public"]; $don->fk_project = $_POST["projectid"]; - $don->note = $_POST["comment"]; + $don->note_private= GETPOST("note_private"); + $don->note_public = GETPOST("note_public"); $don->modepaiementid = $_POST["modepaiement"]; if ($don->update($user) > 0) @@ -146,10 +148,10 @@ if ($action == 'add') $don->country = $_POST["country"]; $don->email = $_POST["email"]; $don->date = $donation_date; - $don->note = $_POST["note"]; + $don->note_private= GETPOST("note_private"); + $don->note_public = GETPOST("note_public"); $don->public = $_POST["public"]; $don->fk_project = $_POST["projectid"]; - $don->note = $_POST["comment"]; $don->modepaiementid = $_POST["modepaiement"]; if ($don->create($user) > 0) @@ -283,7 +285,7 @@ if ($action == 'create') print ''; print ''.$langs->trans("Comments").' :
'; - print ""; + print ""; print ""; // Amount @@ -371,7 +373,7 @@ if (! empty($id) && $action == 'edit') print ''; print ''.$langs->trans("Comments").' :
'; - print ""; + print ""; print ""; // Amount @@ -471,7 +473,7 @@ if (! empty($id) && $action != 'edit') print ""; print ''.$langs->trans("Comments").' :
'; - print nl2br($don->note).''; + print nl2br($don->note_private).''; print "".''.$langs->trans("Amount").''.price($don->amount).' '.$langs->trans("Currency".$conf->currency).''; diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index e4b7e923ef0..7248e124b46 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -8,6 +8,7 @@ * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2013 Jean-Francois FERRY + * Copyright (C) 2013 Florian Henry * * 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 @@ -43,6 +44,7 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php'; if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php'; if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; if (! empty($conf->projet->enabled)) require_once DOL_DOCUMENT_ROOT . '/core/lib/project.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $langs->load('bills'); $langs->load('companies'); @@ -355,10 +357,10 @@ else if ($action == 'setnote_public' && $user->rights->facture->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->facture->creer) +else if ($action == 'setnote_private' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } @@ -695,7 +697,7 @@ else if ($action == 'add' && $user->rights->facture->creer) //$result=$object->fetch($_POST['fac_avoir']); - $object->socid = $_POST['socid']; + $object->socid = GETPOST('socid','int'); $object->number = $_POST['facnumber']; $object->date = $datefacture; $object->note_public = trim($_POST['note_public']); @@ -742,12 +744,12 @@ else if ($action == 'add' && $user->rights->facture->creer) if (! $error) { - $object->socid = $_POST['socid']; + $object->socid = GETPOST('socid','int'); $object->type = $_POST['type']; $object->number = $_POST['facnumber']; $object->date = $datefacture; $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); + $object->note_private = trim($_POST['note_private']); $object->ref_client = $_POST['ref_client']; $object->ref_int = $_POST['ref_int']; $object->modelpdf = $_POST['model']; @@ -778,12 +780,12 @@ else if ($action == 'add' && $user->rights->facture->creer) if (! $error) { // Si facture standard - $object->socid = $_POST['socid']; - $object->type = $_POST['type']; + $object->socid = GETPOST('socid','int'); + $object->type = GETPOST('type'); $object->number = $_POST['facnumber']; $object->date = $datefacture; $object->note_public = trim($_POST['note_public']); - $object->note = trim($_POST['note']); + $object->note_private = trim($_POST['note_private']); $object->ref_client = $_POST['ref_client']; $object->ref_int = $_POST['ref_int']; $object->modelpdf = $_POST['model']; @@ -2113,12 +2115,15 @@ if ($action == 'create') print ''; print ''.$langs->trans('NotePublic').''; print ''; - print ''; + $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + + //print ''; // Private note if (empty($user->societe_id)) @@ -2126,12 +2131,14 @@ if ($action == 'create') print ''; print ''.$langs->trans('NotePrivate').''; print ''; - print ''; + $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print ''; } if (! empty($origin) && ! empty($originid) && is_object($objectsrc)) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 4e168d0645f..1651407d746 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2010-2011 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -54,7 +55,8 @@ class FactureRec extends Facture var $remise; var $tva; var $total; - var $note; + var $note_private; + var $note_public; var $db_table; var $propalid; var $fk_project; @@ -111,7 +113,8 @@ class FactureRec extends Facture $sql.= ", datec"; $sql.= ", amount"; $sql.= ", remise"; - $sql.= ", note"; + $sql.= ", note_private"; + $sql.= ", note_public"; $sql.= ", fk_user_author"; $sql.= ", fk_projet"; $sql.= ", fk_cond_reglement"; @@ -124,7 +127,8 @@ class FactureRec extends Facture $sql.= ", ".$this->db->idate($now); $sql.= ", '".$facsrc->amount."'"; $sql.= ", '".$facsrc->remise."'"; - $sql.= ", '".$this->db->escape($this->note)."'"; + $sql.= ", ".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL"); + $sql.= ", ".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL"); $sql.= ", '".$user->id."'"; $sql.= ", ".(! empty($facsrc->fk_project)?"'".$facsrc->fk_project."'":"null"); $sql.= ", '".$facsrc->cond_reglement_id."'"; @@ -201,7 +205,7 @@ class FactureRec extends Facture { $sql = 'SELECT f.titre,f.fk_soc,f.amount,f.tva,f.total,f.total_ttc,f.remise_percent,f.remise_absolue,f.remise'; $sql.= ', f.date_lim_reglement as dlr'; - $sql.= ', f.note, f.note_public, f.fk_user_author'; + $sql.= ', f.note_private, f.note_public, f.fk_user_author'; $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement'; $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; $sql.= ', c.code as cond_reglement_code, c.libelle as cond_reglement_libelle, c.libelle_facture as cond_reglement_libelle_doc'; @@ -249,7 +253,7 @@ class FactureRec extends Facture $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc; $this->fk_project = $obj->fk_projet; $this->fk_facture_source = $obj->fk_facture_source; - $this->note = $obj->note; + $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->user_author = $obj->fk_user_author; $this->modelpdf = $obj->model_pdf; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 6c19894e7f1..f4dc4527c74 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -11,6 +11,7 @@ * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2012 Marcos García * Copyright (C) 2013 Cedric Gross + * Copyright (C) 2013 Florian Henry * * 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 @@ -144,7 +145,7 @@ class Facture extends CommonInvoice if (empty($this->type)) $this->type = 0; $this->ref_client=trim($this->ref_client); $this->note=(isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated - $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note)); + $this->note_private=(isset($this->note_private) ? trim($this->note_private) : trim($this->note_private)); $this->note_public=trim($this->note_public); if (! $this->cond_reglement_id) $this->cond_reglement_id = 0; if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; @@ -190,7 +191,7 @@ class Facture extends CommonInvoice // Clean parametres if (! $this->type) $this->type = 0; $this->ref_client=trim($this->ref_client); - $this->note=trim($this->note); + $this->note_private=trim($this->note_private); $this->note_public=trim($this->note_public); //if (! $this->remise) $this->remise = 0; if (! $this->mode_reglement_id) $this->mode_reglement_id = 0; @@ -213,7 +214,7 @@ class Facture extends CommonInvoice $sql.= ", remise_absolue"; $sql.= ", remise_percent"; $sql.= ", datef"; - $sql.= ", note"; + $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", ref_client, ref_int"; $sql.= ", fk_facture_source, fk_user_author, fk_projet"; @@ -516,7 +517,7 @@ class Facture extends CommonInvoice $facture->socid = $this->socid; $facture->date = $this->date; $facture->note_public = $this->note_public; - $facture->note = $this->note; + $facture->note_private = $this->note_private; $facture->ref_client = $this->ref_client; $facture->modelpdf = $this->modelpdf; $facture->fk_project = $this->fk_project; @@ -703,7 +704,7 @@ class Facture extends CommonInvoice $this->fk_delivery_address = $object->fk_delivery_address; $this->contact_id = $object->contactid; $this->ref_client = $object->ref_client; - $this->note = $object->note; + $this->note_private = $object->note_private; $this->note_public = $object->note_public; $this->origin = $object->element; @@ -802,7 +803,7 @@ class Facture extends CommonInvoice $sql.= ', f.datec as datec'; $sql.= ', f.date_valid as datev'; $sql.= ', f.tms as datem'; - $sql.= ', f.note as note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf'; + $sql.= ', f.note_private, f.note_public, f.fk_statut, f.paye, f.close_code, f.close_note, f.fk_user_author, f.fk_user_valid, f.model_pdf'; $sql.= ', f.fk_facture_source'; $sql.= ', f.fk_mode_reglement, f.fk_cond_reglement, f.fk_projet, f.extraparams'; $sql.= ', p.code as mode_reglement_code, p.libelle as mode_reglement_libelle'; @@ -1061,7 +1062,7 @@ class Facture extends CommonInvoice $sql.= " fk_cond_reglement=".(isset($this->cond_reglement_id)?$this->cond_reglement_id:"null").","; $sql.= " fk_mode_reglement=".(isset($this->mode_reglement_id)?$this->mode_reglement_id:"null").","; $sql.= " date_lim_reglement=".(strval($this->date_lim_reglement)!='' ? "'".$this->db->idate($this->date_lim_reglement)."'" : 'null').","; - $sql.= " note=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; $sql.= " model_pdf=".(isset($this->modelpdf)?"'".$this->db->escape($this->modelpdf)."'":"null").","; $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; diff --git a/htdocs/compta/facture/fiche-rec.php b/htdocs/compta/facture/fiche-rec.php index 804c34cf701..54d0c800920 100644 --- a/htdocs/compta/facture/fiche-rec.php +++ b/htdocs/compta/facture/fiche-rec.php @@ -2,6 +2,7 @@ /* Copyright (C) 2002-2003 Rodolphe Quiedeville * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -72,7 +73,7 @@ if ($action == 'add') if (! $error) { $object->titre = GETPOST('titre', 'alpha'); - $object->note = GETPOST('note'); + $object->note_private = GETPOST('note_private'); $object->usenewprice = GETPOST('usenewprice'); if ($object->create($user, $id) > 0) @@ -143,7 +144,7 @@ if ($action == 'create') // Note print ''; - print ''; + print ''; print ''; // Author @@ -394,7 +395,7 @@ else $form->form_modes_reglement($_SERVER['PHP_SELF'].'?id='.$object->id, $object->mode_reglement_id,'none'); print ""; - print ''.$langs->trans("Note").''.nl2br($object->note).""; + print ''.$langs->trans("Note").''.nl2br($object->note_private).""; print ""; diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 796bf769698..1003dd23700 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -7,6 +7,7 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2012 Christophe Battarel + * Copyright (C) 2013 Florian Henry * * 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 @@ -140,7 +141,7 @@ if (! $sall) $sql = 'SELECT'; else $sql = 'SELECT DISTINCT'; $sql.= ' f.rowid as facid, f.facnumber, f.type, f.increment, f.total as total_ht, f.tva as total_tva, f.total_ttc,'; $sql.= ' f.datef as df, f.date_lim_reglement as datelimite,'; -$sql.= ' f.paye as paye, f.fk_statut, f.note,'; +$sql.= ' f.paye as paye, f.fk_statut,'; $sql.= ' s.nom, s.rowid as socid'; if (! $sall) $sql.= ', SUM(pf.amount) as am'; // To be able to sort on status $sql.= ' FROM '.MAIN_DB_PREFIX.'societe as s'; @@ -210,7 +211,7 @@ if (! $sall) { $sql.= ' GROUP BY f.rowid, f.facnumber, f.type, f.increment, f.total, f.total_ttc,'; $sql.= ' f.datef, f.date_lim_reglement,'; - $sql.= ' f.paye, f.fk_statut, f.note,'; + $sql.= ' f.paye, f.fk_statut,'; $sql.= ' s.nom, s.rowid'; } else diff --git a/htdocs/compta/facture/note.php b/htdocs/compta/facture/note.php index a96f5643b80..484dff7020f 100644 --- a/htdocs/compta/facture/note.php +++ b/htdocs/compta/facture/note.php @@ -2,6 +2,7 @@ /* Copyright (C) 2004 Rodolphe Quiedeville * Copyright (C) 2004-2008 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -56,10 +57,10 @@ if ($action == 'setnote_public' && $user->rights->facture->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->facture->creer) +else if ($action == 'setnote_private' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 73bdbc4a0f4..65c0407cb97 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2007 Franky Van Liedekerke * Copyright (C) 2008 Raphael Bertrand (Resultic) + * Copyright (C) 2013 Florian Henry * * 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 @@ -63,7 +64,8 @@ class Contact extends CommonObject var $birthday; var $default_lang; var $note_public; // Public note - var $note; // Private note + var $note; // deprecated + var $note_private; // Private note var $no_email; // 1=Don't send e-mail to this contact, 0=do var $ref_facturation; // Nb de reference facture pour lequel il est contact @@ -238,7 +240,8 @@ class Contact extends CommonObject $sql .= ", poste='".$this->db->escape($this->poste)."'"; $sql .= ", fax='".$this->db->escape($this->fax)."'"; $sql .= ", email='".$this->db->escape($this->email)."'"; - $sql .= ", note='".$this->db->escape($this->note)."'"; + $sql .= ", note_private='".$this->db->escape($this->note_private)."'"; + $sql .= ", note_public='".$this->db->escape($this->note_public)."'"; $sql .= ", phone = '".$this->db->escape($this->phone_pro)."'"; $sql .= ", phone_perso = '".$this->db->escape($this->phone_perso)."'"; $sql .= ", phone_mobile = '".$this->db->escape($this->phone_mobile)."'"; @@ -366,7 +369,7 @@ class Contact extends CommonObject if ($this->phone_perso && ! empty($conf->global->LDAP_CONTACT_FIELD_HOMEPHONE)) $info[$conf->global->LDAP_CONTACT_FIELD_HOMEPHONE] = $this->phone_perso; if ($this->phone_mobile && ! empty($conf->global->LDAP_CONTACT_FIELD_MOBILE)) $info[$conf->global->LDAP_CONTACT_FIELD_MOBILE] = $this->phone_mobile; if ($this->fax && ! empty($conf->global->LDAP_CONTACT_FIELD_FAX)) $info[$conf->global->LDAP_CONTACT_FIELD_FAX] = $this->fax; - if ($this->note && ! empty($conf->global->LDAP_CONTACT_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_CONTACT_FIELD_DESCRIPTION] = $this->note; + if ($this->note_private && ! empty($conf->global->LDAP_CONTACT_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_CONTACT_FIELD_DESCRIPTION] = $this->note_private; if ($this->email && ! empty($conf->global->LDAP_CONTACT_FIELD_MAIL)) $info[$conf->global->LDAP_CONTACT_FIELD_MAIL] = $this->email; if ($conf->global->LDAP_SERVER_TYPE == 'egroupware') @@ -482,7 +485,7 @@ class Contact extends CommonObject $sql.= " c.fk_departement,"; $sql.= " c.birthday,"; $sql.= " c.poste, c.phone, c.phone_perso, c.phone_mobile, c.fax, c.email, c.jabberid,"; - $sql.= " c.priv, c.note, c.default_lang, c.no_email, c.canvas,"; + $sql.= " c.priv, c.note_private, c.note_public, c.default_lang, c.no_email, c.canvas,"; $sql.= " c.import_key,"; $sql.= " p.libelle as country, p.code as country_code,"; $sql.= " d.nom as state, d.code_departement as state_code,"; @@ -538,7 +541,8 @@ class Contact extends CommonObject $this->mail = $obj->email; $this->birthday = $this->db->jdate($obj->birthday); - $this->note = $obj->note; + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; $this->default_lang = $obj->default_lang; $this->no_email = $obj->no_email; $this->user_id = $obj->user_id; @@ -1008,7 +1012,7 @@ class Contact extends CommonObject $this->fax = '0909090909'; $this->note_public='This is a comment (public)'; - $this->note='This is a comment (private)'; + $this->note_private='This is a comment (private)'; $socid = rand(1, $num_socs); $this->socid = $socids[$socid]; diff --git a/htdocs/contact/fiche.php b/htdocs/contact/fiche.php index db0fe091cd9..a0ca630a423 100644 --- a/htdocs/contact/fiche.php +++ b/htdocs/contact/fiche.php @@ -4,6 +4,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2007 Franky Van Liedekerke + * Copyright (C) 2013 Florian Henry * * 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 @@ -32,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/contact.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $langs->load("companies"); $langs->load("users"); @@ -152,7 +154,8 @@ if (empty($reshook)) $object->jabberid = $_POST["jabberid"]; $object->no_email = $_POST["no_email"]; $object->priv = $_POST["priv"]; - $object->note = $_POST["note"]; + $object->note_public = GETPOST("note_public"); + $object->note_private = GETPOST("note_private"); // Note: Correct date should be completed with location to have exact GM time of birth. $object->birthday = dol_mktime(0,0,0,$_POST["birthdaymonth"],$_POST["birthdayday"],$_POST["birthdayyear"]); @@ -247,7 +250,8 @@ if (empty($reshook)) $object->jabberid = $_POST["jabberid"]; $object->no_email = $_POST["no_email"]; $object->priv = $_POST["priv"]; - $object->note = $_POST["note"]; + $object->note_public = GETPOST("note_public"); + $object->note_private = GETPOST("note_private"); // Fill array 'array_options' with data from add form $ret = $extrafields->setOptionalsFromPost($extralabels,$object); @@ -499,8 +503,21 @@ else print $form->selectarray('priv',$selectarray,(isset($_POST["priv"])?$_POST["priv"]:$object->priv),0); print ''; - // Note - print ''.$langs->trans("Note").''; + // Note Public + print ''.$langs->trans("NotePublic").''; + print ''; + $doleditor = new DolEditor('note_public', GETPOST('note_public'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print ''; + print ''; + + // Note Private + print ''.$langs->trans("NotePrivate").''; + print ''; + $doleditor = new DolEditor('note_private', GETPOST('note_private'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print ''; + print ''; // Other attributes $parameters=array('colspan' => ' colspan="3"'); @@ -703,11 +720,23 @@ else print $form->selectarray('priv',$selectarray,$object->priv,0); print ''; - // Note - print ''.$langs->trans("Note").''; - print ''; + // Note Public + print ''.$langs->trans("NotePublic").''; + $doleditor = new DolEditor('note_public', $object->note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + // print ''; + print ''; + + // Note Private + print ''.$langs->trans("NotePrivate").''; + $doleditor = new DolEditor('note_private', $object->note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + // print ''; + print ''; // Other attributes $parameters=array('colspan' => ' colspan="3"'); @@ -908,9 +937,14 @@ else print $object->LibPubPriv($object->priv); print ''; - // Note - print ''.$langs->trans("Note").''; - print nl2br($object->note); + // Note Public + print ''.$langs->trans("NotePublic").''; + print nl2br($object->note_public); + print ''; + + // Note Private + print ''.$langs->trans("NotePrivate").''; + print nl2br($object->note_private); print ''; // Other attributes diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index d85b8fb89b1..afbc82ab391 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -5,7 +5,8 @@ * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2008 Raphael Bertrand * Copyright (C) 2010-2011 Juanjo Menent - * Copyright (C) 2013 Christophe Battarel + * Copyright (C) 2013 Christophe Battarel + * Copyright (C) 2013 Florian Henry * * 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 @@ -338,7 +339,7 @@ class Contrat extends CommonObject $sql.= " fk_user_author,"; $sql.= " fk_projet,"; $sql.= " fk_commercial_signature, fk_commercial_suivi,"; - $sql.= " note as note_private, note_public, extraparams"; + $sql.= " note_private, note_public, extraparams"; $sql.= " FROM ".MAIN_DB_PREFIX."contrat"; if ($ref) { @@ -649,7 +650,7 @@ class Contrat extends CommonObject // Insert contract $sql = "INSERT INTO ".MAIN_DB_PREFIX."contrat (datec, fk_soc, fk_user_author, date_contrat,"; $sql.= " fk_commercial_signature, fk_commercial_suivi, fk_projet,"; - $sql.= " ref, entity, note, note_public)"; + $sql.= " ref, entity, note_private, note_public)"; $sql.= " VALUES (".$this->db->idate($now).",".$this->socid.",".$user->id; $sql.= ",".$this->db->idate($this->date_contrat); $sql.= ",".($this->commercial_signature_id>0?$this->commercial_signature_id:"NULL"); @@ -657,7 +658,7 @@ class Contrat extends CommonObject $sql.= ",".($this->fk_project>0?$this->fk_project:"NULL"); $sql.= ", ".(dol_strlen($this->ref)<=0 ? "null" : "'".$this->ref."'"); $sql.= ", ".$conf->entity; - $sql.= ", ".(!empty($this->note)?("'".$this->db->escape($this->note)."'"):"NULL"); + $sql.= ", ".(!empty($this->note_private)?("'".$this->db->escape($this->note_private)."'"):"NULL"); $sql.= ", ".(!empty($this->note_public)?("'".$this->db->escape($this->note_public)."'"):"NULL"); $sql.= ")"; $resql=$this->db->query($sql); @@ -1605,8 +1606,8 @@ class Contrat extends CommonObject $this->date_contrat = dol_now(); $this->commercial_signature_id = 1; $this->commercial_suivi_id = 1; - $this->note='This is a comment (private)'; - $this->note='This is a comment (public)'; + $this->note_private='This is a comment (private)'; + $this->note_public='This is a comment (public)'; $this->fk_projet = 0; // Lines $nbp = 5; diff --git a/htdocs/contrat/fiche.php b/htdocs/contrat/fiche.php index f0fd4cd66ea..368971e6ea4 100644 --- a/htdocs/contrat/fiche.php +++ b/htdocs/contrat/fiche.php @@ -4,7 +4,8 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2006 Andre Cianfarani * Copyright (C) 2010-2012 Juanjo Menent - * Copyright (C) 2013 Christophe Battarel + * Copyright (C) 2013 Christophe Battarel + * Copyright (C) 2013 Florian Henry * * 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 @@ -32,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php'; require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/modules/contract/modules_contract.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; if (! empty($conf->projet->enabled)) { @@ -182,7 +184,7 @@ if ($action == 'add' && $user->rights->contrat->creer) $object->commercial_suivi_id = GETPOST('commercial_suivi_id','int'); $object->commercial_signature_id = GETPOST('commercial_signature_id','int'); - $object->note = GETPOST('note','alpha'); + $object->note_private = GETPOST('note_private','alpha'); $object->note_public = GETPOST('note_public','alpha'); $object->fk_project = GETPOST('projectid','int'); $object->remise_percent = GETPOST('remise_percent','alpha'); @@ -660,9 +662,9 @@ else if ($action == 'setnote_public' && $user->rights->contrat->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->contrat->creer) +else if ($action == 'setnote_private' && $user->rights->contrat->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } @@ -785,7 +787,7 @@ if ($action == 'create') $soc = $objectsrc->client; - $note_private = (! empty($objectsrc->note) ? $objectsrc->note : (! empty($objectsrc->note_private) ? $objectsrc->note_private : '')); + $note_private = (! empty($objectsrc->note_private) ? $objectsrc->note_private : ''); $note_public = (! empty($objectsrc->note_public) ? $objectsrc->note_public : ''); // Object source contacts list @@ -794,7 +796,7 @@ if ($action == 'create') } else { $projectid = GETPOST('projectid','int'); - $note_private = GETPOST("note"); + $note_private = GETPOST("note_private"); $note_public = GETPOST("note_public"); } @@ -869,25 +871,16 @@ if ($action == 'create') print ''.$langs->trans("NotePublic").''; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor('note_public', $note_public, '', '100', 'dolibarr_notes', 'In', 1, true, true, ROWS_3, 70); print $doleditor->Create(1); - /* - print ''; - */ + if (! $user->societe_id) { print ''.$langs->trans("NotePrivate").''; - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note', $note_private, '', '100', 'dolibarr_notes', 'In', 1, true, true, ROWS_3, 70); + $doleditor=new DolEditor('note_private', $note_private, '', '100', 'dolibarr_notes', 'In', 1, true, true, ROWS_3, 70); print $doleditor->Create(1); - /* - print '';*/ print ''; } diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index f502d10d39b..cf347cf2973 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -54,9 +54,9 @@ if ($action == 'setnote_public' && $user->rights->contrat->creer) if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->contrat->creer) +else if ($action == 'setnote_private' && $user->rights->contrat->creer) { - $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note')), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_private')), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index f7bc6938043..e4972596d22 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1402,43 +1402,66 @@ abstract class CommonObject /** * Update private note of element * - * @param string $note New value for note + * @param string $note_private New value for note * @return int <0 if KO, >0 if OK */ - function update_note($note) + function update_note_private($note_private) { if (! $this->table_element) { - dol_syslog(get_class($this)."::update_note was called on objet with property table_element not defined", LOG_ERR); + dol_syslog(get_class($this)."::update_note_private was called on objet with property table_element not defined", LOG_ERR); return -1; } $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - // TODO uniformize fields to note_private - if ($this->table_element == 'fichinter' || $this->table_element == 'projet' || $this->table_element == 'projet_task') - { - $sql.= " SET note_private = '".$this->db->escape($note)."'"; - } - else - { - $sql.= " SET note = '".$this->db->escape($note)."'"; - } + $sql.= " SET note_private = ".(!empty($note_private)?("'".$this->db->escape($note_private)."'"):"NULL"); $sql.= " WHERE rowid =". $this->id; - dol_syslog(get_class($this)."::update_note sql=".$sql, LOG_DEBUG); + dol_syslog(get_class($this)."::update_note_private sql=".$sql, LOG_DEBUG); if ($this->db->query($sql)) { - $this->note = $note; // deprecated $this->note_private = $note; return 1; } else { $this->error=$this->db->error(); - dol_syslog(get_class($this)."::update_note error=".$this->error, LOG_ERR); + dol_syslog(get_class($this)."::update_note_private error=".$this->error, LOG_ERR); return -1; } } + + /** + * Update private note of element + * + * @param string $note New value for note + * @return int <0 if KO, >0 if OK + */ + function update_note($note) + { + if (! $this->table_element) + { + dol_syslog(get_class($this)."::update_note was called on objet with property table_element not defined", LOG_ERR); + return -1; + } + + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; + $sql.= " SET note = ".(!empty($note)?("'".$this->db->escape($note)."'"):"NULL"); + $sql.= " WHERE rowid =". $this->id; + + dol_syslog(get_class($this)."::update_note sql=".$sql, LOG_DEBUG); + if ($this->db->query($sql)) + { + $this->note = $note; // deprecated + return 1; + } + else + { + $this->error=$this->db->error(); + dol_syslog(get_class($this)."::update_note error=".$this->error, LOG_ERR); + return -1; + } + } /** * Update public note of element @@ -1455,7 +1478,7 @@ abstract class CommonObject } $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET note_public = '".$this->db->escape($note_public)."'"; + $sql.= " SET note_public = ".(!empty($note_public)?("'".$this->db->escape($note_public)."'"):"NULL"); $sql.= " WHERE rowid =". $this->id; dol_syslog(get_class($this)."::update_note_public sql=".$sql); diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index cb701a07c8d..c591b2c023c 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -3,6 +3,7 @@ * Copyright (C) 2006 Rodolphe Quiedeville * Copyright (C) 2007 Patrick Raguin * Copyright (C) 2010-2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -85,7 +86,7 @@ function societe_prepare_head($object) if ($user->societe_id == 0) { // Notes - $head[$h][0] = DOL_URL_ROOT.'/societe/note.php?socid='.$object->id; + $head[$h][0] = DOL_URL_ROOT.'/societe/note.php?id='.$object->id; $head[$h][1] = $langs->trans("Note"); $head[$h][2] = 'note'; $h++; @@ -529,7 +530,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') } print ""; - $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays, p.poste, p.phone, p.phone_mobile, p.fax, p.email, p.note "; + $sql = "SELECT p.rowid, p.lastname, p.firstname, p.fk_pays, p.poste, p.phone, p.phone_mobile, p.fax, p.email "; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as p"; $sql .= " WHERE p.fk_soc = ".$object->id; $sql .= " ORDER by p.datec"; diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php index 78fd0b9f0e0..2d4728c07d4 100644 --- a/htdocs/core/lib/sendings.lib.php +++ b/htdocs/core/lib/sendings.lib.php @@ -63,6 +63,11 @@ function shipping_prepare_head($object) $head[$h][1] = $langs->trans("ContactsAddresses"); $head[$h][2] = 'contact'; $h++; + + $head[$h][0] = DOL_URL_ROOT."/expedition/note.php?id=".$object->id; + $head[$h][1] = $langs->trans("Notes"); + $head[$h][2] = 'note'; + $h++; // Show more tabs from modules // Entries must be declared in modules descriptor with line diff --git a/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php index 39c70faab79..4f6f04cc742 100644 --- a/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_expedition_merou.modules.php @@ -2,6 +2,7 @@ /* Copyright (C) 2005 Rodolphe Quiedeville * Copyright (C) 2005-2012 Laurent Destailleur * Copyright (C) 2005-2011 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -191,6 +192,27 @@ class pdf_expedition_merou extends ModelePdfExpedition $tab_top_newpage = (empty($conf->global->MAIN_PDF_DONOTREPEAT_HEAD)?42:10); $tab_height = $this->page_hauteur - $tab_top - $heightforfooter; $tab_height_newpage = $this->page_hauteur - $tab_top_newpage - $heightforfooter; + + // Affiche notes + if (! empty($object->note_public)) + { + $pdf->SetFont('','', $default_font_size - 1); + $pdf->writeHTMLCell(190, 3, $this->marge_gauche, $tab_top, dol_htmlentitiesbr($object->note_public), 0, 1); + $nexY = $pdf->GetY(); + $height_note=$nexY-$tab_top; + + // Rect prend une longueur en 3eme param + $pdf->SetDrawColor(192,192,192); + $pdf->Rect($this->marge_gauche, $tab_top-1, $this->page_largeur-$this->marge_gauche-$this->marge_droite, $height_note+1); + + $tab_height = $tab_height - $height_note; + $tab_top = $nexY+6; + } + else + { + $height_note=0; + } + $pdf->SetFillColor(240,240,240); $pdf->SetTextColor(0,0,0); diff --git a/htdocs/core/tpl/notes.tpl.php b/htdocs/core/tpl/notes.tpl.php index 1fb10e66fda..e0acf0489e8 100644 --- a/htdocs/core/tpl/notes.tpl.php +++ b/htdocs/core/tpl/notes.tpl.php @@ -1,5 +1,6 @@ + * Copyright (C) 2013 Florian Henry * * 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 @@ -18,19 +19,21 @@ $module = $object->element; $note_public = 'note_public'; -$note_private = 'note'; +$note_private = 'note_private'; $colwidth=(isset($colwidth)?$colwidth:25); $permission=(isset($permission)?$permission:(isset($user->rights->$module->creer)?$user->rights->$module->creer:0)); // If already defined by caller page $moreparam=(isset($moreparam)?$moreparam:''); // Special cases -if ($module == 'propal') { $permission=$user->rights->propale->creer; } -elseif ($module == 'fichinter') { $permission=$user->rights->ficheinter->creer; $note_private = 'note_private'; } -elseif ($module == 'project') { $permission=$user->rights->projet->creer; $note_private = 'note_private'; } -elseif ($module == 'project_task') { $permission=$user->rights->projet->creer; $note_private = 'note_private'; } -elseif ($module == 'invoice_supplier') { $permission=$user->rights->fournisseur->facture->creer; } -elseif ($module == 'order_supplier') { $permission=$user->rights->fournisseur->commande->creer; } +if ($module == 'propal') { $permission=$user->rights->propale->creer;} +elseif ($module == 'fichinter') { $permission=$user->rights->ficheinter->creer;} +elseif ($module == 'project') { $permission=$user->rights->projet->creer;} +elseif ($module == 'project_task') { $permission=$user->rights->projet->creer;} +elseif ($module == 'invoice_supplier') { $permission=$user->rights->fournisseur->facture->creer;} +elseif ($module == 'order_supplier') { $permission=$user->rights->fournisseur->commande->creer;} +elseif ($module == 'societe') { $permission=$user->rights->societe->creer;} +elseif ($module == 'shipping') { $permission=$user->rights->expedition->creer;} if (! empty($conf->global->FCKEDITOR_ENABLE_SOCIETE)) $typeofdata='ckeditor:dolibarr_notes:100%:200::1:12:100'; else $typeofdata='textarea:12:100'; diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 9896eb50486..9a59d25d262 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2007 Franky Van Liedekerke * Copyright (C) 2006-2012 Laurent Destailleur * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -56,6 +57,8 @@ class Expedition extends CommonObject var $tracking_url; var $statut; var $billed; + var $note_public; + var $note_private; var $trueWeight; var $weight_units; @@ -191,6 +194,8 @@ class Expedition extends CommonObject $sql.= ", height"; $sql.= ", weight_units"; $sql.= ", size_units"; + $sql.= ", note_private"; + $sql.= ", note_public"; $sql.= ") VALUES ("; $sql.= "'(PROV)'"; $sql.= ", ".$conf->entity; @@ -210,6 +215,8 @@ class Expedition extends CommonObject $sql.= ", ".$this->sizeH; // TODO Should use this->trueHeight $sql.= ", ".$this->weight_units; $sql.= ", ".$this->size_units; + $sql.= ", ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null"); $sql.= ")"; $resql=$this->db->query($sql); @@ -341,6 +348,7 @@ class Expedition extends CommonObject $sql.= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery"; $sql.= ", e.fk_expedition_methode, e.tracking_number"; $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; + $sql.= ", e.note_private, e.note_public"; $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->element."'"; $sql.= " WHERE e.entity = ".$conf->entity; @@ -387,6 +395,9 @@ class Expedition extends CommonObject $this->height_units = $obj->size_units; $this->trueDepth = $obj->size; $this->depth_units = $obj->size_units; + + $this->note_public = $obj->note_public; + $this->note_private = $obj->note_private; // A denormalized value $this->trueSize = $obj->size."x".$obj->width."x".$obj->height; @@ -690,7 +701,8 @@ class Expedition extends CommonObject if (isset($this->size_units)) $this->size_units=trim($this->size_units); if (isset($this->weight_units)) $this->weight_units=trim($this->weight_units); if (isset($this->trueWeight)) $this->weight=trim($this->trueWeight); - if (isset($this->note)) $this->note=trim($this->note); + if (isset($this->note_private)) $this->note=trim($this->note_private); + if (isset($this->note_public)) $this->note=trim($this->note_public); if (isset($this->model_pdf)) $this->model_pdf=trim($this->model_pdf); @@ -721,7 +733,8 @@ class Expedition extends CommonObject $sql.= " size=".(($this->trueDepth != '')?$this->trueDepth:"null").","; $sql.= " weight_units=".(isset($this->weight_units)?$this->weight_units:"null").","; $sql.= " weight=".(($this->trueWeight != '')?$this->trueWeight:"null").","; - $sql.= " note=".(isset($this->note)?"'".$this->db->escape($this->note)."'":"null").","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; + $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; $sql.= " model_pdf=".(isset($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null").","; $sql.= " entity=".$conf->entity; @@ -1093,6 +1106,9 @@ class Expedition extends CommonObject $this->origin_id = 1; $this->origin = 'commande'; + + $this->note_private = 'Private note'; + $this->note_public = 'Public note'; $nbp = 5; $xnbp = 0; diff --git a/htdocs/expedition/fiche.php b/htdocs/expedition/fiche.php index 390e4081066..51d19ff2fa6 100644 --- a/htdocs/expedition/fiche.php +++ b/htdocs/expedition/fiche.php @@ -4,6 +4,7 @@ * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -32,6 +33,7 @@ require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/modules/expedition/modules_expedition.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; if (! empty($conf->product->enabled) || ! empty($conf->service->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (! empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; if (! empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; @@ -107,6 +109,8 @@ if ($action == 'add') $object->shipping_method_id = GETPOST('shipping_method_id','int'); $object->tracking_number = GETPOST('tracking_number','alpha'); $object->ref_int = GETPOST('ref_int','alpha'); + $object->note_private = GETPOST('note_private'); + $object->note_public = GETPOST('note_public'); $num=count($objectsrc->lines); $totalqty=0; @@ -629,12 +633,22 @@ if ($action == 'create') print $form->select_date($object->date_livraison?$object->date_livraison:-1,'date_delivery',1,1); print "\n"; print ''; + + // Note Public + print ''.$langs->trans("NotePublic").''; + print ''; + $doleditor = new DolEditor('note_public', $object->note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + print ""; - // Note - if ($object->note && ! $user->societe_id) + // Note Private + if ($object->note_private && ! $user->societe_id) { print ''.$langs->trans("NotePrivate").''; - print ''.nl2br($object->note).""; + print ''; + $doleditor = new DolEditor('note_private', $object->note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + print ""; } // Weight diff --git a/htdocs/expedition/note.php b/htdocs/expedition/note.php new file mode 100644 index 00000000000..17613c72b58 --- /dev/null +++ b/htdocs/expedition/note.php @@ -0,0 +1,160 @@ + + * Copyright (C) 2004-2008 Laurent Destailleur +* Copyright (C) 2005-2012 Regis Houssin +* Copyright (C) 2013 Florian Henry +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +/** + * \file htdocs/expedition/note.php +* \ingroup expedition +* \brief Note card expedition +*/ + +error_reporting(E_ALL); +ini_set('display_errors', true); +ini_set('html_errors', false); + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/sendings.lib.php'; + +$langs->load("sendings"); +$langs->load("companies"); +$langs->load("bills"); +$langs->load('deliveries'); +$langs->load('orders'); +$langs->load('stocks'); +$langs->load('other'); +$langs->load('propal'); + +$id=(GETPOST('id','int')?GETPOST('id','int'):GETPOST('facid','int')); // For backward compatibility +$ref=GETPOST('ref','alpha'); +$action=GETPOST('action','alpha'); + +// Security check +$socid=''; +if ($user->societe_id) $socid=$user->societe_id; +$result=restrictedArea($user, $origin, $origin_id); + +$object = new Expedition($db); +$object->fetch($id); + + +/******************************************************************************/ +/* Actions */ +/******************************************************************************/ + +if ($action == 'setnote_public' && $user->rights->facture->creer) +{ + $object->fetch($id); + $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + if ($result < 0) dol_print_error($db,$object->error); +} + +else if ($action == 'setnote_private' && $user->rights->facture->creer) +{ + $object->fetch($id); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + if ($result < 0) dol_print_error($db,$object->error); +} + + +/******************************************************************************/ +/* Affichage fiche */ +/******************************************************************************/ + +llxHeader(); + +$form = new Form($db); + +if ($id > 0 || ! empty($ref)) +{ + + $soc = new Societe($db); + $soc->fetch($object->socid); + + $head=shipping_prepare_head($object); + dol_fiche_head($head, 'note', $langs->trans("Sending"), 0, 'sending'); + + print ''; + + $linkback = ''.$langs->trans("BackToList").''; + + // Ref + print ''; + print ''; + + // Customer + print ''; + print ''; + print ""; + + // Linked documents + if ($typeobject == 'commande' && $object->$typeobject->id && ! empty($conf->commande->enabled)) + { + print ''; + print '\n"; + print ''; + } + if ($typeobject == 'propal' && $object->$typeobject->id && ! empty($conf->propal->enabled)) + { + print ''; + print '\n"; + print ''; + } + + // Ref customer + print ''; + print '\n"; + print ''; + + // Date creation + print ''; + print '\n"; + print ''; + + // Delivery date planed + print ''; + print '\n"; + print ''; + + print '
'.$langs->trans("Ref").''; + print $form->showrefnav($object, 'ref', $linkback, 1, 'ref', 'ref'); + print '
'.$langs->trans("Customer").''.$soc->getNomUrl(1).'
'; + $objectsrc=new Commande($db); + $objectsrc->fetch($object->$typeobject->id); + print $langs->trans("RefOrder").''; + print $objectsrc->getNomUrl(1,'commande'); + print "
'; + $objectsrc=new Propal($db); + $objectsrc->fetch($object->$typeobject->id); + print $langs->trans("RefProposal").''; + print $objectsrc->getNomUrl(1,'expedition'); + print "
'.$langs->trans("RefCustomer").''.$object->ref_customer."
'.$langs->trans("DateCreation").''.dol_print_date($object->date_creation,"day")."
'.$langs->trans("DateDeliveryPlanned").''.dol_print_date($object->date_delivery,"dayhourtext")."
'; + + print '
'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + + dol_fiche_end(); +} + + +llxFooter(); + +$db->close(); +?> diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php index e355ebd0c96..3886edb30f9 100644 --- a/htdocs/fichinter/fiche.php +++ b/htdocs/fichinter/fiche.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2012 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2011-2013 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -39,6 +40,7 @@ if (! empty($conf->global->FICHEINTER_ADDON) && is_readable(DOL_DOCUMENT_ROOT ." { require_once DOL_DOCUMENT_ROOT ."/core/modules/fichinter/mod_".$conf->global->FICHEINTER_ADDON.'.php'; } +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $langs->load("companies"); $langs->load("interventions"); @@ -977,16 +979,20 @@ if ($action == 'create') print ''; print ''.$langs->trans('NotePublic').''; print ''; - print ''; + $doleditor = new DolEditor('note_public', $note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print ''; print ''; // Private note - if (! $user->societe_id) + if (!empty($user->societe_id)) { print ''; print ''.$langs->trans('NotePrivate').''; print ''; - print ''; + $doleditor = new DolEditor('note_private', $note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + //print ''; print ''; } diff --git a/htdocs/fichinter/note.php b/htdocs/fichinter/note.php index 054933139d8..a2de821e6c7 100644 --- a/htdocs/fichinter/note.php +++ b/htdocs/fichinter/note.php @@ -1,6 +1,7 @@ * Copyright (C) 2011-2012 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -53,7 +54,7 @@ if ($action == 'setnote_public' && $user->rights->ficheinter->creer) else if ($action == 'setnote_private' && $user->rights->ficheinter->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 99a443c71db..90e5afa1726 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2010-2013 Philippe Grand * Copyright (C) 2012 Marcos García + * Copyright (C) 2013 Florian Henry * * 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 @@ -121,7 +122,7 @@ class CommandeFournisseur extends CommonOrder $sql.= " c.date_creation, c.date_valid, c.date_approve,"; $sql.= " c.fk_user_author, c.fk_user_valid, c.fk_user_approve,"; $sql.= " c.date_commande as date_commande, c.date_livraison as date_livraison, c.fk_cond_reglement, c.fk_mode_reglement, c.fk_projet as fk_project, c.remise_percent, c.source, c.fk_input_method,"; - $sql.= " c.note as note_private, c.note_public, c.model_pdf, c.extraparams,"; + $sql.= " c.note_private, c.note_public, c.model_pdf, c.extraparams,"; $sql.= " cm.libelle as methode_commande,"; $sql.= " cr.code as cond_reglement_code, cr.libelle as cond_reglement_libelle,"; $sql.= " p.code as mode_reglement_code, p.libelle as mode_reglement_libelle"; @@ -927,7 +928,7 @@ class CommandeFournisseur extends CommonOrder $sql = "INSERT INTO ".MAIN_DB_PREFIX."commande_fournisseur ("; $sql.= "ref"; $sql.= ", ref_supplier"; - $sql.= ", note"; + $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", entity"; $sql.= ", fk_soc"; @@ -942,7 +943,7 @@ class CommandeFournisseur extends CommonOrder $sql.= " VALUES ("; $sql.= "''"; $sql.= ", '".$this->ref_supplier."'"; - $sql.= ", '".$this->note."'"; + $sql.= ", '".$this->note_private."'"; $sql.= ", '".$this->note_public."'"; $sql.= ", ".$conf->entity; $sql.= ", ".$this->socid; @@ -1874,7 +1875,7 @@ class CommandeFournisseur extends CommonOrder $this->cond_reglement_code = 'RECEP'; $this->mode_reglement_code = 'CHQ'; $this->note_public='This is a comment (public)'; - $this->note='This is a comment (private)'; + $this->note_private='This is a comment (private)'; // Lines $nbp = 5; $xnbp = 0; diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index e1d084939ac..d3c7d12d98a 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -6,6 +6,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010-2011 Juanjo Menent * Copyright (C) 2013 Philippe Grand + * Copyright (C) 2013 Florian Henry * * 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 @@ -140,7 +141,7 @@ class FactureFournisseur extends CommonInvoice $sql.= ", fk_soc"; $sql.= ", datec"; $sql.= ", datef"; - $sql.= ", note"; + $sql.= ", note_private"; $sql.= ", note_public"; $sql.= ", fk_user_author"; $sql.= ", date_lim_reglement"; @@ -153,7 +154,7 @@ class FactureFournisseur extends CommonInvoice $sql.= ", ".$this->socid; $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", '".$this->db->idate($this->date)."'"; - $sql.= ", '".$this->db->escape($this->note)."'"; + $sql.= ", '".$this->db->escape($this->note_private)."'"; $sql.= ", '".$this->db->escape($this->note_public)."'"; $sql.= ", ".$user->id.","; $sql.= $this->date_echeance!=''?"'".$this->db->idate($this->date_echeance)."'":"null"; @@ -297,7 +298,7 @@ class FactureFournisseur extends CommonInvoice $sql.= " t.fk_projet,"; $sql.= " t.fk_cond_reglement,"; $sql.= " t.date_lim_reglement,"; - $sql.= " t.note as note_private,"; + $sql.= " t.note_private,"; $sql.= " t.note_public,"; $sql.= " t.model_pdf,"; $sql.= " t.import_key,"; @@ -496,7 +497,7 @@ class FactureFournisseur extends CommonInvoice if (isset($this->fk_facture_source)) $this->fk_facture_source=trim($this->fk_facture_source); if (isset($this->fk_project)) $this->fk_project=trim($this->fk_project); if (isset($this->fk_cond_reglement)) $this->fk_cond_reglement=trim($this->fk_cond_reglement); - if (isset($this->note)) $this->note=trim($this->note); + if (isset($this->note_private)) $this->note=trim($this->note_private); if (isset($this->note_public)) $this->note_public=trim($this->note_public); if (isset($this->model_pdf)) $this->model_pdf=trim($this->model_pdf); if (isset($this->import_key)) $this->import_key=trim($this->import_key); @@ -535,7 +536,7 @@ class FactureFournisseur extends CommonInvoice $sql.= " fk_projet=".(isset($this->fk_project)?$this->fk_project:"null").","; $sql.= " fk_cond_reglement=".(isset($this->fk_cond_reglement)?$this->fk_cond_reglement:"null").","; $sql.= " date_lim_reglement=".(dol_strlen($this->date_echeance)!=0 ? "'".$this->db->idate($this->date_echeance)."'" : 'null').","; - $sql.= " note=".(isset($this->note)?"'".$this->db->escape($this->note)."'":"null").","; + $sql.= " note_private=".(isset($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null").","; $sql.= " note_public=".(isset($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null").","; $sql.= " model_pdf=".(isset($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null").","; $sql.= " import_key=".(isset($this->import_key)?"'".$this->db->escape($this->import_key)."'":"null").""; @@ -1433,7 +1434,7 @@ class FactureFournisseur extends CommonInvoice $this->cond_reglement_code = 'RECEP'; $this->mode_reglement_code = 'CHQ'; $this->note_public='This is a comment (public)'; - $this->note='This is a comment (private)'; + $this->note_private='This is a comment (private)'; // Lines $nbp = 5; $xnbp = 0; diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php index 6ba577c152b..7a5128cca45 100644 --- a/htdocs/fourn/commande/fiche.php +++ b/htdocs/fourn/commande/fiche.php @@ -6,6 +6,7 @@ * Copyright (C) 2010-2013 Juanjo Menent * Copyright (C) 2011 Philippe Grand * Copyright (C) 2012 Marcos García + * Copyright (C) 2013 Florian Henry * * 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 @@ -37,6 +38,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; if (!empty($conf->produit->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (!empty($conf->projet->enabled)) @@ -142,9 +144,9 @@ else if ($action == 'setnote_public' && $user->rights->fournisseur->commande->cr if ($result < 0) dol_print_error($db,$object->error); } -else if ($action == 'setnote' && $user->rights->fournisseur->commande->creer) +else if ($action == 'setnote_private' && $user->rights->fournisseur->commande->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } @@ -675,7 +677,7 @@ else if ($action == 'add' && $user->rights->fournisseur->commande->creer) // Creation commande $object->ref_supplier = GETPOST('refsupplier'); $object->socid = $socid; - $object->note = GETPOST('note'); + $object->note_private = GETPOST('note_private'); $object->note_public = GETPOST('note_public'); $id = $object->create($user); @@ -997,15 +999,25 @@ if ($action=="create") print ''; print ''; - - print ''.$langs->trans('Note').''; - print ''; - print ''; - + print ''.$langs->trans('NotePublic').''; - print ''; + print ''; + $doleditor = new DolEditor('note_public', GETPOST('note_public'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + print ''; + //print ''; print ''; + print ''.$langs->trans('NotePrivate').''; + print ''; + $doleditor = new DolEditor('note_private', GETPOST('note_private'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + print ''; + //print ''; + print ''; + + + // Other options $parameters=array(); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook @@ -1504,9 +1516,7 @@ elseif (! empty($object->id)) $parameters=array('fk_parent_line'=>$line->fk_parent_line, 'line'=>$line,'var'=>$var,'num'=>$num,'i'=>$i); $reshook=$hookmanager->executeHooks('formEditProductOptions',$parameters,$object,$action); } - - // Description - Editor wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $nbrows=ROWS_2; if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; $doleditor=new DolEditor('eldesc',$line->description,'',200,'dolibarr_details','',false,true,$conf->global->FCKEDITOR_ENABLE_DETAILS,$nbrows,70); @@ -1532,8 +1542,6 @@ elseif (! empty($object->id)) */ if ($object->statut == 0 && $user->rights->fournisseur->commande->creer && $action <> 'editline') { - //WYSIWYG Editor - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; print ''; print ''; diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index e1ff199de6d..4393023f07c 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -6,6 +6,7 @@ * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2010-2012 Juanjo Menent * Copyright (C) 2013 Philippe Grand + * Copyright (C) 2013 Florian Henry * * 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 @@ -35,6 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/paiementfourn.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; if (!empty($conf->produit->enabled)) require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; if (!empty($conf->projet->enabled)) @@ -212,10 +214,10 @@ elseif ($action == 'setnote_public' && $user->rights->fournisseur->facture->cree $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } -elseif ($action == 'setnote' && $user->rights->fournisseur->facture->creer) +elseif ($action == 'setnote_private' && $user->rights->fournisseur->facture->creer) { $object->fetch($id); - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); if ($result < 0) dol_print_error($db,$object->error); } @@ -273,7 +275,8 @@ elseif ($action == 'add' && $user->rights->fournisseur->facture->creer) $object->libelle = $_POST['libelle']; $object->date = $datefacture; $object->date_echeance = $datedue; - $object->note_public = $_POST['note']; + $object->note_public = GETPOST('note_public'); + $object->note_private = GETPOST('note_private'); // If creation from another object of another module if ($_POST['origin'] && $_POST['originid']) @@ -1152,7 +1155,20 @@ if ($action == 'create') print ''; print ''.$langs->trans('NotePublic').''; - print ''; + print ''; + $doleditor = new DolEditor('note_public', GETPOST('note_public'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + print ''; + // print ''; + print ''; + + // Private note + print ''.$langs->trans('NotePrivate').''; + print ''; + $doleditor = new DolEditor('note_private', GETPOST('note_private'), '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1); + print ''; + // print ''; print ''; if (is_object($objectsrc)) @@ -1702,8 +1718,6 @@ else $reshook=$hookmanager->executeHooks('formEditProductOptions',$parameters,$object,$action); } - // Description - Editor wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $nbrows=ROWS_2; if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; $doleditor=new DolEditor('desc',$object->lines[$i]->description,'',128,'dolibarr_details','',false,true,$conf->global->FCKEDITOR_ENABLE_DETAILS,$nbrows,70); @@ -1849,8 +1863,6 @@ else $reshook=$hookmanager->executeHooks('formCreateSupplierProductOptions',$parameters,$object,$action); } - // Editor wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; $nbrows=ROWS_2; if (! empty($conf->global->MAIN_INPUT_DESC_HEIGHT)) $nbrows=$conf->global->MAIN_INPUT_DESC_HEIGHT; $doleditor=new DolEditor('dp_desc',GETPOST("dp_desc"),'',100,'dolibarr_details','',false,true,$conf->global->FCKEDITOR_ENABLE_DETAILS,$nbrows,70); diff --git a/htdocs/fourn/facture/note.php b/htdocs/fourn/facture/note.php index bbdd1b5f60f..834858788e9 100644 --- a/htdocs/fourn/facture/note.php +++ b/htdocs/fourn/facture/note.php @@ -2,26 +2,27 @@ /* Copyright (C) 2004 Rodolphe Quiedeville * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin -* -* 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 . + * Copyright (C) 2013 Florian Henry + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ /** * \file htdocs/fourn/facture/note.php * \ingroup facture - * \brief Fiche de notes sur une facture fournisseur - */ +* \brief Fiche de notes sur une facture fournisseur +*/ require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; @@ -50,21 +51,21 @@ $object->fetch($id,$ref); if ($action == 'setnote_public' && $user->rights->fournisseur->facture->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); - if ($result < 0) dol_print_error($db,$object->error); + $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + if ($result < 0) dol_print_error($db,$object->error); } -elseif ($action == 'setnote' && $user->rights->fournisseur->facture->creer) +elseif ($action == 'setnote_private' && $user->rights->fournisseur->facture->creer) { - $result=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); - if ($result < 0) dol_print_error($db,$object->error); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + if ($result < 0) dol_print_error($db,$object->error); } // Set label if ($action == 'setlabel' && $user->rights->fournisseur->facture->creer) { - $object->label=$_POST['label']; - $result=$object->update($user); - if ($result < 0) dol_print_error($db); + $object->label=$_POST['label']; + $result=$object->update($user); + if ($result < 0) dol_print_error($db); } @@ -78,82 +79,82 @@ llxHeader(); if ($id) { - $object->fetch_thirdparty(); + $object->fetch_thirdparty(); - $head = facturefourn_prepare_head($object); - $titre=$langs->trans('SupplierInvoice'); - dol_fiche_head($head, 'note', $titre, 0, 'bill'); + $head = facturefourn_prepare_head($object); + $titre=$langs->trans('SupplierInvoice'); + dol_fiche_head($head, 'note', $titre, 0, 'bill'); - print ''; + print '
'; - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; - // Ref - print ''; - print "\n"; + // Ref + print ''; + print "\n"; - // Ref supplier - print ''; - print "\n"; + // Ref supplier + print ''; + print "\n"; - // Company - print ''; + // Company + print ''; - // Type - print ''; + $facidavoir=$object->getListIdAvoirFromInvoice(); + if (count($facidavoir) > 0) + { + print ' ('.$langs->transnoentities("InvoiceHasAvoir"); + $i=0; + foreach($facidavoir as $fid) + { + if ($i==0) print ' '; + else print ','; + $facavoir=new FactureFournisseur($db); + $facavoir->fetch($fid); + print $facavoir->getNomUrl(1); + } + print ')'; + } + if ($facidnext > 0) + { + $facthatreplace=new FactureFournisseur($db); + $facthatreplace->fetch($facidnext); + print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; + } + print ''; - // Label - print ''; + // Label + print ''; - print "
'.$langs->trans("Ref").''; - print $form->showrefnav($object, 'facid', $linkback, 1, 'rowid', 'ref', $morehtmlref); - print '
'.$langs->trans("Ref").''; + print $form->showrefnav($object, 'facid', $linkback, 1, 'rowid', 'ref', $morehtmlref); + print '
'.$langs->trans("RefSupplier").''.$object->ref_supplier.'
'.$langs->trans("RefSupplier").''.$object->ref_supplier.'
'.$langs->trans('Supplier').''.$object->thirdparty->getNomUrl(1).'
'.$langs->trans('Supplier').''.$object->thirdparty->getNomUrl(1).'
'.$langs->trans('Type').''; - print $object->getLibType(); - if ($object->type == 1) - { - $facreplaced=new FactureFournisseur($db); - $facreplaced->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; - } - if ($object->type == 2) - { - $facusing=new FactureFournisseur($db); - $facusing->fetch($object->fk_facture_source); - print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; - } + // Type + print '
'.$langs->trans('Type').''; + print $object->getLibType(); + if ($object->type == 1) + { + $facreplaced=new FactureFournisseur($db); + $facreplaced->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("ReplaceInvoice",$facreplaced->getNomUrl(1)).')'; + } + if ($object->type == 2) + { + $facusing=new FactureFournisseur($db); + $facusing->fetch($object->fk_facture_source); + print ' ('.$langs->transnoentities("CorrectInvoice",$facusing->getNomUrl(1)).')'; + } - $facidavoir=$object->getListIdAvoirFromInvoice(); - if (count($facidavoir) > 0) - { - print ' ('.$langs->transnoentities("InvoiceHasAvoir"); - $i=0; - foreach($facidavoir as $fid) - { - if ($i==0) print ' '; - else print ','; - $facavoir=new FactureFournisseur($db); - $facavoir->fetch($fid); - print $facavoir->getNomUrl(1); - } - print ')'; - } - if ($facidnext > 0) - { - $facthatreplace=new FactureFournisseur($db); - $facthatreplace->fetch($facidnext); - print ' ('.$langs->transnoentities("ReplacedByInvoice",$facthatreplace->getNomUrl(1)).')'; - } - print '
'.$form->editfieldkey("Label",'label',$object->label,$object,0).''; - print $form->editfieldval("Label",'label',$object->label,$object,0); - print '
'.$form->editfieldkey("Label",'label',$object->label,$object,0).''; + print $form->editfieldval("Label",'label',$object->label,$object,0); + print '
"; + print ""; - print '
'; + print '
'; - $colwidth=20; - include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + $colwidth=20; + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; - dol_fiche_end(); + dol_fiche_end(); } diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 8dfaf85ac71..a861496cb72 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -2,6 +2,7 @@ /* Copyright (C) 2011 Dimitri Mouillard * Copyright (C) 2012 Laurent Destailleur * Copyright (C) 2012 Regis Houssin + * Copyright (C) 2013 Florian Henry * * 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 @@ -192,7 +193,7 @@ class Holiday extends CommonObject $sql.= " cp.date_cancel,"; $sql.= " cp.fk_user_cancel,"; $sql.= " cp.detail_refuse,"; - $sql.= " cp.note,"; + $sql.= " cp.note_private,"; $sql.= " cp.note_public"; $sql.= " FROM ".MAIN_DB_PREFIX."holiday as cp"; $sql.= " WHERE cp.rowid = ".$id; @@ -223,7 +224,7 @@ class Holiday extends CommonObject $this->date_cancel = $this->db->jdate($obj->date_cancel); $this->fk_user_cancel = $obj->fk_user_cancel; $this->detail_refuse = $obj->detail_refuse; - $this->note = $obj->note; + $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; } $this->db->free($resql); diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index fef019afd87..b2be5f7fa14 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -243,3 +243,19 @@ ALTER TABLE llx_facture_fourn_det ADD COLUMN info_bits integer NOT NULL DEFAULT ALTER TABLE llx_actioncomm ADD COLUMN transparency integer after fk_user_action; INSERT INTO llx_c_action_trigger (rowid,code,label,description,elementtype,rang) VALUES (29,'FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',29); + +ALTER TABLE llx_expedition CHANGE COLUMN note note_private text; +ALTER TABLE llx_expedition ADD COLUMN note_public text after note_private; +ALTER TABLE llx_livraison CHANGE COLUMN note note_private text; +ALTER TABLE llx_facture CHANGE COLUMN note note_private text; +ALTER TABLE llx_commande CHANGE COLUMN note note_private text; +ALTER TABLE llx_propal CHANGE COLUMN note note_private text; +ALTER TABLE llx_commande_fournisseur CHANGE COLUMN note note_private text; +ALTER TABLE llx_contrat CHANGE COLUMN note note_private text; +ALTER TABLE llx_deplacement CHANGE COLUMN note note_private text; +ALTER TABLE llx_don CHANGE COLUMN note note_private text; +ALTER TABLE llx_facture_fourn CHANGE COLUMN note note_private text; +ALTER TABLE llx_facture_rec CHANGE COLUMN note note_private text; +ALTER TABLE llx_holiday CHANGE COLUMN note note_private text; +ALTER TABLE llx_societe CHANGE COLUMN note note_private text; +ALTER TABLE llx_socpeople CHANGE COLUMN note note_private text; diff --git a/htdocs/install/mysql/tables/llx_commande.sql b/htdocs/install/mysql/tables/llx_commande.sql index 0ef0eddb739..325b1f3fe13 100644 --- a/htdocs/install/mysql/tables/llx_commande.sql +++ b/htdocs/install/mysql/tables/llx_commande.sql @@ -50,7 +50,7 @@ create table llx_commande localtax2 double(24,8) default 0, -- total localtax2 total_ht double(24,8) default 0, total_ttc double(24,8) default 0, - note text, + note_private text, note_public text, model_pdf varchar(255), diff --git a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql index ac9e49d604f..51e57452397 100644 --- a/htdocs/install/mysql/tables/llx_commande_fournisseur.sql +++ b/htdocs/install/mysql/tables/llx_commande_fournisseur.sql @@ -50,7 +50,7 @@ create table llx_commande_fournisseur localtax2 double(24,8) default 0, total_ht double(24,8) default 0, total_ttc double(24,8) default 0, - note text, + note_private text, note_public text, model_pdf varchar(255), @@ -61,4 +61,4 @@ create table llx_commande_fournisseur import_key varchar(14), extraparams varchar(255) -- for stock other parameters with json format -)ENGINE=innodb; \ No newline at end of file +)ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_contrat.sql b/htdocs/install/mysql/tables/llx_contrat.sql index e952c8eb073..7521eb0aa1b 100644 --- a/htdocs/install/mysql/tables/llx_contrat.sql +++ b/htdocs/install/mysql/tables/llx_contrat.sql @@ -37,7 +37,7 @@ create table llx_contrat fk_user_author integer NOT NULL default 0, fk_user_mise_en_service integer, fk_user_cloture integer, - note text, + note_private text, note_public text, import_key varchar(14), extraparams varchar(255) -- for stock other parameters with json format diff --git a/htdocs/install/mysql/tables/llx_deplacement.sql b/htdocs/install/mysql/tables/llx_deplacement.sql index acf774f41ec..34c4ab103cd 100644 --- a/htdocs/install/mysql/tables/llx_deplacement.sql +++ b/htdocs/install/mysql/tables/llx_deplacement.sql @@ -34,7 +34,7 @@ create table llx_deplacement km real, fk_soc integer, fk_projet integer DEFAULT 0, - note text, + note_private text, note_public text, extraparams varchar(255) -- for stock other parameters with json format diff --git a/htdocs/install/mysql/tables/llx_don.sql b/htdocs/install/mysql/tables/llx_don.sql index 40ab90eab80..259cac22966 100644 --- a/htdocs/install/mysql/tables/llx_don.sql +++ b/htdocs/install/mysql/tables/llx_don.sql @@ -44,7 +44,7 @@ create table llx_don fk_don_projet integer NULL, -- projet auquel est fait le don fk_user_author integer NOT NULL, fk_user_valid integer NULL, - note text, + note_private text, note_public text, model_pdf varchar(255), import_key varchar(14) diff --git a/htdocs/install/mysql/tables/llx_expedition.sql b/htdocs/install/mysql/tables/llx_expedition.sql index ef30ce38f7a..6e7bccf08e3 100644 --- a/htdocs/install/mysql/tables/llx_expedition.sql +++ b/htdocs/install/mysql/tables/llx_expedition.sql @@ -48,7 +48,8 @@ create table llx_expedition size integer, -- depth weight_units integer, -- unit of weight weight integer, -- weight - note text, + note_private text, + note_public text, model_pdf varchar(255) )ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_facture.sql b/htdocs/install/mysql/tables/llx_facture.sql index a9046b49065..62ea8936e90 100644 --- a/htdocs/install/mysql/tables/llx_facture.sql +++ b/htdocs/install/mysql/tables/llx_facture.sql @@ -68,7 +68,7 @@ create table llx_facture fk_mode_reglement integer, -- mode de reglement (Virement, Prelevement) date_lim_reglement date, -- date limite de reglement - note text, + note_private text, note_public text, model_pdf varchar(255), import_key varchar(14), diff --git a/htdocs/install/mysql/tables/llx_facture_fourn.sql b/htdocs/install/mysql/tables/llx_facture_fourn.sql index 372004c4477..c2d26a9c7cb 100644 --- a/htdocs/install/mysql/tables/llx_facture_fourn.sql +++ b/htdocs/install/mysql/tables/llx_facture_fourn.sql @@ -61,7 +61,7 @@ create table llx_facture_fourn fk_cond_reglement integer DEFAULT 1 NOT NULL, -- condition de reglement (30 jours, fin de mois ...) date_lim_reglement date, -- date limite de reglement - note text, + note_private text, note_public text, model_pdf varchar(255), import_key varchar(14), diff --git a/htdocs/install/mysql/tables/llx_facture_rec.sql b/htdocs/install/mysql/tables/llx_facture_rec.sql index 8283de388dc..0a935a3623d 100644 --- a/htdocs/install/mysql/tables/llx_facture_rec.sql +++ b/htdocs/install/mysql/tables/llx_facture_rec.sql @@ -43,7 +43,7 @@ create table llx_facture_rec fk_mode_reglement integer DEFAULT 0, -- mode de reglement (Virement, Prelevement) date_lim_reglement date, -- date limite de reglement - note text, + note_private text, note_public text, usenewprice integer, diff --git a/htdocs/install/mysql/tables/llx_holiday.sql b/htdocs/install/mysql/tables/llx_holiday.sql index c83590c84c7..582b00034ff 100644 --- a/htdocs/install/mysql/tables/llx_holiday.sql +++ b/htdocs/install/mysql/tables/llx_holiday.sql @@ -34,7 +34,7 @@ fk_user_refuse integer DEFAULT NULL, date_cancel DATETIME DEFAULT NULL, fk_user_cancel integer DEFAULT NULL, detail_refuse varchar( 250 ) DEFAULT NULL, -note text, +note_private text, note_public text ) -ENGINE=innodb; \ No newline at end of file +ENGINE=innodb; diff --git a/htdocs/install/mysql/tables/llx_livraison.sql b/htdocs/install/mysql/tables/llx_livraison.sql index 780e2f50633..a940e191199 100644 --- a/htdocs/install/mysql/tables/llx_livraison.sql +++ b/htdocs/install/mysql/tables/llx_livraison.sql @@ -37,7 +37,7 @@ create table llx_livraison fk_address integer, -- delivery address (deprecated) fk_statut smallint DEFAULT 0, total_ht double(24,8) DEFAULT 0, - note text, + note_private text, note_public text, model_pdf varchar(255) diff --git a/htdocs/install/mysql/tables/llx_propal.sql b/htdocs/install/mysql/tables/llx_propal.sql index 2964e768e47..3155eed6370 100644 --- a/htdocs/install/mysql/tables/llx_propal.sql +++ b/htdocs/install/mysql/tables/llx_propal.sql @@ -57,7 +57,7 @@ create table llx_propal fk_cond_reglement integer, -- condition de reglement (30 jours, fin de mois ...) fk_mode_reglement integer, -- mode de reglement (Virement, Prelevement) - note text, + note_private text, note_public text, model_pdf varchar(255), date_livraison date DEFAULT NULL, -- delivery date diff --git a/htdocs/install/mysql/tables/llx_societe.sql b/htdocs/install/mysql/tables/llx_societe.sql index b0d601fff47..95ceadec503 100644 --- a/htdocs/install/mysql/tables/llx_societe.sql +++ b/htdocs/install/mysql/tables/llx_societe.sql @@ -62,7 +62,7 @@ create table llx_societe tva_intra varchar(20), -- tva capital real, -- capital de la societe fk_stcomm integer DEFAULT 0 NOT NULL, -- commercial statut - note text, -- + note_private text, -- note_public text, -- prefix_comm varchar(5), -- prefix commercial client tinyint DEFAULT 0, -- client 0/1/2 diff --git a/htdocs/install/mysql/tables/llx_socpeople.sql b/htdocs/install/mysql/tables/llx_socpeople.sql index 921580394a8..d06e91e5395 100644 --- a/htdocs/install/mysql/tables/llx_socpeople.sql +++ b/htdocs/install/mysql/tables/llx_socpeople.sql @@ -46,7 +46,7 @@ create table llx_socpeople priv smallint NOT NULL DEFAULT 0, fk_user_creat integer DEFAULT 0, -- user qui a creel'enregistrement fk_user_modif integer, - note text, + note_private text, note_public text, default_lang varchar(6), canvas varchar(32), -- type of canvas if used (null by default) diff --git a/htdocs/livraison/class/livraison.class.php b/htdocs/livraison/class/livraison.class.php index d5dce8c6830..ea1962be34c 100644 --- a/htdocs/livraison/class/livraison.class.php +++ b/htdocs/livraison/class/livraison.class.php @@ -4,6 +4,7 @@ * Copyright (C) 2006-2007 Laurent Destailleur * Copyright (C) 2007 Franky Van Liedekerke * Copyright (C) 2011-2012 Philippe Grand + * Copyright (C) 2013 Florian Henry * * 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 @@ -49,6 +50,9 @@ class Livraison extends CommonObject var $socid; var $ref_customer; var $statut; + + var $note_public; + var $note_private; var $expedition_id; @@ -106,15 +110,19 @@ class Livraison extends CommonObject $sql.= ", fk_user_author"; $sql.= ", date_delivery"; $sql.= ", fk_address"; + $sql.= ", note_private"; + $sql.= ", note_public"; $sql.= ") VALUES ("; $sql.= "'(PROV)'"; $sql.= ", ".$conf->entity; $sql.= ", ".$this->socid; - $sql.= ", '".$this->ref_customer."'"; + $sql.= ", '".$this->db->escape($this->ref_customer)."'"; $sql.= ", ".$this->db->idate($now); $sql.= ", ".$user->id; $sql.= ", ".($this->date_delivery?"'".$this->db->idate($this->date_delivery)."'":"null"); $sql.= ", ".($this->fk_delivery_address > 0 ? $this->fk_delivery_address : "null"); + $sql.= ", ".(!empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null"); + $sql.= ", ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null"); $sql.= ")"; dol_syslog("Livraison::create sql=".$sql, LOG_DEBUG); @@ -253,7 +261,7 @@ class Livraison extends CommonObject global $conf; $sql = "SELECT l.rowid, l.fk_soc, l.date_creation, l.date_valid, l.ref, l.ref_customer, l.fk_user_author,"; - $sql.=" l.total_ht, l.fk_statut, l.fk_user_valid, l.note, l.note_public"; + $sql.=" l.total_ht, l.fk_statut, l.fk_user_valid, l.note_private, l.note_public"; $sql.= ", l.date_delivery, l.fk_address, l.model_pdf"; $sql.= ", el.fk_source as origin_id, el.sourcetype as origin"; $sql.= " FROM ".MAIN_DB_PREFIX."livraison as l"; @@ -279,7 +287,8 @@ class Livraison extends CommonObject $this->user_author_id = $obj->fk_user_author; $this->user_valid_id = $obj->fk_user_valid; $this->fk_delivery_address = $obj->fk_address; - $this->note = $obj->note; + $this->note = $obj->note_private; //TODO deprecated + $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->modelpdf = $obj->model_pdf; $this->origin = $obj->origin; // May be 'shipping' @@ -488,7 +497,8 @@ class Livraison extends CommonObject $this->origin = $expedition->element; $this->origin_id = $expedition->id; - $this->note = $expedition->note; + $this->note_private = $expedition->note_private; + $this->note_public = $expedition->note_public; $this->fk_project = $expedition->fk_project; $this->date_delivery = $expedition->date_delivery; $this->fk_delivery_address = $expedition->fk_delivery_address; @@ -792,7 +802,8 @@ class Livraison extends CommonObject $this->specimen=1; $this->socid = 1; $this->date_delivery = $now; - $this->note_public='SPECIMEN'; + $this->note_public='Pulbic note'; + $this->note_private='Private note'; $i=0; $line=new LivraisonLigne($this->db); diff --git a/htdocs/livraison/fiche.php b/htdocs/livraison/fiche.php index b3ae95fd512..2849daa9c67 100644 --- a/htdocs/livraison/fiche.php +++ b/htdocs/livraison/fiche.php @@ -4,6 +4,7 @@ * Copyright (C) 2005 Simon TOSSER * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2007 Franky Van Liedekerke + * Copyright (C) 2013 Florian Henry * * 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 @@ -446,7 +447,7 @@ else $delivery = new Livraison($db); $result = $delivery->fetch($id); $delivery->fetch_thirdparty(); - + $expedition=new Expedition($db); $result = $expedition->fetch($delivery->origin_id); $typeobject = $expedition->origin; @@ -537,6 +538,23 @@ else print ''.$langs->trans("DateReceived").''; print ''.dol_print_date($delivery->date_delivery,'daytext')."\n"; print ''; + + // Note Public + print ''.$langs->trans("NotePublic").''; + print ''; + print nl2br($delivery->note_public); + /*$doleditor = new DolEditor('note_public', $object->note_public, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1);*/ + print ""; + + // Note Private + print ''.$langs->trans("NotePrivate").''; + print ''; + print nl2br($delivery->note_private); + /*$doleditor = new DolEditor('note_pprivate', $object->note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); + print $doleditor->Create(1);*/ + print ""; + // Statut print ''.$langs->trans("Status").''; diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 97291206ad4..da5927128ae 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -7,6 +7,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2008 Patrick Raguin * Copyright (C) 2010-2011 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -118,7 +119,9 @@ class Societe extends CommonObject var $code_compta; var $code_compta_fournisseur; - var $note; + var $note; //TODO deprecated + var $note_private; + var $note_public; //! code statut prospect var $stcomm_id; var $statut_commercial; @@ -698,7 +701,7 @@ class Societe extends CommonObject $sql .= ', s.status'; $sql .= ', s.price_level'; $sql .= ', s.tms as date_update'; - $sql .= ', s.phone, s.fax, s.email, s.url, s.zip, s.town, s.note, s.client, s.fournisseur'; + $sql .= ', s.phone, s.fax, s.email, s.url, s.zip, s.town, s.note_private, s.note_public, s.client, s.fournisseur'; $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6'; $sql .= ', s.capital, s.tva_intra'; $sql .= ', s.fk_typent as typent_id'; @@ -832,7 +835,9 @@ class Societe extends CommonObject $this->client = $obj->client; $this->fournisseur = $obj->fournisseur; - $this->note = $obj->note; + $this->note = $obj->note_private; //TODO Deprecatedfor backward comtability + $this->note_private = $obj->note_private; + $this->note_public = $obj->note_public; $this->default_lang = $obj->default_lang; $this->logo = $obj->logo; @@ -2444,7 +2449,7 @@ class Societe extends CommonObject $this->zip=empty($conf->global->MAIN_INFO_SOCIETE_ZIP)?'':$conf->global->MAIN_INFO_SOCIETE_ZIP; $this->town=empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN; $this->state_id=empty($conf->global->MAIN_INFO_SOCIETE_DEPARTEMENT)?'':$conf->global->MAIN_INFO_SOCIETE_DEPARTEMENT; - $this->note=empty($conf->global->MAIN_INFO_SOCIETE_NOTE)?'':$conf->global->MAIN_INFO_SOCIETE_NOTE; + $this->note_private=empty($conf->global->MAIN_INFO_SOCIETE_NOTE)?'':$conf->global->MAIN_INFO_SOCIETE_NOTE; $this->nom=$this->name; // deprecated @@ -2541,7 +2546,7 @@ class Societe extends CommonObject $this->tva_assuj=1; $this->tva_intra='EU1234567'; $this->note_public='This is a comment (public)'; - $this->note='This is a comment (private)'; + $this->note_private='This is a comment (private)'; $this->idprof1='idprof1'; $this->idprof2='idprof2'; diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php index 01a43230f7f..0d09f21da25 100644 --- a/htdocs/societe/note.php +++ b/htdocs/societe/note.php @@ -3,6 +3,7 @@ * Copyright (C) 2004-2011 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2010 Juanjo Menent + * Copyright (C) 2013 Florian Henry * * 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 @@ -24,6 +25,10 @@ * \ingroup societe */ +error_reporting(E_ALL); +ini_set('display_errors', true); +ini_set('html_errors', false); + require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; @@ -32,39 +37,45 @@ $action = GETPOST('action'); $langs->load("companies"); // Security check -$socid = GETPOST('socid','int'); -if ($user->societe_id) $socid=$user->societe_id; -$result = restrictedArea($user, 'societe', $socid, '&societe'); +$id = GETPOST('id','int'); +if ($user->societe_id) $id=$user->societe_id; +$result = restrictedArea($user, 'societe', $id, '&societe'); $object = new Societe($db); -if ($socid > 0) $object->fetch($socid); +if ($id > 0) $object->fetch($id); /* * Actions */ -if ($action == 'add' && ! GETPOST('cancel')) +/******************************************************************************/ +/* Actions */ +/******************************************************************************/ + +if ($action == 'setnote_public' && $user->rights->propale->creer) { - $result=$object->update_note($_POST["note"]); - if ($result < 0) - { - $errors[]=$object->errors; - } + $object->fetch($id); + $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + if ($result < 0) setEventMessage($object->error,'errors'); } +else if ($action == 'setnote_private' && $user->rights->propale->creer) +{ + $object->fetch($id); + $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + if ($result < 0) setEventMessage($object->error,'errors'); +} /* * View */ -if ($conf->global->MAIN_DIRECTEDITMODE && $user->rights->societe->creer) $action='edit'; - $form = new Form($db); $help_url='EN:Module_Third_Parties|FR:Module_Tiers|ES:Empresas'; llxHeader('',$langs->trans("ThirdParty").' - '.$langs->trans("Notes"),$help_url); -if ($socid > 0) +if ($id > 0) { /* * Affichage onglets @@ -73,7 +84,6 @@ if ($socid > 0) $head = societe_prepare_head($object); - dol_fiche_head($head, 'note', $langs->trans("ThirdParty"),0,'company'); @@ -110,61 +120,17 @@ if ($socid > 0) print ''; } - print ''.$langs->trans("Note").''; - print ''; - if ($action == 'edit' && $user->rights->societe->creer) - { - print ''; - print ''; - - // Editeur wysiwyg - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note',$object->note,'',360,'dolibarr_notes','In',true,false,$conf->global->FCKEDITOR_ENABLE_SOCIETE,20,70); - $doleditor->Create(); - } - else - { - print dol_textishtml($object->note)?$object->note:dol_nl2br($object->note,1,true); - } - print ""; - print ""; - - if ($action == 'edit') - { - print '

'; - print ''; - print '   '; - print ''; - print '
'; - } - - print ''; + + print '
'; + + include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; + dol_fiche_end(); } -dol_htmloutput_errors('',$errors); - - -/* - * Buttons - */ - -if ($action != 'edit') -{ - print '
'; - - if ($user->rights->societe->creer) - { - print ''.$langs->trans("Modify").''; - } - - print '
'; -} - llxFooter(); - $db->close(); -?> +?> \ No newline at end of file diff --git a/htdocs/webservices/demo_wsclient_order.php-NORUN b/htdocs/webservices/demo_wsclient_order.php-NORUN index 5617c5cdd5d..dedb4cdf1e0 100755 --- a/htdocs/webservices/demo_wsclient_order.php-NORUN +++ b/htdocs/webservices/demo_wsclient_order.php-NORUN @@ -136,6 +136,6 @@ echo ''; echo '

SOAP Message

'; echo '
' . htmlspecialchars($soapclient2->response, ENT_QUOTES) . '
'; -echo ''."\n";; -echo ''."\n";; +echo ''."\n"; +echo ''."\n"; ?> diff --git a/htdocs/webservices/server_invoice.php b/htdocs/webservices/server_invoice.php index 014eba8fcb4..3e5d6305102 100755 --- a/htdocs/webservices/server_invoice.php +++ b/htdocs/webservices/server_invoice.php @@ -161,7 +161,7 @@ $server->wsdl->addComplexType( 'total_net' => array('name'=>'type','type'=>'xsd:double'), 'total_vat' => array('name'=>'type','type'=>'xsd:double'), 'total' => array('name'=>'type','type'=>'xsd:double'), - 'note' => array('name'=>'note','type'=>'xsd:string'), + 'note_private' => array('name'=>'note_private','type'=>'xsd:string'), 'note_public' => array('name'=>'note_public','type'=>'xsd:string'), 'status' => array('name'=>'status','type'=>'xsd:int'), 'close_code' => array('name'=>'close_code','type'=>'xsd:string'), @@ -324,7 +324,7 @@ function getInvoice($authentication,$id='',$ref='',$ref_ext='') 'total_net' => $invoice->total_ht, 'total_vat' => $invoice->total_tva, 'total' => $invoice->total_ttc, - 'note' => $invoice->note?$invoice->note:'', + 'note_private' => $invoice->note_private?$invoice->note_private:'', 'note_public' => $invoice->note_public?$invoice->note_public:'', 'status'=> $invoice->statut, 'close_code' => $invoice->close_code?$invoice->close_code:'', @@ -454,7 +454,7 @@ function getInvoicesForThirdParty($authentication,$idthirdparty) 'total_net' => $invoice->total_ht, 'total_vat' => $invoice->total_tva, 'total' => $invoice->total_ttc, - 'note' => $invoice->note?$invoice->note:'', + 'note_private' => $invoice->note_private?$invoice->note_private:'', 'note_public' => $invoice->note_public?$invoice->note_public:'', 'status'=> $invoice->statut, 'close_code' => $invoice->close_code?$invoice->close_code:'', @@ -517,7 +517,7 @@ function createInvoice($authentication,$invoice) $newobject->type=$invoice['type']; $newobject->ref_ext=$invoice['ref_ext']; $newobject->date=dol_stringtotime($invoice['date'],'dayrfc'); - $newobject->note=$invoice['note']; + $newobject->note_private=$invoice['note_private']; $newobject->note_public=$invoice['note_public']; $newobject->statut=$invoice['status']; $newobject->fk_project=$invoice['project_id']; diff --git a/htdocs/webservices/server_order.php b/htdocs/webservices/server_order.php index ee311e17bc1..25839b5d76d 100644 --- a/htdocs/webservices/server_order.php +++ b/htdocs/webservices/server_order.php @@ -179,7 +179,7 @@ $server->wsdl->addComplexType( 'remise_percent' => array('name'=>'remise_percent','type'=>'xsd:string'), 'remise_absolue' => array('name'=>'remise_absolue','type'=>'xsd:string'), 'source' => array('name'=>'source','type'=>'xsd:string'), - 'note' => array('name'=>'note','type'=>'xsd:string'), + 'note_private' => array('name'=>'note_private','type'=>'xsd:string'), 'note_public' => array('name'=>'note_public','type'=>'xsd:string'), 'project_id' => array('name'=>'project_id','type'=>'xsd:string'), @@ -399,7 +399,7 @@ function getOrder($authentication,$id='',$ref='',$ref_ext='') 'source' => $order->source, 'facturee' => $order->facturee, - 'note' => $order->note, + 'note_private' => $order->note_private, 'note_public' => $order->note_public, 'cond_reglement_id' => $order->cond_reglement_id, 'cond_reglement_code' => $order->cond_reglement_code, @@ -556,7 +556,7 @@ function getOrdersForThirdParty($authentication,$idthirdparty) 'source' => $order->source, 'facturee' => $order->facturee, - 'note' => $order->note, + 'note_private' => $order->note_private, 'note_public' => $order->note_public, 'cond_reglement_id' => $order->cond_reglement_id, 'cond_reglement' => $order->cond_reglement, @@ -633,7 +633,7 @@ function createOrder($authentication,$order) $newobject->ref_ext=$order['ref_ext']; $newobject->date=dol_stringtotime($order['date'],'dayrfc'); $newobject->date_lim_reglement=dol_stringtotime($order['date_due'],'dayrfc'); - $newobject->note=$order['note']; + $newobject->note_private=$order['note_private']; $newobject->note_public=$order['note_public']; $newobject->statut=$order['status']; $newobject->facturee=$order['facturee']; diff --git a/htdocs/webservices/server_supplier_invoice.php b/htdocs/webservices/server_supplier_invoice.php index 42e5dda7636..0655b0cd729 100755 --- a/htdocs/webservices/server_supplier_invoice.php +++ b/htdocs/webservices/server_supplier_invoice.php @@ -144,7 +144,7 @@ $server->wsdl->addComplexType( 'total_net' => array('name'=>'type','type'=>'xsd:double'), 'total_vat' => array('name'=>'type','type'=>'xsd:double'), 'total' => array('name'=>'type','type'=>'xsd:double'), - 'note' => array('name'=>'note','type'=>'xsd:string'), + 'note_private' => array('name'=>'note_private','type'=>'xsd:string'), 'note_public' => array('name'=>'note_public','type'=>'xsd:string'), 'status' => array('name'=>'status','type'=>'xsd:int'), 'close_code' => array('name'=>'close_code','type'=>'xsd:string'), @@ -293,7 +293,7 @@ function getSupplierInvoice($authentication,$id='',$ref='',$ref_ext='') 'date_term'=>dol_print_date($invoice->date_echeance,'dayhourrfc'), 'label'=>$invoice->libelle, 'paid'=>$invoice->paye, - 'note'=>$invoice->note, + 'note_private'=>$invoice->note_private, 'note_public'=>$invoice->note_public, 'close_code'=>$invoice->close_code, 'close_note'=>$invoice->close_note, @@ -425,7 +425,7 @@ function getSupplierInvoicesForThirdParty($authentication,$idthirdparty) 'date_term'=>dol_print_date($invoice->date_echeance,'dayhourrfc'), 'label'=>$invoice->libelle, 'paid'=>$invoice->paye, - 'note'=>$invoice->note, + 'note_private'=>$invoice->note_private, 'note_public'=>$invoice->note_public, 'close_code'=>$invoice->close_code, 'close_note'=>$invoice->close_note, diff --git a/htdocs/webservices/server_thirdparty.php b/htdocs/webservices/server_thirdparty.php index 525d6df3bf3..448da44ece2 100755 --- a/htdocs/webservices/server_thirdparty.php +++ b/htdocs/webservices/server_thirdparty.php @@ -98,7 +98,8 @@ $thirdparty_fields= array( 'supplier_code_accountancy' => array('name'=>'supplier_code_accountancy','type'=>'xsd:string'), 'date_creation' => array('name'=>'date_creation','type'=>'xsd:dateTime'), 'date_modification' => array('name'=>'date_modification','type'=>'xsd:dateTime'), - 'note' => array('name'=>'note','type'=>'xsd:string'), + 'note_private' => array('name'=>'note_private','type'=>'xsd:string'), + 'note_public' => array('name'=>'note_public','type'=>'xsd:string'), 'address' => array('name'=>'address','type'=>'xsd:string'), 'zip' => array('name'=>'zip','type'=>'xsd:string'), 'town' => array('name'=>'town','type'=>'xsd:string'), @@ -323,7 +324,9 @@ function getThirdParty($authentication,$id='',$ref='',$ref_ext='') 'capital' => $thirdparty->capital, 'barcode' => $thirdparty->barcode, 'vat_used' => $thirdparty->tva_assuj, - 'vat_number' => $thirdparty->tva_intra); + 'vat_number' => $thirdparty->tva_intra, + 'note_private' => $thirdparty->note_private, + 'note_public' => $thirdparty->note_public); //Retreive all extrafield for thirdsparty // fetch optionals attributes and labels @@ -410,7 +413,8 @@ function createThirdParty($authentication,$thirdparty) $newobject->code_compta=$thirdparty['customer_code_accountancy']; $newobject->code_compta_fournisseur=$thirdparty['supplier_code_accountancy']; $newobject->date_creation=$now; - $newobject->note=$thirdparty['note']; + $newobject->note_private=$thirdparty['note_private']; + $newobject->note_public=$thirdparty['note_public']; $newobject->address=$thirdparty['address']; $newobject->zip=$thirdparty['zip']; $newobject->town=$thirdparty['town']; @@ -530,7 +534,8 @@ function updateThirdParty($authentication,$thirdparty) $object->code_compta=$thirdparty['customer_code_accountancy']; $object->code_compta_fournisseur=$thirdparty['supplier_code_accountancy']; $object->date_creation=$now; - $object->note=$thirdparty['note']; + $object->note_private=$thirdparty['note_private']; + $object->note_public=$thirdparty['note_public']; $object->address=$thirdparty['address']; $object->zip=$thirdparty['zip']; $object->town=$thirdparty['town']; diff --git a/test/phpunit/ContactTest.php b/test/phpunit/ContactTest.php index 83dd603ba3e..bac26a28485 100755 --- a/test/phpunit/ContactTest.php +++ b/test/phpunit/ContactTest.php @@ -189,8 +189,8 @@ class ContactTest extends PHPUnit_Framework_TestCase $localobject->oldcopy=dol_clone($localobject); - $localobject->note='New note after update'; - //$localobject->note_public='New note public after update'; + $localobject->note_private='New private note after update'; + $localobject->note_public='New public note after update'; $localobject->lastname='New name'; $localobject->firstname='New firstname'; $localobject->address='New address'; @@ -205,15 +205,18 @@ class ContactTest extends PHPUnit_Framework_TestCase $localobject->email='newemail@newemail.com'; $localobject->jabberid='New im id'; $localobject->default_lang='es_ES'; + $result=$localobject->update($localobject->id,$user); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0, 'Contact::update error'); - $result=$localobject->update_note($localobject->note); + + $result=$localobject->update_note_private($localobject->note_private); print __METHOD__." id=".$localobject->id." result=".$result."\n"; - $this->assertLessThan($result, 0, 'Contact::update_note error'); - //$result=$localobject->update_note_public($localobject->note_public); - //print __METHOD__." id=".$localobject->id." result=".$result."\n"; - //$this->assertLessThan($result, 0); + $this->assertLessThan($result, 0, 'Contact::update_note_private error'); + + $result=$localobject->update_note_public($localobject->note_public); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertLessThan($result, 0, 'Contact::update_note_public error'); $newobject=new Contact($this->savdb); $result=$newobject->fetch($localobject->id); diff --git a/test/phpunit/HolidayTest.php b/test/phpunit/HolidayTest.php index eabfdf4bcfc..f0bb254ce25 100644 --- a/test/phpunit/HolidayTest.php +++ b/test/phpunit/HolidayTest.php @@ -183,8 +183,8 @@ class HolidayTest extends PHPUnit_Framework_TestCase $localobject->oldcopy=dol_clone($localobject); - $localobject->note='New note after update'; - //$localobject->note_public='New note public after update'; + $localobject->note_private='New private note after update'; + $localobject->note_public='New public note after update'; $localobject->lastname='New name'; $localobject->firstname='New firstname'; $localobject->address='New address'; @@ -199,15 +199,19 @@ class HolidayTest extends PHPUnit_Framework_TestCase $localobject->email='newemail@newemail.com'; $localobject->jabberid='New im id'; $localobject->default_lang='es_ES'; + $result=$localobject->update($localobject->id,$user); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0, 'Holiday::update error'); - $result=$localobject->update_note($localobject->note); + + $result=$localobject->update_note_private($localobject->note_private); print __METHOD__." id=".$localobject->id." result=".$result."\n"; - $this->assertLessThan($result, 0, 'Holiday::update_note error'); - //$result=$localobject->update_note_public($localobject->note_public); - //print __METHOD__." id=".$localobject->id." result=".$result."\n"; - //$this->assertLessThan($result, 0); + $this->assertLessThan($result, 0, 'Holiday::update_note_private error'); + + $result=$localobject->update_note_public($localobject->note_public); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertLessThan($result, 0, 'Holiday::update_note_public error'); + $newobject=new Holiday($this->savdb); $result=$newobject->fetch($localobject->id); diff --git a/test/phpunit/SocieteTest.php b/test/phpunit/SocieteTest.php index c7b3434218d..619bf98dbe7 100755 --- a/test/phpunit/SocieteTest.php +++ b/test/phpunit/SocieteTest.php @@ -189,8 +189,8 @@ class SocieteTest extends PHPUnit_Framework_TestCase $langs=$this->savlangs; $db=$this->savdb; - $localobject->note='New note after update'; - //$localobject->note_public='New note public after update'; + $localobject->note_private='New private note after update'; + $localobject->note_public='New public note after update'; $localobject->name='New name'; $localobject->address='New address'; $localobject->zip='New zip'; @@ -205,15 +205,18 @@ class SocieteTest extends PHPUnit_Framework_TestCase $localobject->idprof2='new idprof2'; $localobject->idprof3='new idprof3'; $localobject->idprof4='new idprof4'; + $result=$localobject->update($localobject->id,$user); print __METHOD__." id=".$localobject->id." result=".$result."\n"; $this->assertLessThan($result, 0); - $result=$localobject->update_note($localobject->note); + + $result=$localobject->update_note_private($localobject->note_private); print __METHOD__." id=".$localobject->id." result=".$result."\n"; - $this->assertLessThan($result, 0); - //$result=$localobject->update_note_public($localobject->note_public); - //print __METHOD__." id=".$localobject->id." result=".$result."\n"; - //$this->assertLessThan($result, 0); + $this->assertLessThan($result, 0, 'Holiday::update_note_private error'); + + $result=$localobject->update_note_public($localobject->note_public); + print __METHOD__." id=".$localobject->id." result=".$result."\n"; + $this->assertLessThan($result, 0, 'Holiday::update_note_public error'); $newobject=new Societe($this->savdb); $result=$newobject->fetch($localobject->id); From 04e933c40f9f9b7e474a4f2d75c9969f2699cc4a Mon Sep 17 00:00:00 2001 From: fhenry Date: Tue, 9 Apr 2013 21:58:25 +0200 Subject: [PATCH 04/44] Fix : admin ODT doctemplate path commande/project --- htdocs/admin/commande.php | 2 +- htdocs/admin/project.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/commande.php b/htdocs/admin/commande.php index ebcb94110e9..23295efa17a 100644 --- a/htdocs/admin/commande.php +++ b/htdocs/admin/commande.php @@ -188,7 +188,7 @@ else if ($action == 'set_COMMANDE_FREE_TEXT') $mesg = "".$langs->trans("Error").""; } } -else if ($action='setModuleOptions') { +else if ($action=='setModuleOptions') { if (dolibarr_set_const($db, "COMMANDE_ADDON_PDF_ODT_PATH",GETPOST('value1'),'chaine',0,'',$conf->entity)) { // La constante qui a ete lue en avant du nouveau set diff --git a/htdocs/admin/project.php b/htdocs/admin/project.php index 9f28b57be5b..e9973758c73 100644 --- a/htdocs/admin/project.php +++ b/htdocs/admin/project.php @@ -152,7 +152,8 @@ else if ($action == 'setmod') dolibarr_set_const($db, "PROJECT_ADDON",$value,'chaine',0,'',$conf->entity); } -else if ($action='setModuleOptions') { + +else if ($action=='setModuleOptions') { if (dolibarr_set_const($db, "PROJECT_ADDON_PDF_ODT_PATH",GETPOST('value1'),'chaine',0,'',$conf->entity)) { // La constante qui a ete lue en avant du nouveau set From a4b56708e9843aae7770be393d099b0dc046a386 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 9 Apr 2013 23:04:59 +0200 Subject: [PATCH 05/44] Better error management --- htdocs/admin/system/modules.php | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/htdocs/admin/system/modules.php b/htdocs/admin/system/modules.php index bfd1bc5d81f..0baed9e53bc 100644 --- a/htdocs/admin/system/modules.php +++ b/htdocs/admin/system/modules.php @@ -47,9 +47,11 @@ print "
\n"; $modules = array(); $modules_names = array(); $modules_files = array(); +$modules_fullpath = array(); $modulesdir = dolGetModulesDirs(); // Load list of modules +$i=0; foreach($modulesdir as $dir) { $handle=@opendir(dol_osencode($dir)); @@ -63,13 +65,25 @@ foreach($modulesdir as $dir) if ($modName) { - include_once $dir.$file; - $objMod = new $modName($db); + //print 'xx'.$dir.$file.'
'; + if (in_array($file, $modules_files)) + { + // File duplicate + print "Warning duplicate file found : ".$file." (Found ".$dir.$file.", already found ".$modules_fullpath[$file].")
"; + } + else + { + // File to load + include_once $dir.$file; - $modules[$objMod->numero]=$objMod; - $modules_names[$objMod->numero]=$objMod->name; - $modules_files[$objMod->numero]=$file; - $picto[$objMod->numero]=(isset($objMod->picto) && $objMod->picto)?$objMod->picto:'generic'; + $objMod = new $modName($db); + + $modules[$objMod->numero]=$objMod; + $modules_names[$objMod->numero]=$objMod->name; + $modules_files[$objMod->numero]=$file; + $modules_fullpath[$file]=$dir.$file; + $picto[$objMod->numero]=(isset($objMod->picto) && $objMod->picto)?$objMod->picto:'generic'; + } } } } @@ -127,8 +141,7 @@ sort($rights_ids); $old=''; foreach($rights_ids as $right_id) { - if ($old == $right_id) - print "Warning duplicate id on permission : ".$right_id."
"; + if ($old == $right_id) print "Warning duplicate id on permission : ".$right_id."
"; $old = $right_id; } From 538194f43579574333c2d9adcc9df68e20f0ee61 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 9 Apr 2013 23:05:50 +0200 Subject: [PATCH 06/44] New: Add module opensurvey. Final. Test are welcome. --- ChangeLog | 3 +- htdocs/core/modules/modOpenSurvey.class.php | 224 ++++ htdocs/opensurvey/admin/index.php | 62 + htdocs/opensurvey/adminstuds.php | 352 ++++++ htdocs/opensurvey/adminstuds_preview.php | 1062 +++++++++++++++++ .../class/opensurveysondage.class.php | 512 ++++++++ htdocs/opensurvey/css/style.css | 532 +++++++++ htdocs/opensurvey/fonctions.php | 292 +++++ htdocs/opensurvey/img/accept-24.png | Bin 0 -> 1696 bytes htdocs/opensurvey/img/accept-32.png | Bin 0 -> 2449 bytes htdocs/opensurvey/img/accept.png | Bin 0 -> 901 bytes htdocs/opensurvey/img/add-16.png | Bin 0 -> 845 bytes htdocs/opensurvey/img/add-24.png | Bin 0 -> 1393 bytes htdocs/opensurvey/img/add.png | Bin 0 -> 2017 bytes htdocs/opensurvey/img/back-32.png | Bin 0 -> 2026 bytes htdocs/opensurvey/img/calendar-32.png | Bin 0 -> 2155 bytes htdocs/opensurvey/img/cancel.png | Bin 0 -> 587 bytes htdocs/opensurvey/img/chart-32.png | Bin 0 -> 2059 bytes htdocs/opensurvey/img/csv.png | Bin 0 -> 804 bytes htdocs/opensurvey/img/fforward.png | Bin 0 -> 1359 bytes htdocs/opensurvey/img/ical.png | Bin 0 -> 829 bytes htdocs/opensurvey/img/info.png | Bin 0 -> 777 bytes htdocs/opensurvey/img/medaille.png | Bin 0 -> 753 bytes htdocs/opensurvey/img/next-32.png | Bin 0 -> 2017 bytes htdocs/opensurvey/img/next.png | Bin 0 -> 1349 bytes htdocs/opensurvey/img/object_opensurvey.png | Bin 0 -> 828 bytes htdocs/opensurvey/img/opensurvey.png | Bin 0 -> 2350 bytes htdocs/opensurvey/img/opensurvey_logo.png | Bin 0 -> 37593 bytes htdocs/opensurvey/img/previous.png | Bin 0 -> 1388 bytes htdocs/opensurvey/img/reload.png | Bin 0 -> 1544 bytes htdocs/opensurvey/img/rewind.png | Bin 0 -> 1364 bytes htdocs/opensurvey/index.php | 69 ++ htdocs/opensurvey/langs/en_US/opensurvey.lang | 68 ++ htdocs/opensurvey/langs/fr_FR/opensurvey.lang | 68 ++ htdocs/opensurvey/list.php | 145 +++ htdocs/opensurvey/public/choix_autre.php | 222 ++++ htdocs/opensurvey/public/choix_date.php | 573 +++++++++ htdocs/opensurvey/public/create_survey.php | 199 +++ htdocs/opensurvey/public/exportcsv.php | 154 +++ htdocs/opensurvey/public/images/accept-24.png | Bin 0 -> 1696 bytes htdocs/opensurvey/public/images/accept-32.png | Bin 0 -> 2449 bytes htdocs/opensurvey/public/images/accept.png | Bin 0 -> 901 bytes htdocs/opensurvey/public/images/add-16.png | Bin 0 -> 845 bytes htdocs/opensurvey/public/images/add-24.png | Bin 0 -> 1393 bytes htdocs/opensurvey/public/images/add.png | Bin 0 -> 2017 bytes htdocs/opensurvey/public/images/back-32.png | Bin 0 -> 2026 bytes .../opensurvey/public/images/calendar-32.png | Bin 0 -> 2155 bytes htdocs/opensurvey/public/images/cancel.png | Bin 0 -> 587 bytes htdocs/opensurvey/public/images/chart-32.png | Bin 0 -> 2059 bytes htdocs/opensurvey/public/images/csv.png | Bin 0 -> 804 bytes htdocs/opensurvey/public/images/date.png | Bin 0 -> 60015 bytes htdocs/opensurvey/public/images/fforward.png | Bin 0 -> 1359 bytes htdocs/opensurvey/public/images/ical.png | Bin 0 -> 829 bytes htdocs/opensurvey/public/images/info.png | Bin 0 -> 777 bytes .../public/images/logo_uds_bandeau.gif | Bin 0 -> 3391 bytes .../public/images/logo_uds_lettre.jpg | Bin 0 -> 23051 bytes htdocs/opensurvey/public/images/medaille.png | Bin 0 -> 753 bytes htdocs/opensurvey/public/images/next-32.png | Bin 0 -> 2017 bytes htdocs/opensurvey/public/images/next.png | Bin 0 -> 1349 bytes htdocs/opensurvey/public/images/previous.png | Bin 0 -> 1388 bytes htdocs/opensurvey/public/images/reload.png | Bin 0 -> 1544 bytes htdocs/opensurvey/public/images/rewind.png | Bin 0 -> 1364 bytes htdocs/opensurvey/public/images/sondage2.png | Bin 0 -> 70717 bytes htdocs/opensurvey/public/index.php | 61 + htdocs/opensurvey/public/studs.php | 713 +++++++++++ .../sql/llx_opensurvey_comments.key.sql | 22 + .../sql/llx_opensurvey_comments.sql | 25 + .../sql/llx_opensurvey_sondage.key.sql | 19 + .../opensurvey/sql/llx_opensurvey_sondage.sql | 33 + .../sql/llx_opensurvey_user_studs.key.sql | 20 + .../sql/llx_opensurvey_user_studs.sql | 24 + 71 files changed, 5453 insertions(+), 1 deletion(-) create mode 100755 htdocs/core/modules/modOpenSurvey.class.php create mode 100755 htdocs/opensurvey/admin/index.php create mode 100755 htdocs/opensurvey/adminstuds.php create mode 100755 htdocs/opensurvey/adminstuds_preview.php create mode 100644 htdocs/opensurvey/class/opensurveysondage.class.php create mode 100644 htdocs/opensurvey/css/style.css create mode 100755 htdocs/opensurvey/fonctions.php create mode 100755 htdocs/opensurvey/img/accept-24.png create mode 100755 htdocs/opensurvey/img/accept-32.png create mode 100755 htdocs/opensurvey/img/accept.png create mode 100755 htdocs/opensurvey/img/add-16.png create mode 100755 htdocs/opensurvey/img/add-24.png create mode 100755 htdocs/opensurvey/img/add.png create mode 100755 htdocs/opensurvey/img/back-32.png create mode 100755 htdocs/opensurvey/img/calendar-32.png create mode 100755 htdocs/opensurvey/img/cancel.png create mode 100755 htdocs/opensurvey/img/chart-32.png create mode 100755 htdocs/opensurvey/img/csv.png create mode 100755 htdocs/opensurvey/img/fforward.png create mode 100755 htdocs/opensurvey/img/ical.png create mode 100755 htdocs/opensurvey/img/info.png create mode 100755 htdocs/opensurvey/img/medaille.png create mode 100755 htdocs/opensurvey/img/next-32.png create mode 100755 htdocs/opensurvey/img/next.png create mode 100755 htdocs/opensurvey/img/object_opensurvey.png create mode 100644 htdocs/opensurvey/img/opensurvey.png create mode 100644 htdocs/opensurvey/img/opensurvey_logo.png create mode 100755 htdocs/opensurvey/img/previous.png create mode 100755 htdocs/opensurvey/img/reload.png create mode 100755 htdocs/opensurvey/img/rewind.png create mode 100755 htdocs/opensurvey/index.php create mode 100755 htdocs/opensurvey/langs/en_US/opensurvey.lang create mode 100755 htdocs/opensurvey/langs/fr_FR/opensurvey.lang create mode 100755 htdocs/opensurvey/list.php create mode 100755 htdocs/opensurvey/public/choix_autre.php create mode 100755 htdocs/opensurvey/public/choix_date.php create mode 100755 htdocs/opensurvey/public/create_survey.php create mode 100755 htdocs/opensurvey/public/exportcsv.php create mode 100755 htdocs/opensurvey/public/images/accept-24.png create mode 100755 htdocs/opensurvey/public/images/accept-32.png create mode 100755 htdocs/opensurvey/public/images/accept.png create mode 100755 htdocs/opensurvey/public/images/add-16.png create mode 100755 htdocs/opensurvey/public/images/add-24.png create mode 100755 htdocs/opensurvey/public/images/add.png create mode 100755 htdocs/opensurvey/public/images/back-32.png create mode 100644 htdocs/opensurvey/public/images/calendar-32.png create mode 100755 htdocs/opensurvey/public/images/cancel.png create mode 100644 htdocs/opensurvey/public/images/chart-32.png create mode 100755 htdocs/opensurvey/public/images/csv.png create mode 100644 htdocs/opensurvey/public/images/date.png create mode 100755 htdocs/opensurvey/public/images/fforward.png create mode 100755 htdocs/opensurvey/public/images/ical.png create mode 100755 htdocs/opensurvey/public/images/info.png create mode 100755 htdocs/opensurvey/public/images/logo_uds_bandeau.gif create mode 100755 htdocs/opensurvey/public/images/logo_uds_lettre.jpg create mode 100755 htdocs/opensurvey/public/images/medaille.png create mode 100755 htdocs/opensurvey/public/images/next-32.png create mode 100755 htdocs/opensurvey/public/images/next.png create mode 100755 htdocs/opensurvey/public/images/previous.png create mode 100755 htdocs/opensurvey/public/images/reload.png create mode 100755 htdocs/opensurvey/public/images/rewind.png create mode 100644 htdocs/opensurvey/public/images/sondage2.png create mode 100755 htdocs/opensurvey/public/index.php create mode 100755 htdocs/opensurvey/public/studs.php create mode 100755 htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql create mode 100755 htdocs/opensurvey/sql/llx_opensurvey_comments.sql create mode 100755 htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql create mode 100755 htdocs/opensurvey/sql/llx_opensurvey_sondage.sql create mode 100755 htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql create mode 100755 htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql diff --git a/ChangeLog b/ChangeLog index d6ae2f76959..cbca688c6c0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,7 +30,8 @@ For users: - New: Can define a different clicktodial setup per user. - New: Add option INVOICE_CAN_NEVER_BE_REMOVED. - New: Enhance agenda module to reach RFC2445 (add busy information). -- First change to prepare feature click to print for PDF. +- New: Add module Opensurvey. +- First change to prepare feature "click to print" (IPP) for PDF. For translators: - Update language files. diff --git a/htdocs/core/modules/modOpenSurvey.class.php b/htdocs/core/modules/modOpenSurvey.class.php new file mode 100755 index 00000000000..e9385442a85 --- /dev/null +++ b/htdocs/core/modules/modOpenSurvey.class.php @@ -0,0 +1,224 @@ + + * + * Licensed under the GNU GPL v3 or higher (See file gpl-3.0.html) + */ + +/** + * \defgroup opensurvey Module OpenSurvey + * \brief Module to OpenSurvey integration. + */ + +/** + * \file htdocs/opensurvey/core/modules/modOpenSurvey.class.php + * \ingroup opensurvey + * \brief Description and activation file for module OpenSurvey + */ +include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php"); + + +/** + * Description and activation class for module opensurvey + */ +class modOpenSurvey extends DolibarrModules +{ + + /** + * Constructor. Define names, constants, directories, boxes, permissions + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $langs,$conf; + + $this->db = $db; + + // Id for module (must be unique). + // Use here a free id (See in Home -> System information -> Dolibarr for list of used module id). + $this->numero = 55000; + // Key text used to identify module (for permission, menus, etc...) + $this->rights_class = 'opensurvey'; + + // Family can be 'crm','financial','hr','projects','product','technic','other' + // It is used to group modules in module setup page + $this->family = "projects"; + // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) + $this->name = preg_replace('/^mod/i','',get_class($this)); + // Module description used if translation string 'ModuleXXXDesc' not found (XXX is value MyModule) + $this->description = "Module to integrate a survey (like Doodle, Studs, Rdvz, ...)"; + // Possible values for version are: 'development', 'experimental', 'dolibarr' or version + $this->version = 'dolibarr'; + // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) + $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); + // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) + $this->special = 0; + // Name of image file used for this module. + // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue' + // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module' + $this->picto='opensurvey.png@opensurvey'; + + // Data directories to create when module is enabled + $this->dirs = array(); + //$this->dirs[0] = DOL_DATA_ROOT.'/mymodule; + //$this->dirs[1] = DOL_DATA_ROOT.'/mymodule/temp; + + // Config pages. Put here list of php page names stored in admin directory used to setup module + $this->config_page_url = array("index.php@opensurvey"); + + // Dependencies + $this->depends = array(); // List of modules id that must be enabled if this module is enabled + $this->requiredby = array(); // List of modules id to disable if this one is disabled + $this->phpmin = array(4,1); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(2,4); // Minimum version of Dolibarr required by module + + // Constants + $this->const = array(); // List of parameters + + // Dictionnaries + $this->dictionnaries=array(); + + // Boxes + $this->boxes = array(); // List of boxes + $r=0; + + // Add here list of php file(s) stored in includes/boxes that contains class to show a box. + // Example: + //$this->boxes[$r][1] = "myboxa.php"; + //$r++; + //$this->boxes[$r][1] = "myboxb.php"; + //$r++; + + // Permissions + $this->rights = array(); // Permission array used by this module + $r=0; + + // Add here list of permission defined by an id, a label, a boolean and two constant strings. + // Example: + $this->rights[$r][0] = 55000; // Permission id (must not be already used) + $this->rights[$r][1] = 'Read surveys'; // Permission label + $this->rights[$r][2] = 'r'; // Permission by default for new user (0/1) + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'survey'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $this->rights[$r][5] = 'read'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $r++; + + // Add here list of permission defined by an id, a label, a boolean and two constant strings. + // Example: + $this->rights[$r][0] = 55001; // Permission id (must not be already used) + $this->rights[$r][1] = 'Create/modify surveys'; // Permission label + $this->rights[$r][2] = 'w'; // Permission by default for new user (0/1) + $this->rights[$r][3] = 0; // Permission by default for new user (0/1) + $this->rights[$r][4] = 'survey'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $this->rights[$r][5] = 'write'; // In php code, permission will be checked by test if ($user->rights->permkey->level1->level2) + $r++; + + + // Main menu entries + $this->menus = array(); // List of menus to add + $r=0; + + $this->menu[$r]=array( 'fk_menu'=>0, // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'top', + 'titre'=>'Surveys', + 'mainmenu'=>'opensurvey', + 'url'=>'/opensurvey/index.php', + 'langs'=>'opensurvey@opensurvey', + 'position'=>200, + 'enabled'=>'$conf->opensurvey->enabled', // Define condition to show or hide menu entry. Use '$conf->NewsSubmitter->enabled' if entry must be visible if module is enabled. + 'perms'=>'$user->rights->opensurvey->survey->read', + 'target'=>'', + 'user'=>0); + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=opensurvey', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', + 'titre'=>'Survey', + 'mainmenu'=>'opensurvey', + 'leftmenu'=>'opensurvey', + 'url'=>'/opensurvey/index.php?mainmenu=opensurvey&leftmenu=opensurvey', + 'langs'=>'opensurvey@opensurvey', + 'position'=>200, + 'enabled'=>'$conf->opensurvey->enabled', // Define condition to show or hide menu entry. Use '$conf->NewsSubmitter->enabled' if entry must be visible if module is enabled. + 'perms'=>'', + 'target'=>'', + 'user'=>0); + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=opensurvey,fk_leftmenu=opensurvey', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', + 'titre'=>'NewSurvey', + 'mainmenu'=>'opensurvey', + 'leftmenu'=>'opensurvey_new', + 'url'=>'/opensurvey/public/index.php?origin=dolibarr', + 'langs'=>'opensurvey@opensurvey', + 'position'=>210, + 'enabled'=>'$conf->opensurvey->enabled', // Define condition to show or hide menu entry. Use '$conf->NewsSubmitter->enabled' if entry must be visible if module is enabled. + 'perms'=>'', + 'target'=>'_blank', + 'user'=>0); + $r++; + + $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=opensurvey,fk_leftmenu=opensurvey', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + 'type'=>'left', + 'titre'=>'List', + 'mainmenu'=>'opensurvey', + 'leftmenu'=>'opensurvey_list', + 'url'=>'/opensurvey/list.php', + 'langs'=>'opensurvey@opensurvey', + 'position'=>220, + 'enabled'=>'$conf->opensurvey->enabled', // Define condition to show or hide menu entry. Use '$conf->NewsSubmitter->enabled' if entry must be visible if module is enabled. + 'perms'=>'', + 'target'=>'', + 'user'=>0); + $r++; + } + + /** + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function init($options='') + { + $sql = array(); + + $result=$this->load_tables(); + + return $this->_init($sql,$options); + } + + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options='') + { + $sql = array(); + + return $this->_remove($sql,$options); + } + + + /** + * Create tables and keys required by module + * Files mymodule.sql and mymodule.key.sql with create table and create keys + * commands must be stored in directory /mymodule/sql/ + * This function is called by this->init. + * + * @return int <=0 if KO, >0 if OK + */ + function load_tables() + { + return $this->_load_tables('/opensurvey/sql/'); + } +} + +?> diff --git a/htdocs/opensurvey/admin/index.php b/htdocs/opensurvey/admin/index.php new file mode 100755 index 00000000000..02c6a5ea125 --- /dev/null +++ b/htdocs/opensurvey/admin/index.php @@ -0,0 +1,62 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/admin/index.php + * \ingroup opensurvey + * \brief Setup page of opensurvey + */ + +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + +// Security check +if (!$user->admin) accessforbidden(); + + + + +/* + * View + */ + +$langs->load("opensurvey@opensurvey"); +llxHeader(); + +print_fiche_titre($langs->trans("OpenSurveyArea")); + +echo $langs->trans("OpenSurveyNothingToSetup").'

'."\n"; + +// Link +print img_picto('','object_globe.png').' '.$langs->trans("PublicLinkToCreateSurvey").':
'; + +// Define $urlwithroot +$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + +$url=$urlwithouturlroot.dol_buildpath('/opensurvey/public/index.php',1); +$urllink=''.$url.''; +print $urllink; + + +llxFooter(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/adminstuds.php b/htdocs/opensurvey/adminstuds.php new file mode 100755 index 00000000000..d3547a4ac51 --- /dev/null +++ b/htdocs/opensurvey/adminstuds.php @@ -0,0 +1,352 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/adminstuds.php + * \ingroup opensurvey + * \brief Page to edit survey + */ + +require_once('../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + + +// Security check +if (!$user->admin) accessforbidden(); + + +// Initialisation des variables +$action=GETPOST('action'); +$numsondage = $numsondageadmin = ''; +if (GETPOST('sondage')) +{ + if (strlen(GETPOST('sondage')) == 24) // recuperation du numero de sondage admin (24 car.) dans l'URL + { + $numsondageadmin=GETPOST("sondage",'alpha'); + $numsondage=substr($numsondageadmin, 0, 16); + } + else + { + $numsondageadmin=''; + $numsondage=GETPOST("sondage",'alpha'); + } +} + +$object=new Opensurveysondage($db); + +$expiredate=dol_mktime(0, 0, 0, GETPOST('expiremonth'), GETPOST('expireday'), GETPOST('expireyear')); + + + +/* + * Actions + */ + + +// Delete +if ($action == 'delete_confirm') +{ + $result=$object->delete($user,'',$numsondageadmin); + + header('Location: '.dol_buildpath('/opensurvey/list.php',1)); + exit(); +} + +// Update +if ($action == 'update') +{ + $error=0; + + if (! GETPOST('nouveautitre')) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Title")),'errors'); + $error++; + $action = 'edit'; + } + + if (! $error) + { + $res=$object->fetch(0,$numsondageadmin); + if ($res < 0) dol_print_error($db,$object->error); + } + + if (! $error) + { + $object->titre = GETPOST('nouveautitre'); + $object->commentaires = GETPOST('nouveauxcommentaires'); + $object->mail_admin = GETPOST('nouvelleadresse'); + $object->date_fin = $expiredate; + $object->survey_link_visible = GETPOST('survey_link_visible')=='on'?1:0; + $object->canedit = GETPOST('canedit')=='on'?1:0; + + $res=$object->update($user); + if ($res < 0) + { + setEventMessage($object->error,'errors'); + $action='edit'; + } + } +} + + +// Add comment +if (GETPOST('ajoutcomment')) +{ + $error=0; + + if (! GETPOST('comment')) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Comment")),'errors'); + } + if (! GETPOST('commentuser')) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("User")),'errors'); + } + + if (! $error) + { + $comment = GETPOST("comment"); + $comment_user = GETPOST('commentuser'); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."opensurvey_comments (id_sondage, comment, usercomment)"; + $sql.= " VALUES ('".$db->escape($numsondage)."','".$db->escape($comment)."','".$db->escape($comment_user)."')"; + $resql = $db->query($sql); + dol_syslog("sql=".$sql); + if (! $resql) + { + $err |= COMMENT_INSERT_FAILED; + } + } +} + +// Delete comment +$idcomment=GETPOST('deletecomment','int'); +if ($idcomment) +{ + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'opensurvey_comments WHERE id_comment = '.$idcomment; + $resql = $db->query($sql); +} + + +/* + * View + */ + +$form=new Form($db); + +$result=$object->fetch(0,$numsondage); +if ($result <= 0) +{ + print $langs->trans("ErrorRecordNotFound"); + llxFooter(); + exit; +} + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeader('',$object->titre, 0, 0, 0, 0, $arrayofjs, $arrayofcss); + + +// Define format of choices +$toutsujet=explode(",",$object->sujet); +$listofanswers=array(); +foreach ($toutsujet as $value) +{ + $tmp=explode('@',$value); + $listofanswers[]=array('label'=>$tmp[0],'format'=>($tmp[1]?$tmp[1]:'checkbox')); +} +$toutsujet=str_replace("@","
",$toutsujet); +$toutsujet=str_replace("°","'",$toutsujet); + + +print '
'."\n"; +print ''; + +$head = array(); + +$head[0][0] = ''; +$head[0][1] = $langs->trans("Card"); +$head[0][2] = 'general'; +$h++; + +$head[1][0] = 'adminstuds_preview.php?sondage='.$object->id_sondage_admin; +$head[1][1] = $langs->trans("SurveyResults").'/'.$langs->trans("Preview"); +$head[1][2] = 'preview'; +$h++; + +print dol_get_fiche_head($head,'general',$langs->trans("Survey"),0,dol_buildpath('/opensurvey/img/object_opensurvey.png',1),1); + + +print ''; + +$linkback = ''.$langs->trans("BackToList").''; + +// Ref +print ''; +print ''; +print ''; + +// Type +$type=($object->format=="A"||$object->format=="A+")?'classic':'date'; +print ''; + +// Title +print ''; + +// Auteur +print ''; + +// Description +print ''; + +// EMail +print ''; + +// Can edit other votes +print ''; + +// Expire date +print ''; + + +// Link +print '
'.$langs->trans('Ref').''; +print $form->showrefnav($object, 'sondage', $linkback, 1, 'id_sondage_admin', 'id_sondage_admin'); +print '
'.$langs->trans("Type").''; +print img_picto('',dol_buildpath('/opensurvey/img/'.($type == 'classic'?'chart-32.png':'calendar-32.png'),1),'width="16"',1); +print ' '.$langs->trans($type=='classic'?"TypeClassic":"TypeDate").'
'; +$adresseadmin=$object->mail_admin; +print $langs->trans("Title") .''; +if ($action == 'edit') +{ + print ''; +} +else print $object->titre; +print '
'; +print $langs->trans("Author") .''; +print $object->nom_admin; +print '
'.$langs->trans("Description") .''; +if ($action == 'edit') +{ + print ''."\n"; +} +else print dol_nl2br($object->commentaires); +print '
'.$langs->trans("EMail") .''; +if ($action == 'edit') +{ + print ''; +} +else print dol_print_email($object->mail_admin); +print '
'.$langs->trans('CanEditVotes').''; +if ($action == 'edit') +{ + print 'canedit?' checked="true"':'').'">'; +} +else print yn($object->canedit); +print '
'.$langs->trans('ExpireDate').''; +if ($action == 'edit') print $form->select_date($expiredate?$expiredate:$object->date_fin,'expire'); +else print dol_print_date($object->date_fin,'day'); +print '
'.img_picto('','object_globe.png').' '.$langs->trans("UrlForSurvey",'').''; + +// Define $urlwithroot +$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + +$url=$urlwithouturlroot.dol_buildpath('/opensurvey/public/studs.php',1).'?sondage='.$numsondage; +$urllink=''.$url.''; +print $urllink; + +print '
'; + +if ($action == 'edit') print '

'; + +print '
'."\n"; + +dol_fiche_end(); + + +/* + * Barre d'actions + */ +print '
'; + +if ($action != 'edit') print ''.$langs->trans("Modify") . ''; + +if ($action != 'edit') print ''.$langs->trans('Delete').''; + +print '
'; + +if ($action == 'delete') +{ + print $form->formconfirm($_SERVER["PHP_SELF"].'?&sondage='.$numsondageadmin, $langs->trans("RemovePoll"), $langs->trans("ConfirmRemovalOfPoll",$id), 'delete_confirm', '', '', 1); +} + + + +print '
'; + + +print '
'."\n"; + +print_fiche_titre($langs->trans("CommentsOfVoters"),'',''); + +// Comment list +$sql = 'SELECT id_comment, usercomment, comment'; +$sql.= ' FROM '.MAIN_DB_PREFIX.'opensurvey_comments'; +$sql.= " WHERE id_sondage='".$db->escape($numsondage)."'"; +$sql.= " ORDER BY id_comment"; +$resql = $db->query($sql); +$num_rows=$db->num_rows($resql); +if ($num_rows > 0) +{ + $i = 0; + while ( $i < $num_rows) + { + $obj=$db->fetch_object($resql); + print ' '.img_picto('', 'delete.png').' '; + print $obj->usercomment.' : '.dol_nl2br($obj->comment)."
"; + $i++; + } +} +else +{ + print $langs->trans("NoCommentYet").'
';; +} + +print '
'; + +// Add comment +print $langs->trans("AddACommentForPoll") . '
'; +print '
'."\n"; +print $langs->trans("Name") .' :
'."\n"; +print '
'."\n"; +if (isset($erreur_commentaire_vide) && $erreur_commentaire_vide=="yes") { + print "" . $langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Name")) . ""; +} + +print '
'; + +llxFooterSurvey(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/adminstuds_preview.php b/htdocs/opensurvey/adminstuds_preview.php new file mode 100755 index 00000000000..7e7bb6a6967 --- /dev/null +++ b/htdocs/opensurvey/adminstuds_preview.php @@ -0,0 +1,1062 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/admin_studs_preview.php + * \ingroup opensurvey + * \brief Page to preview votes of a survey + */ + +$res=0; +require_once('../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + + +// Security check +if (!$user->admin) accessforbidden(); + + +// Init vars +$action=GETPOST('action'); +$numsondageadmin=GETPOST("sondage"); +$numsondage=substr($numsondageadmin, 0, 16); + +$object=new Opensurveysondage($db); +$object->fetch(0,$numsondageadmin); +$nblignes=count($object->fetch_lines()); + + +/* + * Actions + */ + +$nbcolonnes = substr_count($object->sujet, ',') + 1; + +// Add vote +if (isset($_POST["boutonp"]) || isset($_POST["boutonp_x"])) +{ + if (GETPOST('nom')) + { + $erreur_prenom = false; + + $nouveauchoix = ''; + for ($i=0;$i<$nbcolonnes;$i++) + { + if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '1') + { + $nouveauchoix.="1"; + } + else if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '2') + { + $nouveauchoix.="2"; + } + else { // sinon c'est 0 + $nouveauchoix.="0"; + } + } + + $nom=substr(GETPOST("nom"),0,64); + + // Check if vote already exists + $sql = 'SELECT id_users, nom'; + $sql.= ' FROM '.MAIN_DB_PREFIX."opensurvey_user_studs'; + $sql.= ' WHERE id_sondage='".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."'"; + $sql.= ' ORDER BY id_users'; + $resql = $db->query($sql); + $num_rows = $db->num_rows($resql); + if ($num_rows > 0) + { + setEventMessage($langs->trans("VoteNameAlreadyExists"),'errors'); + $error++; + } + else + { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'opensurvey_user_studs (nom, id_sondage, reponses)'; + $sql.= " VALUES ('".$db->escape($nom)."', '".$db->escape($numsondage)."','".$db->escape($nouveauchoix)."')"; + $resql=$db->query($sql); + if (! $resql) dol_print_error($db); + } + } +} + +// Update vote +$testmodifier = false; +$testligneamodifier = false; +$ligneamodifier = -1; +for ($i=0; $i<$nblignes; $i++) +{ + if (isset($_POST['modifierligne'.$i])) + { + $ligneamodifier=$i; + $testligneamodifier=true; + } + + //test pour voir si une ligne est a modifier + if (isset($_POST['validermodifier'.$i])) + { + $modifier=$i; + $testmodifier=true; + } +} +if ($testmodifier) +{ + //var_dump($_POST);exit; + $nouveauchoix = ''; + for ($i = 0; $i < $nbcolonnes; $i++) + { + //var_dump($_POST["choix$i"]); + if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '1') + { + $nouveauchoix.="1"; + } + else if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '2') + { + $nouveauchoix.="2"; + } + else { // sinon c'est 0 + $nouveauchoix.="0"; + } + } + + $idtomodify=$_POST["idtomodify".$modifier]; + $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_user_studs"; + $sql.= " SET reponses = '".$db->escape($nouveauchoix)."'"; + $sql.= " WHERE id_users = '".$db->escape($idtomodify)."'"; + + dol_syslog("sql=".$sql); + $resql = $db->query($sql); + if (! $resql) dol_print_error($db); +} + +// Add column (not for date) +if (GETPOST("ajoutercolonne") && GETPOST('nouvellecolonne') && ($object->format == "A" || $object->format == "A+")) +{ + $nouveauxsujets=$object->sujet; + + //on rajoute la valeur a la fin de tous les sujets deja entrés + $nouveauxsujets.=','; + $nouveauxsujets.=str_replace(array(",","@"), " ", $_POST["nouvellecolonne"]).(empty($_POST["typecolonne"])?'':'@'.$_POST["typecolonne"]); + + //mise a jour avec les nouveaux sujets dans la base + $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_sondage"; + $sql.= " SET sujet = '".$db->escape($nouveauxsujets)."'"; + $sql.= " WHERE id_sondage = '".$db->escape($numsondage)."'"; + dol_syslog("sql=".$sql); + $resql = $db->query($sql); + if (! $resql) dol_print_error($db); +} + +// Add column (with format date) +if (isset($_POST["ajoutercolonne"]) && ($object->format == "D" || $object->format == "D+")) +{ + $nouveauxsujets=$object->sujet; + + if (isset($_POST["nouveaujour"]) && $_POST["nouveaujour"] != "vide" && + isset($_POST["nouveaumois"]) && $_POST["nouveaumois"] != "vide" && + isset($_POST["nouvelleannee"]) && $_POST["nouvelleannee"] != "vide") { + + $nouvelledate=dol_mktime(0, 0, 0, $_POST["nouveaumois"], $_POST["nouveaujour"], $_POST["nouvelleannee"]); + + if (isset($_POST["nouvelleheuredebut"]) && $_POST["nouvelleheuredebut"]!="vide"){ + $nouvelledate.="@"; + $nouvelledate.=$_POST["nouvelleheuredebut"]; + $nouvelledate.="h"; + + if ($_POST["nouvelleminutedebut"]!="vide") { + $nouvelledate.=$_POST["nouvelleminutedebut"]; + } + } + + if (isset($_POST["nouvelleheurefin"]) && $_POST["nouvelleheurefin"]!="vide"){ + $nouvelledate.="-"; + $nouvelledate.=$_POST["nouvelleheurefin"]; + $nouvelledate.="h"; + + if ($_POST["nouvelleminutefin"]!="vide") { + $nouvelledate.=$_POST["nouvelleminutefin"]; + } + } + + if($_POST["nouvelleheuredebut"] == "vide" || (isset($_POST["nouvelleheuredebut"]) && isset($_POST["nouvelleheurefin"]) && (($_POST["nouvelleheuredebut"] < $_POST["nouvelleheurefin"]) || (($_POST["nouvelleheuredebut"] == $_POST["nouvelleheurefin"]) && ($_POST["nouvelleminutedebut"] < $_POST["nouvelleminutefin"]))))) { + $erreur_ajout_date = false; + } else { + $erreur_ajout_date = "yes"; + } + + //on rajoute la valeur dans les valeurs + $datesbase = explode(",",$object->sujet); + $taillebase = sizeof($datesbase); + + //recherche de l'endroit de l'insertion de la nouvelle date dans les dates deja entrées dans le tableau + if ($nouvelledate < $datesbase[0]) { + $cleinsertion = 0; + } elseif ($nouvelledate > $datesbase[$taillebase-1]) { + $cleinsertion = count($datesbase); + } else { + for ($i = 0; $i < count($datesbase); $i++) { + $j = $i + 1; + if ($nouvelledate > $datesbase[$i] && $nouvelledate < $datesbase[$j]) { + $cleinsertion = $j; + } + } + } + + array_splice($datesbase, $cleinsertion, 0, $nouvelledate); + $cle = array_search($nouvelledate, $datesbase); + $dateinsertion = ''; + for ($i = 0; $i < count($datesbase); $i++) { + $dateinsertion.=","; + $dateinsertion.=$datesbase[$i]; + } + + $dateinsertion = substr("$dateinsertion", 1); + + //mise a jour avec les nouveaux sujets dans la base + if (isset($erreur_ajout_date) && !$erreur_ajout_date) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_sondage"; + $sql.= " SET sujet = '".$db->escape($dateinsertion)."'"; + $sql.= " WHERE id_sondage = '".$db->escape($numsondage)."'"; + dol_syslog("sql=".$sql); + $resql = $db->query($sql); + if (! $resql) dol_print_error($db); + + if ($nouvelledate > strtotime($object->date_fin)) + { + $date_fin=$nouvelledate+200000; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'opensurvey_sondage'; + $sql.= " SET date_fin = '".$db->escape($date_fin)."'"; + $sql.= " WHERE id_sondage = '".$db->escape($numsondage)."'"; + dol_syslog("sql=".$sql); + $resql = $db->query($sql); + if (! $resql) dol_print_error($db); + } + } + + $adresseadmin = $object->mail_admin; + } + else + { + $erreur_ajout_date="yes"; + } +} + +// Delete line +for ($i = 0; $i < $nblignes; $i++) +{ + if (isset($_POST["effaceligne$i"]) || isset($_POST['effaceligne'.$i.'_x'])) + { + $compteur=0; + + // Loop on each answer + $compteur = 0; + $sql ="SELECT id_users, nom, id_sondage, reponses"; + $sql.=" FROM ".MAIN_DB_PREFIX."opensurvey_user_studs"; + $sql.=" WHERE id_sondage = '".$db->escape($numsondage)."'"; + dol_syslog('sql='.$sql); + $resql=$db->query($sql); + if (! $resql) dol_print_error($db); + $num=$db->num_rows($resql); + while ($compteur < $num) + { + $obj=$db->fetch_object($resql); + + if ($compteur==$i) + { + $sql2 = 'DELETE FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs'; + $sql2.= ' WHERE id_users = '.$db->escape($obj->id_users); + $resql2 = $db->query($sql2); + } + + $compteur++; + } + } +} + +// Delete column +for ($i = 0; $i < $nbcolonnes; $i++) +{ + if ((isset($_POST["effacecolonne$i"]) || isset($_POST['effacecolonne'.$i.'_x'])) && $nbcolonnes > 1) + { + $db->begin(); + + $toutsujet = explode(",",$object->sujet); + $j = 0; + $nouveauxsujets = ''; + + //parcours de tous les sujets actuels + while (isset($toutsujet[$j])) + { + //si le sujet n'est pas celui qui a été effacé alors on concatene + if ($i != $j) + { + if (! empty($nouveauxsujets)) $nouveauxsujets .= ','; + $nouveauxsujets .= $toutsujet[$j]; + } + + $j++; + } + + // Mise a jour des sujets dans la base + $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_sondage"; + $sql.= " SET sujet = '".$db->escape($nouveauxsujets)."' WHERE id_sondage = '".$db->escape($numsondage)."'"; + dol_syslog("sql=".$sql); + $resql = $db->query($sql); + if (! $resql) dol_print_error($db); + + // Clean current answer to remove deleted columns + $compteur = 0; + $sql ="SELECT id_users, nom, id_sondage, reponses"; + $sql.=" FROM ".MAIN_DB_PREFIX."opensurvey_user_studs"; + $sql.=" WHERE id_sondage = '".$db->escape($numsondage)."'"; + dol_syslog('sql='.$sql); + $resql=$db->query($sql); + if (! $resql) + { + dol_print_error($db); + exit; + } + $num=$db->num_rows($resql); + while ($compteur < $num) + { + $obj=$db->fetch_object($resql); + + $newcar = ''; + $ensemblereponses = $obj->reponses; + + // parcours de toutes les réponses actuelles + for ($j = 0; $j < $nbcolonnes; $j++) + { + $car=substr($ensemblereponses, $j, 1); + //si les reponses ne concerne pas la colonne effacée, on concatene + if ($i != $j) { + $newcar .= $car; + } + } + + // mise a jour des reponses utilisateurs dans la base + $sql2 = 'UPDATE '.MAIN_DB_PREFIX.'opensurvey_user_studs'; + $sql2.= " SET reponses = '".$db->escape($newcar)."'"; + $sql2.= " WHERE id_users = '".$db->escape($obj->id_users)."'"; + //print $sql2; + dol_syslog('sql='.$sql2); + $resql2 = $db->query($sql2); + + $compteur++; + } + + $db->commit(); + } +} + + + +/* + * View + */ + +$form=new Form($db); + +$result=$object->fetch(0,$numsondage); +if ($result <= 0) +{ + print $langs->trans("ErrorRecordNotFound"); + llxFooter(); + exit; +} + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeader('',$object->titre, 0, 0, 0, 0, $arrayofjs, $arrayofcss); + + +// Define format of choices +$toutsujet=explode(",",$object->sujet); +$listofanswers=array(); +foreach ($toutsujet as $value) +{ + $tmp=explode('@',$value); + $listofanswers[]=array('label'=>$tmp[0],'format'=>($tmp[1]?$tmp[1]:'checkbox')); +} +$toutsujet=str_replace("@","
",$toutsujet); +$toutsujet=str_replace("°","'",$toutsujet); + + +print '
'."\n"; + +$head = array(); + +$head[0][0] = 'adminstuds.php?sondage='.$object->id_sondage_admin; +$head[0][1] = $langs->trans("Card"); +$head[0][2] = 'general'; +$h++; + +$head[1][0] = 'adminstuds_preview.php?sondage='.$object->id_sondage_admin; +$head[1][1] = $langs->trans("SurveyResults").'/'.$langs->trans("Preview"); +$head[1][2] = 'preview'; +$h++; + +print dol_get_fiche_head($head,'preview',$langs->trans("Survey"),0,dol_buildpath('/opensurvey/img/object_opensurvey.png',1),1); + + +print ''; + +$linkback = ''.$langs->trans("BackToList").''; + +// Ref +print ''; +print ''; +print ''; + +// Type +$type=($object->format=="A"||$object->format=="A+")?'classic':'date'; +print ''; + +// Link +print '
'.$langs->trans('Ref').''; +print $form->showrefnav($object, 'sondage', $linkback, 1, 'id_sondage_admin', 'id_sondage_admin'); +print '
'.$langs->trans("Type").''; +print img_picto('',dol_buildpath('/opensurvey/img/'.($type == 'classic'?'chart-32.png':'calendar-32.png'),1),'width="16"',1); +print ' '.$langs->trans($type=='classic'?"TypeClassic":"TypeDate").'
'.img_picto('','object_globe.png').' '.$langs->trans("UrlForSurvey",'').''; + +// Define $urlwithroot +$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + +$url=$urlwithouturlroot.dol_buildpath('/opensurvey/public/studs.php',1).'?sondage='.$numsondage; +$urlvcal=''.$url.''; +print $urlvcal; + + +print '
'; + +dol_fiche_end(); + +print '
'."\n"; + +print ''; + + +showlogo(); + + +// Add form to add a field +if (GETPOST('ajoutsujet')) +{ + //on recupere les données et les sujets du sondage + print '
'."\n"; + print ''; + print ''; + + print '
'."\n"; + print "

"."\n"; + + // Add new column + if ($object->format=="A"||$object->format=="A+") + { + print $langs->trans("AddNewColumn") .' :

'; + print $langs->trans("Title").'
'; + $tmparray=array('checkbox'=>$langs->trans("CheckBox"),'yesno'=>$langs->trans("YesNoList"),'foragainst'=>$langs->trans("PourContreList")); + print $langs->trans("Type").' '.$form->selectarray("typecolonne", $tmparray, GETPOST('typecolonne')).'

'; + print ''; + print '     '; + print ''; + print '

'."\n"; + } + else + { + //ajout d'une date avec creneau horaire + //print _("You can add a new scheduling date to your poll.
If you just want to add a new hour to an existant date, put the same date and choose a new hour.") .'

'."\n"; + print $langs->trans("AddADate") .' :

'."\n"; + print ''."\n"; + + print ''."\n"; + + + print ''."\n"; + print '

'. $langs->trans("AddStartHour") .' :

'."\n"; + print ''."\n"; + print ''."\n"; + print '

'. $langs->trans("AddEndHour") .' :

'."\n"; + print ''."\n"; + print ''."\n"; + + print '

'; + print' '."\n"; + print '   '; + print ''; + } + + print ''."\n"; + print '



'."\n"; + print '
'."\n"; + + exit; +} + + +print $langs->trans("PollAdminDesc",img_picto('','cancel.png@opensurvey'),img_picto('','add-16.png@opensurvey')).'

'; + +print '
'."\n"; + +//affichage du titre du sondage +$titre=str_replace("\\","",$object->titre); +print ''.$titre.'
'."\n"; + +//affichage du nom de l'auteur du sondage +print $langs->trans("InitiatorOfPoll") .' : '.$object->nom_admin.'
'."\n"; + +//affichage des commentaires du sondage +if ($object->commentaires) +{ + print '
'.$langs->trans("Description") .' :
'."\n"; + $commentaires=dol_nl2br($object->commentaires); + print $commentaires; + print '
'."\n"; +} + +print '
'."\n"; + + +$nbcolonnes=substr_count($object->sujet,',')+1; + +print '
'."\n"; +print ''; + +print '
'."\n"; +print '
'."\n"; + +//debut de l'affichage de résultats +print ''."\n"; + +//reformatage des données des sujets du sondage +$toutsujet=explode(",",$object->sujet); +$toutsujet=str_replace("°","'",$toutsujet); + +print ''."\n"; +print ''."\n"; +print ''."\n"; + +//boucle pour l'affichage des boutons de suppression de colonne +for ($i = 0; isset($toutsujet[$i]); $i++) { + print ''."\n"; +} + +print ''."\n"; + + +// Show choice titles +if ($object->format=="D"||$object->format=="D+") +{ + //affichage des sujets du sondage + print ''."\n"; + print ''."\n"; + print ''."\n"; + + //affichage des années + $colspan=1; + for ($i=0;$i'.strftime("%Y", $current).''."\n"; + $colspan=1; + } + } + + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + + //affichage des mois + $colspan = 1; + for ($i = 0; $i < count($toutsujet); $i++) { + $cur = intval($toutsujet[$i]); // intval() est utiliser pour supprimer le suffixe @* qui déplaît logiquement à strftime() + + if (isset($toutsujet[$i+1]) === false) { + $next = false; + } else { + $next = intval($toutsujet[$i+1]); + } + + if ($next && dol_print_date($cur, "%B") == dol_print_date($next, "%B") && dol_print_date($cur, "%Y") == dol_print_date($next, "%Y")){ + $colspan++; + } else { + print ''."\n"; + + $colspan=1; + } + } + + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + + //affichage des jours + $colspan = 1; + for ($i = 0; $i < count($toutsujet); $i++) { + $cur = intval($toutsujet[$i]); + if (isset($toutsujet[$i+1]) === false) { + $next = false; + } else { + $next = intval($toutsujet[$i+1]); + } + if ($next && dol_print_date($cur, "%a %e") == dol_print_date($next,"%a %e") && dol_print_date($cur, "%B") == dol_print_date($next, "%B")) { + $colspan++; + } else { + print ''."\n"; + + $colspan=1; + } + } + + print ''."\n"; + print ''."\n"; + + //affichage des horaires + if (strpos($object->sujet,'@') !== false) { + print ''."\n"; + print ''."\n"; + print ''."\n"; + + for ($i = 0; isset($toutsujet[$i]); $i++) { + $heures=explode('@', $toutsujet[$i]); + if (isset($heures[1])) { + print ''."\n"; + } else { + print ''."\n"; + } + } + + print ''."\n"; + print ''."\n"; + } +} +else +{ + //affichage des sujets du sondage + print ''."\n"; + print ''."\n"; + print ''."\n"; + + for ($i = 0; isset($toutsujet[$i]); $i++) + { + $tmp=explode('@',$toutsujet[$i]); + print ''."\n"; + } + + print ''."\n"; + print ''."\n"; +} + + +// Loop on each answer +$sumfor = array(); +$sumagainst = array(); +$compteur = 0; +$sql ="SELECT id_users, nom, id_sondage, reponses"; +$sql.=" FROM ".MAIN_DB_PREFIX."opensurvey_user_studs"; +$sql.=" WHERE id_sondage = '".$db->escape($numsondage)."'"; +dol_syslog('sql='.$sql); +$resql=$db->query($sql); +if (! $resql) +{ + dol_print_error($db); + exit; +} +$num=$db->num_rows($resql); +while ($compteur < $num) +{ + $obj=$db->fetch_object($resql); + + $ensemblereponses = $obj->reponses; + + print ''."\n"; + print ''."\n"; + + // Name + $nombase=str_replace("°","'",$obj->nom); + print ''."\n"; + + // si la ligne n'est pas a changer, on affiche les données + if (! $testligneamodifier) + { + for ($i = 0; $i < $nbcolonnes; $i++) + { + $car = substr($ensemblereponses, $i, 1); + //print 'xx'.$i."-".$car.'-'.$listofanswers[$i]['format'].'zz'; + + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + if (((string) $car) == "1") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + if (((string) $car) == "1") print ''."\n"; + else if (((string) $car) == "0") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (! isset($sumagainst[$i])) $sumagainst[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + if (((string) $car) == "0") $sumagainst[$i]++; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + if (((string) $car) == "1") print ''."\n"; + else if (((string) $car) == "0") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (! isset($sumagainst[$i])) $sumagainst[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + if (((string) $car) == "0") $sumagainst[$i]++; + } + } + } + else + { + //sinon on remplace les choix de l'utilisateur par une ligne de checkbox pour recuperer de nouvelles valeurs + if ($compteur == $ligneamodifier) + { + for ($i = 0; $i < $nbcolonnes; $i++) + { + $car = substr($ensemblereponses, $i, 1); + print ''."\n"; + } + } + else + { + for ($i = 0; $i < $nbcolonnes; $i++) + { + $car = substr($ensemblereponses, $i, 1); + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + if (((string) $car) == "1") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + if (((string) $car) == "1") print ''."\n"; + else if (((string) $car) == "0") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (! isset($sumagainst[$i])) $sumagainst[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + if (((string) $car) == "0") $sumagainst[$i]++; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + if (((string) $car) == "1") print ''."\n"; + else if (((string) $car) == "0") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (! isset($sumagainst[$i])) $sumagainst[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + if (((string) $car) == "0") $sumagainst[$i]++; + } + } + } + } + + //a la fin de chaque ligne se trouve les boutons modifier + if ($compteur != $ligneamodifier) + { + print ''."\n"; + } + + //demande de confirmation pour modification de ligne + for ($i = 0; $i < $nblignes; $i++) + { + if (isset($_POST["modifierligne".$i])) + { + if ($compteur == $i) + { + print ''."\n"; + } + } + } + + $compteur++; + print ''."\n"; +} + +// Add line to add new record +if (empty($testligneamodifier)) +{ + print ''."\n"; + print ''."\n"; + print ''."\n"; + + for ($i = 0; $i < $nbcolonnes; $i++) + { + print ''."\n"; + } + + // Affichage du bouton de formulaire pour inscrire un nouvel utilisateur dans la base + print ''."\n"; + print ''."\n"; +} + +// Select value of best choice (for checkbox columns only) +$nbofcheckbox=0; +for ($i=0; $i < $nbcolonnes + 1; $i++) +{ + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + $nbofcheckbox++; + if (isset($sumfor[$i])) + { + if ($i == 0) { + $meilleurecolonne = $sumfor[$i]; + } + if (isset($sumfor[$i]) && $sumfor[$i] > $meilleurecolonne){ + $meilleurecolonne = $sumfor[$i]; + } + } +} + + +// Show line total +print ''."\n"; +print ''."\n"; +print ''."\n"; +for ($i = 0; $i < $nbcolonnes; $i++) +{ + $showsumfor = isset($sumfor[$i])?$sumfor[$i]:''; + $showsumagainst = isset($sumagainst[$i])?$sumagainst[$i]:''; + if (empty($showsumfor)) $showsumfor = 0; + if (empty($showsumagainst)) $showsumagainst = 0; + + print ''."\n"; +} +print ''; +// Show picto winner +if ($nbofcheckbox >= 2) +{ + print ''."\n"; + print ''."\n"; + print ''."\n"; + for ($i = 0; $i < $nbcolonnes; $i++) { + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst')) && isset($sumfor[$i]) && isset($meilleurecolonne) && $sumfor[$i] == $meilleurecolonne) + { + print ''."\n"; + } else { + print ''."\n"; + } + } + print ''."\n"; +} + +// S'il a oublié de remplir un nom +if ((isset($_POST["boutonp"]) || isset($_POST["boutonp_x"])) && $_POST["nom"] == "") { + print ''."\n"; + print "'."\n"; +} + +if (isset($erreur_prenom) && $erreur_prenom) { + print ''."\n"; + print "\n"; + print ''."\n"; +} + +if (isset($erreur_injection) && $erreur_injection) { + print ''."\n"; + print "\n"; + print ''."\n"; +} + +if (isset($erreur_ajout_date) && $erreur_ajout_date) { + print ''."\n"; + print "\n"; + print ''."\n"; +} + +//fin du tableau +print '
id_sondage_admin.'">'.$langs->trans("Add").'
'.dol_print_date($cur, "%B").'id_sondage_admin.'">'.$langs->trans("Add").'
'.dol_print_date($cur, "%a %e").'id_sondage_admin.'">'.$langs->trans("Add").'
'.$heures[1].'id_sondage_admin.'">'.$langs->trans("Add").'
'.$tmp[0].''.img_picto('',dol_buildpath('/opensurvey/img/add-16.png',1),'',1).'
'.$nombase.'OKKO'.$langs->trans("Yes").''.$langs->trans("No").' '.$langs->trans("For").''.$langs->trans("Against").' '; + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + print ''; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("No"),'1'=>$langs->trans("Yes")); + print $form->selectarray("choix".$i, $arraychoice, $car); + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("Against"),'1'=>$langs->trans("For")); + print $form->selectarray("choix".$i, $arraychoice, $car); + } + print 'OKKO'.$langs->trans("For").''.$langs->trans("Against").' '.$langs->trans("For").''.$langs->trans("Against").' '; + print ''; + print ''; + print '
'."\n"; + print ''."\n"; + print ''; + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + print ''; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("No"),'1'=>$langs->trans("Yes")); + print $form->selectarray("choix".$i, $arraychoice); + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("Against"),'1'=>$langs->trans("For")); + print $form->selectarray("choix".$i, $arraychoice); + } + print '
'. $langs->trans("Total") .''; + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) print $showsumfor; + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') print $langs->trans("Yes").': '.$showsumfor.'
'.$langs->trans("No").': '.$showsumagainst; + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') print $langs->trans("For").': '.$showsumfor.'
'.$langs->trans("Against").': '.$showsumagainst; + print '
" . _("Enter a name !") . "\n"; + print '
" . _("The name you've chosen already exist in this poll!") . "
" . _("Characters \" ' < et > are not permitted") . "
" . _("The date is not correct !") . "
'."\n"; +print '
'."\n"; + + +$toutsujet = explode(",", $object->sujet); + +$compteursujet = 0; +$meilleursujet = ''; +for ($i = 0; $i < $nbcolonnes; $i++) { + if (isset($sumfor[$i]) === true && isset($meilleurecolonne) === true && $sumfor[$i] == $meilleurecolonne){ + $meilleursujet.=", "; + + if ($object->format == "D" || $object->format == "D+") { + $meilleursujetexport = $toutsujet[$i]; + + if (strpos($toutsujet[$i], '@') !== false) { + $toutsujetdate = explode("@", $toutsujet[$i]); + $meilleursujet .= dol_print_date($toutsujetdate[0],'daytext'). ' ('.dol_print_date($toutsujetdate[0],'%A').')' . ' - ' . $toutsujetdate[1]; + } else { + $meilleursujet .= dol_print_date($toutsujet[$i],'daytext'). ' ('.dol_print_date($toutsujet[$i],'%A').')'; + } + } + else + { + $tmps=explode('@',$toutsujet[$i]); + $meilleursujet .= $tmps[0]; + } + + $compteursujet++; + } +} + +//adaptation pour affichage des valeurs +$meilleursujet = substr("$meilleursujet", 1); +$meilleursujet = str_replace("°", "'", $meilleursujet); + +// Show best choice +if ($nbofcheckbox >= 2) +{ + $vote_str = $langs->trans('votes'); + print '

'."\n"; + + if (isset($meilleurecolonne) && $compteursujet == "1") { + print " " . $langs->trans('TheBestChoice') . " : $meilleursujet " . $langs->trans("with") . " $meilleurecolonne " . $vote_str . ".
\n"; + } elseif (isset($meilleurecolonne)) { + print " " . $langs->trans('TheBestChoices') . " : $meilleursujet " . $langs->trans("with") . " $meilleurecolonne " . $vote_str . ".
\n"; + } + print '


'."\n"; +} + +print '
'."\n"; + +llxFooterSurvey(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php new file mode 100644 index 00000000000..7cdfd1e4c7e --- /dev/null +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -0,0 +1,512 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file dev/skeletons/opensurveysondage.class.php + * \ingroup mymodule othermodule1 othermodule2 + * \brief This file is an example for a CRUD class file (Create/Read/Update/Delete) + * Initialy built by build_class_from_table on 2013-03-10 00:32 + */ + +// Put here all includes required by your class file +require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php"); +//require_once(DOL_DOCUMENT_ROOT."/societe/class/societe.class.php"); +//require_once(DOL_DOCUMENT_ROOT."/product/class/product.class.php"); + + +/** + * Put here description of your class + */ +class Opensurveysondage extends CommonObject +{ + var $db; //!< To store db handler + var $error; //!< To return error code (or message) + var $errors=array(); //!< To return several error codes (or messages) + var $element='opensurvey_sondage'; //!< Id that identify managed objects + var $table_element='opensurvey_sondage'; //!< Name of table without prefix where object is stored + + var $id; + + var $id_sondage; + var $commentaires; + var $mail_admin; + var $nom_admin; + var $titre; + var $id_sondage_admin; + var $date_fin=''; + var $format; + var $mailsonde; + var $survey_link_visible; + var $canedit; + + + + + /** + * Constructor + * + * @param DoliDb $db Database handler + */ + function __construct($db) + { + $this->db = $db; + return 1; + } + + + /** + * Create object into database + * + * @param User $user User that creates + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, Id of created object if OK + */ + function create($user, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + + if (isset($this->id_sondage)) $this->id_sondage=trim($this->id_sondage); + if (isset($this->commentaires)) $this->commentaires=trim($this->commentaires); + if (isset($this->mail_admin)) $this->mail_admin=trim($this->mail_admin); + if (isset($this->nom_admin)) $this->nom_admin=trim($this->nom_admin); + if (isset($this->titre)) $this->titre=trim($this->titre); + if (isset($this->id_sondage_admin)) $this->id_sondage_admin=trim($this->id_sondage_admin); + if (isset($this->format)) $this->format=trim($this->format); + if (isset($this->mailsonde)) $this->mailsonde=trim($this->mailsonde); + if (isset($this->survey_link_visible)) $this->survey_link_visible=trim($this->survey_link_visible); + if (isset($this->canedit)) $this->canedit=trim($this->canedit); + + + + // Check parameters + // Put here code to add control on parameters values + + // Insert request + $sql = "INSERT INTO ".MAIN_DB_PREFIX."opensurvey_sondage("; + + $sql.= "id_sondage,"; + $sql.= "commentaires,"; + $sql.= "mail_admin,"; + $sql.= "nom_admin,"; + $sql.= "titre,"; + $sql.= "id_sondage_admin,"; + $sql.= "date_fin,"; + $sql.= "format,"; + $sql.= "mailsonde,"; + $sql.= "survey_link_visible,"; + $sql.= "canedit"; + $sql.= ") VALUES ("; + + $sql.= " ".(! isset($this->id_sondage)?'NULL':"'".$this->id_sondage."'").","; + $sql.= " ".(! isset($this->commentaires)?'NULL':"'".$this->db->escape($this->commentaires)."'").","; + $sql.= " ".(! isset($this->mail_admin)?'NULL':"'".$this->db->escape($this->mail_admin)."'").","; + $sql.= " ".(! isset($this->nom_admin)?'NULL':"'".$this->db->escape($this->nom_admin)."'").","; + $sql.= " ".(! isset($this->titre)?'NULL':"'".$this->db->escape($this->titre)."'").","; + $sql.= " ".(! isset($this->id_sondage_admin)?'NULL':"'".$this->id_sondage_admin."'").","; + $sql.= " ".(! isset($this->date_fin) || dol_strlen($this->date_fin)==0?'NULL':$this->db->idate($this->date_fin)).","; + $sql.= " ".(! isset($this->format)?'NULL':"'".$this->db->escape($this->format)."'").","; + $sql.= " ".(! isset($this->mailsonde)?'NULL':"'".$this->mailsonde."'").","; + $sql.= " ".(! isset($this->survey_link_visible)?'NULL':"'".$this->survey_link_visible."'").","; + $sql.= " ".(! isset($this->canedit)?'NULL':"'".$this->canedit."'").""; + + $sql.= ")"; + + $this->db->begin(); + + dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."opensurvey_sondage"); + + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_CREATE',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return $this->id; + } + } + + + /** + * Load object in memory from the database + * + * @param int $id Id object + * @param string $numsurvey Ref of survey (admin or not) + * @return int <0 if KO, >0 if OK + */ + function fetch($id,$numsurvey='') + { + global $langs; + + $sql = "SELECT"; + //$sql.= " t.rowid,"; + $sql.= " t.id_sondage,"; + $sql.= " t.commentaires,"; + $sql.= " t.mail_admin,"; + $sql.= " t.nom_admin,"; + $sql.= " t.titre,"; + $sql.= " t.id_sondage_admin,"; + $sql.= " t.date_fin,"; + $sql.= " t.format,"; + $sql.= " t.mailsonde,"; + $sql.= " t.survey_link_visible,"; + $sql.= " t.canedit,"; + $sql.= " t.sujet,"; + $sql.= " t.tms"; + $sql.= " FROM ".MAIN_DB_PREFIX."opensurvey_sondage as t"; + if ($id > 0) $sql.= " WHERE t.rowid = ".$id; + else if (strlen($numsurvey) == 16) $sql.= " WHERE t.id_sondage = '".$numsurvey."'"; + else $sql.= " WHERE t.id_sondage_admin = '".$numsurvey."'"; + + dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + //$this->id = $obj->rowid; + $this->ref = $obj->id_sondage_admin; + + $this->id_sondage = $obj->id_sondage; + $this->commentaires = $obj->commentaires; + $this->mail_admin = $obj->mail_admin; + $this->nom_admin = $obj->nom_admin; + $this->titre = $obj->titre; + $this->id_sondage_admin = $obj->id_sondage_admin; + $this->date_fin = $this->db->jdate($obj->date_fin); + $this->format = $obj->format; + $this->mailsonde = $obj->mailsonde; + $this->survey_link_visible = $obj->survey_link_visible; + $this->canedit = $obj->canedit; + $this->sujet = $obj->sujet; + + $this->date_m = $this->db->jdate($obj->tls); + $ret=1; + } + else $ret=0; + + $this->db->free($resql); + } + else + { + $this->error="Error ".$this->db->lasterror(); + dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR); + $ret=-1; + } + + return $ret; + } + + + /** + * Update object into database + * + * @param User $user User that modifies + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @return int <0 if KO, >0 if OK + */ + function update($user=0, $notrigger=0) + { + global $conf, $langs; + $error=0; + + // Clean parameters + + if (isset($this->id_sondage)) $this->id_sondage=trim($this->id_sondage); + if (isset($this->commentaires)) $this->commentaires=trim($this->commentaires); + if (isset($this->mail_admin)) $this->mail_admin=trim($this->mail_admin); + if (isset($this->nom_admin)) $this->nom_admin=trim($this->nom_admin); + if (isset($this->titre)) $this->titre=trim($this->titre); + if (isset($this->id_sondage_admin)) $this->id_sondage_admin=trim($this->id_sondage_admin); + if (isset($this->format)) $this->format=trim($this->format); + if (isset($this->mailsonde)) $this->mailsonde=trim($this->mailsonde); + if (isset($this->survey_link_visible)) $this->survey_link_visible=trim($this->survey_link_visible); + if (isset($this->canedit)) $this->canedit=trim($this->canedit); + + + // Check parameters + // Put here code to add a control on parameters values + + // Update request + $sql = "UPDATE ".MAIN_DB_PREFIX."opensurvey_sondage SET"; + + $sql.= " id_sondage='".(isset($this->id_sondage)?$this->id_sondage:"null")."',"; + $sql.= " commentaires=".(isset($this->commentaires)?"'".$this->db->escape($this->commentaires)."'":"null").","; + $sql.= " mail_admin=".(isset($this->mail_admin)?"'".$this->db->escape($this->mail_admin)."'":"null").","; + $sql.= " nom_admin=".(isset($this->nom_admin)?"'".$this->db->escape($this->nom_admin)."'":"null").","; + $sql.= " titre=".(isset($this->titre)?"'".$this->db->escape($this->titre)."'":"null").","; + $sql.= " id_sondage_admin='".(isset($this->id_sondage_admin)?$this->id_sondage_admin:"null")."',"; + $sql.= " date_fin=".(dol_strlen($this->date_fin)!=0 ? "'".$this->db->idate($this->date_fin)."'" : 'null').","; + $sql.= " format=".(isset($this->format)?"'".$this->db->escape($this->format)."'":"null").","; + $sql.= " mailsonde=".(isset($this->mailsonde)?$this->mailsonde:"null").","; + $sql.= " survey_link_visible=".(isset($this->survey_link_visible)?$this->survey_link_visible:"null").","; + $sql.= " canedit=".(isset($this->canedit)?$this->canedit:"null").""; + + //$sql.= " WHERE rowid=".$this->id; + $sql.= " WHERE id_sondage_admin='".$this->id_sondage_admin."'"; + + $this->db->begin(); + + dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + + if (! $error) + { + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_MODIFY',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + + /** + * Delete object in database + * + * @param User $user User that deletes + * @param int $notrigger 0=launch triggers after, 1=disable triggers + * @param string $numsondageadmin Num sondage to delete + * @return int <0 if KO, >0 if OK + */ + function delete($user, $notrigger=0, $numsondageadmin) + { + global $conf, $langs; + $error=0; + + $this->db->begin(); + + if (! $error) + { + if (! $notrigger) + { + // Uncomment this and change MYOBJECT to your own tag if you + // want this action calls a trigger. + + //// Call triggers + //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php'; + //$interface=new Interfaces($this->db); + //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf); + //if ($result < 0) { $error++; $this->errors=$interface->errors; } + //// End call triggers + } + } + + if (! $error) + { + + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$numsondageadmin."'"; + dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$numsondageadmin."'"; + dol_syslog(get_class($this)."::delete sql=".$sql, LOG_DEBUG); + $resql=$this->db->query($sql); + + $sql = "DELETE FROM ".MAIN_DB_PREFIX."opensurvey_sondage"; + $sql.= " WHERE id_sondage_admin = '".$numsondageadmin."'"; + + dol_syslog(get_class($this)."::delete sql=".$sql); + $resql = $this->db->query($sql); + if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); } + } + + // Commit or rollback + if ($error) + { + foreach($this->errors as $errmsg) + { + dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); + $this->error.=($this->error?', '.$errmsg:$errmsg); + } + $this->db->rollback(); + return -1*$error; + } + else + { + $this->db->commit(); + return 1; + } + } + + /** + * Return array of lines + * + * @return array Array of lines + */ + function fetch_lines() + { + $ret=array(); + $sql = "SELECT id_users, nom, reponses FROM ".MAIN_DB_PREFIX."opensurvey_user_studs"; + $sql.= " WHERE id_sondage = '".$this->id_sondage."'"; + $resql=$this->db->query($sql); + + if ($resql) + { + $num=$this->db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj=$this->db->fetch_object($resql); + $tmp=array('id_users'=>$obj->id_users, 'nom'=>$obj->nom, 'reponses'=>$obj->reponses); + + $ret[]=$tmp; + $i++; + } + } + else dol_print_error($this->db); + + $this->lines=$ret; + + return $this->lines; + } + + /** + * Load an object from its id and create a new one in database + * + * @param int $fromid Id of object to clone + * @return int New id of clone + */ + function createFromClone($fromid) + { + global $user,$langs; + + $error=0; + + $object=new Opensurveysondage($this->db); + + $this->db->begin(); + + // Load source object + $object->fetch($fromid); + $object->id=0; + $object->statut=0; + + // Clear fields + // ... + + // Create clone + $result=$object->create($user); + + // Other options + if ($result < 0) + { + $this->error=$object->error; + $error++; + } + + if (! $error) + { + + + } + + // End + if (! $error) + { + $this->db->commit(); + return $object->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + + /** + * Initialise object with example values + * Id must be 0 if object instance is a specimen + * + * @return void + */ + function initAsSpecimen() + { + $this->id=0; + + $this->id_sondage=''; + $this->commentaires=''; + $this->mail_admin=''; + $this->nom_admin=''; + $this->titre=''; + $this->id_sondage_admin=''; + $this->date_fin=''; + $this->format=''; + $this->mailsonde=''; + $this->survey_link_visible=''; + $this->canedit=0; + } + +} +?> diff --git a/htdocs/opensurvey/css/style.css b/htdocs/opensurvey/css/style.css new file mode 100644 index 00000000000..be8e05df4c1 --- /dev/null +++ b/htdocs/opensurvey/css/style.css @@ -0,0 +1,532 @@ +/* Copyright (C) 2004-2013 Laurent Destailleur + * Copyright (C) 2006 Rodolphe Quiedeville + * Copyright (C) 2007-2012 Regis Houssin + * Copyright (C) 2011 Philippe Grand + * Copyright (C) 2012 Juanjo Menent + * + * 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 . + */ + +.survey_invitation +{ + font-color: #445566; + font-weight: bold; +} + +.corps { +font-family: "Lucida Grande",Verdana,Arial,sans-serif; +font-size: 14px; +margin: auto; +padding: 20px; +overflow-x: auto; +border: 2px solid #999999; +background-color: #fff; +box-shadow: 2px 2px 2px #F5F5F5; +-moz-border-radius: 10px; +border-radius: 10px; +} + + +.index_date, .index_sondage { +float: left; +width: 50%; +text-align: center; +} + +.orange { +color: #fef4e9; +border: solid 1px #da7c0c; +background: #f78d1d; +background: -webkit-gradient(linear, left top, left bottom, from(#faa51a), to(#f47a20)); +background: -moz-linear-gradient(top, #faa51a, #f47a20); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#faa51a', endColorstr='#f47a20'); +} +.orange:active { +color: #fcd3a5; +background: -webkit-gradient(linear, left top, left bottom, from(#f47a20), to(#faa51a)); +background: -moz-linear-gradient(top, #f47a20, #faa51a); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f47a20', endColorstr='#faa51a'); +} +.orange:hover { +background: #f47c20; +background: -webkit-gradient(linear, left top, left bottom, from(#f88e11), to(#f06015)); +background: -moz-linear-gradient(top, #f88e11, #f06015); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f88e11', endColorstr='#f06015'); +} + + +.blue { +color: #d9eef7; +border: solid 1px #0076a3; +background: #0095cd; +background: -webkit-gradient(linear, left top, left bottom, from(#00adee), to(#0078a5)); +background: -moz-linear-gradient(top, #00adee, #0078a5); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00adee', endColorstr='#0078a5'); +} +.blue:active { +color: #80bed6; +background: -webkit-gradient(linear, left top, left bottom, from(#0078a5), to(#00adee)); +background: -moz-linear-gradient(top, #0078a5, #00adee); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0078a5', endColorstr='#00adee'); +} +.blue:hover { +background: #007ead; +background: -webkit-gradient(linear, left top, left bottom, from(#0095cc), to(#00678e)); +background: -moz-linear-gradient(top, #0095cc, #00678e); +filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0095cc', endColorstr='#00678e'); +} + + +/* +========================================================================== + +Université de Strasbourg - Direction Informatique +Auteur : Guilhem BORGHESI +Création : Février 2008 + +borghesi@unistra.fr + +Ce logiciel est régi par la licence CeCILL-B soumise au droit français et +respectant les principes de diffusion des logiciels libres. Vous pouvez +utiliser, modifier et/ou redistribuer ce programme sous les conditions +de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA +sur le site "http://www.cecill.info". + +Le fait que vous puissiez accéder à cet en-tête signifie que vous avez +pris connaissance de la licence CeCILL-B, et que vous en avez accepté les +termes. Vous pouvez trouver une copie de la licence dans le fichier LICENCE. + +========================================================================== + +Université de Strasbourg - Direction Informatique +Author : Guilhem BORGHESI +Creation : Feb 2008 + +borghesi@unistra.fr + +This software is governed by the CeCILL-B license under French law and +abiding by the rules of distribution of free software. You can use, +modify and/ or redistribute the software under the terms of the CeCILL-B +license as circulated by CEA, CNRS and INRIA at the following URL +"http://www.cecill.info". + +The fact that you are presently reading this means that you have had +knowledge of the CeCILL-B license and that you accept its terms. You can +find a copy of this license in the file LICENSE. + +========================================================================== +*/ + +/* +Le fichier style.css est le fichier de style de studs. Il se trouve à la racine +du répertoire studs. Il contient toutes les mises en forme des fichiers PHP +de Studs. +*/ +/*bandeau de titre*/ +div.bandeau{ + line-height:35px; + text-align:center; + background-color: #0b419b; + color:white; + vertical-align:middle; + font-size:35px; + font-family:arial; + padding:8px; + height:35px; + position:static; + top:6px; + left:6px; + right:6px; + +} +div.logo{ + height:64px; + float:right; + top:8px; + right:8px; + margin-left: 0; + margin-right:0; + margin-bottom:auto; +} +/*Sous bandeau avec bouton de navigation*/ +div.bandeautitre{ + height:17px; + font-size:14px; + font-weight:bold; + text-align:center; + vertical-align:middle; + font-family:arial; + padding:3px; + position:static; + top:57px; + left:6px; + right:6px; +} +div.sousbandeau{ + height:17px; + background-color: #DDDDDD; + font-size:11px; + color:black; + vertical-align:middle; + font-family:arial; + padding:3px; + position:static; + top:80px; + left:6px; + right:6px; +} +/*bandeau de pied*/ +div.surbandeaupied{ + background-color: #0077DD; + position:absolute; + bottom:30px; + left:6px; + right:6px; + height:6px; +} +div.bandeaupied{ + text-align:center; + background-color: #0b419b; + color:white; + font-size:11px; + font-family:arial; + padding:6px; + position:fixed; + bottom:6px; + left:6px; + right:6px; + margin:2px; +} +div.surbandeaupiedmobile{ + background-color: #0077DD; + position:static; + bottom:32px; + left:6px; + right:6px; + height:6px; +} +div.bandeaupiedmobile{ + text-align:center; + background-color: #0b419b; + color:white; + font-size:11px; + font-family:arial; + padding:6px; + position:static; +} +/*les boutons se trouvant dans le sousbandeau*/ +div.sousbandeau a, div.sousbandeau span.sousbandeaulangue a { + background-color: #0b419b; + height:16px; + padding: 2px 6px 2px 6px; + vertical-align:middle; + text-align:center; + margin-left:10px; + margin-right:10px; + font-family:arial; + color:white; + font-size:10px; + text-decoration:none; +} +span.sousbandeaulangue { + margin-left:6px; + margin-right:6px; + float:right; +} +/*corps de la page index.php*/ +div.corps{ + font-size:12px; + font-family:arial; + position:static; + padding:15px; +} +div.corps table{ + font-family:arial; + font-size:12px; + font-weight:bold; +} +div.corpscentre{ + font-size:12px; + font-family:arial; + text-align:center; + position:absolute; + top:150px; + margin-right:10%; + margin-left:10%; + width:80%; +} +/*affichage des jours*/ +div.jourschoisis { + background-color: #DDD; + padding:10px; + text-align: center; + position:static; + left:700px; + top:170px; + font-size:12px; + width:100%; +} +/*presenation des pages*/ +div.bodydate { + padding:10px; + font-family:arial; + font-size:12px; + text-align:center; + position:static; + top:330px; + left:20px; + right:20px; +} +div.bodydate table{ + font-family:arial; + font-size:12px; + font-weight:bold; +} +/*cadre de commentaires*/ +div.presentationdate { + width:100%; + font-family:arial; + text-align:center; + font-size:12px; + border-top:1px solid; + border-bottom:1px solid; + border-left: none; + border-right: none; + border-color:#969696; + position:static; + top:110px; + margin-top:10px; +} +div.presentationdatefin { + width:40%; + padding:10px; + font-family:arial; + text-align:center; + font-size:12px; + border-width:1px; + border-style:solid; + margin-top: 10px; + margin-left: 30%; + margin-right: 30%; + position:static; +} +/*cadre principal de studs.php*/ +div.cadre { + padding:10px; + font-family:arial; + font-size:12px; + position:static; + top:235px; + text-align:center; + margin:0 auto; +} +/*la table des résultats dans l'affichage de sondage*/ +div.cadre table.resultats { + text-align: center; + margin:0 auto; +} +td.nom { + min-width: 160px; +} +td.vide { + min-width: 60px; +} +div.cadre td { + height:21px; +} +/*case de tableau OK dans affichage de sondage*/ +div.cadre td.ok { + background-color: #66FF99; + font-size:12px; + text-align:center; +} +/*Case de tableau NON dans affichage de sondage*/ +div.cadre td.non { + background-color: #FF7777; + min-width: 60px; +} +/*Case de tableau VIDE dans affichage de sondage*/ +div.cadre td.vide { + background-color: #DDDDDD; + text-align:center; +} +/*Case de tableau contenant les noms dans affichage de sondage*/ +div.cadre td.nom { + background-color: #DDDDDD; + font-size:12px; + text-align:center; +} +div.cadre td.casevide { + background-color: white; + text-align:center; +} +/*les cases contenant les sommes de chaque colonne dans l'affichage de calendrier*/ +div.cadre td.somme { + font-weight: bold; + font-size:14px; +} + +/*Case de tableau SUJET dans affichage de sondage*/ +div.cadre td.sujet, div.cadre td.jour, div.cadre td.heure { + border: 2px; + background-color: #DDDDDD; + font-size:14px; + padding:1px 5px; +} + +div.cadre td.annee { + border: 2px; + background-color: #969696; + font-weight: bold; + font-size:14px; + padding:1px 5px; +} +div.cadre td.mois { + border: 2px; + background-color: #C0C0C0; + font-weight: bold; + font-size:14px; + padding:1px 5px; +} + +/*affichage du calendrier*/ +div.calendrier { + padding:10px; + background-color: #AAA; + width:490px; + font-size:12px; + font-family:arial; + margin-left: 30%; + margin-right: 30%; + position:static; +} +/*jour de la semaine dans calendrier*/ +div.calendrier td.joursemaine { + width:65px; + text-align: center; + font-family:arial; + font-size:14px; + border: 2px; + background-color: white; +} +div.calendrier td.jourwe { + width:65px; + text-align: center; + font-family:arial; + font-size:14px; + border: 2px; + background-color: #C0C0C0; +} +/*jour avant le premier jour du mois dans calendrier*/ +div.calendrier td.avant { + width:65px; + text-align: center; + border: 2px; + font-family:arial; + font-size:13px; + background-color: #DDDDDD; +} +/*jour libre dans calendrier*/ +div.calendrier td.libre { + width:65px; + text-align: center; + border: 2px; + background-color: #66FF99; +} +/*jour deja selectionné dans calendrier*/ +div.calendrier td.choisi { + width:65px; + text-align: center; + border: 2px; + background-color: #0077DD; +} +/* Le paragraphe de fin */ +p.affichageresultats{ + text-align: center; + font-family:arial; + font-size:13px; +} + +div.comment{ + width:100%; +} + +div.comment span.usercomment{ + font-weight:bold; +} + +a.affichageexport{ + text-align: center; + font-family:arial; + font-size:10px; + margin-left:10px; + text-decoration: none; +} +div.titregestionadmin{ + text-align: center; + font-weight:bold; + font-size:18px; + padding:10px; +} + + +.bouton { + width: 65px; + border:0px; + padding:0px 0 0 0; + margin:0px; + cursor:pointer; + font-family:arial; + font-size:13px; +} +/*les boutons pour choisir un jour non selectionné*/ +.ON { + background-color: #BBBBCC; +} + +/*les boutons pour deselectionner un jour deja choisi*/ +.OFF { + background-color: #AAFFAA; +} + +div.nouveau_sondage a { + text-decoration: none; +} +div.nouveau_sondage span img { + vertical-align: middle; + border: 0px; +} +div.nouveau_sondage span { + margin-left: 20px; +} + +div.error, div.addcomment { + text-align:center; + border: 1px; + font-family: arial; + font-size: 13px; +} +ul.exports { + text-align:center; + list-style-type : none ; +} +li.error { + color: red; +} + +.half { + -moz-transform:scale(0.5); + -webkit-transform:scale(0.5); + transform:scale(0.5); +} diff --git a/htdocs/opensurvey/fonctions.php b/htdocs/opensurvey/fonctions.php new file mode 100755 index 00000000000..6068ca965f1 --- /dev/null +++ b/htdocs/opensurvey/fonctions.php @@ -0,0 +1,292 @@ + + * +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +*/ + +/** + * \file htdocs/opensurvey/fonction.php + * \ingroup opensurvey + * \brief Functions for module + */ + + + +/** + * Show header for new member + * + * @param string $title Title + * @param string $head Head array + * @param int $disablejs More content into html header + * @param int $disablehead More content into html header + * @param array $arrayofjs Array of complementary js files + * @param array $arrayofcss Array of complementary css files + * @return void + */ +function llxHeaderSurvey($title, $head="", $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='') +{ + global $user, $conf, $langs, $mysoc; + + top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss); // Show html headers + print ''; + + showlogo(); + + print '
'; +} + +/** + * Show footer for new member + * + * @return void + */ +function llxFooterSurvey() +{ + print '
'; + + printCommonFooter('public'); + + dol_htmloutput_events(); + + print "\n"; + print "\n"; +} + + +/** + * Show logo + * + * @return void + */ +function showlogo() +{ + global $user, $conf, $langs, $mysoc; + + // Print logo + $urllogo=DOL_URL_ROOT.'/theme/login_logo.png'; + + if (! empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) + { + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode('thumbs/'.$mysoc->logo_small); + } + elseif (! empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) + { + $urllogo=DOL_URL_ROOT.'/viewimage.php?cache=1&modulepart=companylogo&file='.urlencode($mysoc->logo); + $width=128; + } + elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.png')) + { + $urllogo=DOL_URL_ROOT.'/theme/dolibarr_logo.png'; + } + print '
'; + print 'Logo
'; + print ''.$langs->trans("OpenSurvey").''; + print '

'; +} + + +/** + * get_server_name + * + * @return string URL to use + */ +function get_server_name() +{ + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + $url=$urlwithouturlroot.dol_buildpath('/opensurvey/',1); + + if (!preg_match("|/$|", $url)) { + $url = $url."/"; + } + + return $url; +} + + +/** + * is_error + * + * @param unknown_type $cerr + * @return boolean + */ +function is_error($cerr) +{ + global $err; + if ( $err == 0 ) { + return false; + } + + return (($err & $cerr) != 0 ); +} + + + +/** + * Vérifie une adresse e-mail selon les normes RFC + * + * @param string $email l'adresse e-mail a vérifier + * @return bool vrai si l'adresse est correcte, faux sinon + * @see http://fightingforalostcause.net/misc/2006/compare-email-regex.php + * @see http://svn.php.net/viewvc/php/php-src/trunk/ext/filter/logical_filters.c?view=markup + */ +function validateEmail($email) +{ + $pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD'; + + return (bool)preg_match($pattern, $email); +} + + +/** + * Fonction vérifiant l'existance et la valeur non vide d'une clé d'un tableau + * + * @param string $name La clé à tester + * @param array $tableau Le tableau où rechercher la clé ($_POST par défaut) + * @return bool Vrai si la clé existe et renvoie une valeur non vide + */ +function issetAndNoEmpty($name, $tableau = null) +{ + if ($tableau === null) { + $tableau = $_POST; + } + + return (isset($tableau[$name]) === true && empty($tableau[$name]) === false); +} + + +/** + * Fonction permettant de générer les URL pour les sondage + * + * @param string $id L'identifiant du sondage + * @param bool $admin True pour générer une URL pour l'administration d'un sondage, False pour un URL publique + * @return string L'url pour le sondage + */ +function getUrlSondage($id, $admin = false) +{ + if ($admin === true) { + $url = get_server_name().'adminstuds_preview.php?sondage='.$id; + } else { + $url = get_server_name().'/public/studs.php?sondage='.$id; + } + + return $url; +} + + +/** + * Generate a random id + * + * @return void + */ +function dol_survey_random($car) +{ + $string = ""; + $chaine = "abcdefghijklmnopqrstuvwxyz123456789"; + srand((double)microtime()*1000000); + for($i=0; $i<$car; $i++) { + $string .= $chaine[rand()%strlen($chaine)]; + } + return $string; +} + +/** + * Add a poll + * + * @param string $origin Origin of poll creation + * @return void + */ +function ajouter_sondage($origin) +{ + global $conf, $db; + + $sondage=dol_survey_random(16); + $sondage_admin=$sondage.dol_survey_random(8); + + if ($_SESSION["formatsondage"]=="A"||$_SESSION["formatsondage"]=="A+") { + //extraction de la date de fin choisie + if ($_SESSION["champdatefin"]) { + if ($_SESSION["champdatefin"]>time()+250000) { + $date_fin=$_SESSION["champdatefin"]; + } + } else { + $date_fin=time()+15552000; + } + } + + if ($_SESSION["formatsondage"]=="D"||$_SESSION["formatsondage"]=="D+") { + //Calcul de la date de fin du sondage + $taille_tableau=sizeof($_SESSION["totalchoixjour"])-1; + $date_fin=$_SESSION["totalchoixjour"][$taille_tableau]+200000; + } + + if (is_numeric($date_fin) === false) { + $date_fin = time()+15552000; + } + $canedit=empty($_SESSION['formatcanedit'])?'0':'1'; + + // Insert survey + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'opensurvey_sondage'; + $sql.= '(id_sondage, commentaires, mail_admin, nom_admin, titre, id_sondage_admin, date_fin, format, mailsonde, canedit, origin, sujet)'; + $sql.= " VALUES ('".$db->escape($sondage)."', '".$db->escape($_SESSION['commentaires'])."', '".$db->escape($_SESSION['adresse'])."', '".$db->escape($_SESSION['nom'])."',"; + $sql.= " '".$db->escape($_SESSION['titre'])."', '".$sondage_admin."', '".$db->idate($date_fin)."', '".$_SESSION['formatsondage']."', '".$db->escape($_SESSION['mailsonde'])."',"; + $sql.= " '".$canedit."', '".$db->escape($origin)."',"; + $sql.= " '".$db->escape($_SESSION['toutchoix'])."'"; + $sql.= ")"; + dol_syslog($sql); + $resql=$db->query($sql); + + if ($origin == 'dolibarr') $urlback=dol_buildpath('/opensurvey/adminstuds_preview.php',1).'?sondage='.$sondage_admin; + else + { + // Define $urlwithroot + $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); + $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file + //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + + $url=$urlwithouturlroot.dol_buildpath('/opensurvey/public/studs.php',1).'?sondage='.$sondage; + + $urlback=$url; + + //var_dump($urlback);exit; + } + + unset($_SESSION["titre"]); + unset($_SESSION["nom"]); + unset($_SESSION["adresse"]); + unset($_SESSION["commentaires"]); + unset($_SESSION["canedit"]); + unset($_SESSION["mailsonde"]); + + header("Location: ".$urlback); + exit(); +} + + + +define('COMMENT_EMPTY', 0x0000000001); +define('COMMENT_USER_EMPTY', 0x0000000010); +define('COMMENT_INSERT_FAILED', 0x0000000100); +define('NAME_EMPTY', 0x0000001000); +define('NAME_TAKEN', 0x0000010000); +define('NO_POLL', 0x0000100000); +define('NO_POLL_ID', 0x0001000000); +define('INVALID_EMAIL', 0x0010000000); +define('TITLE_EMPTY', 0x0100000000); +define('INVALID_DATE', 0x1000000000); +$err = 0; + +?> \ No newline at end of file diff --git a/htdocs/opensurvey/img/accept-24.png b/htdocs/opensurvey/img/accept-24.png new file mode 100755 index 0000000000000000000000000000000000000000..65ca043ee12627bd42bb6e8563fb73ed61e07d06 GIT binary patch literal 1696 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 P00000NkvXXu0mjfpFpSJ literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/accept.png b/htdocs/opensurvey/img/accept.png new file mode 100755 index 0000000000000000000000000000000000000000..ada57a9ae60ebccf4cf8f4fcb9523cffbc6c51d0 GIT binary patch literal 901 zcmV;01A6?4P)dCy7H)TT{LFKH{8ZL@ZD61C8Mkl_ujB9adZqJv$Wvbir}b(lh?Vj@yy zDnk@6=ob|fyNMvPxT#26S7&h_#@ZFqW~3%<(zI#pN#FFGvo{Bgm-o}*egDtz{BIA3 z_fBYJ*hNHfhb+r0HC=NVmpVd9M){3WdZE6yKJ<1x_xfWbJRe9DU?H*mDuKLMu!}dV|-2 z45dgg;18dCg;ra0C(CAY4q}9iMqdPei9Yrn>bnGIu^lD>ka-;?R*t=c9xG1%eKlLHJi06p~{2TaLg&ig2L! z6s`_-;ojO)S(C!Mxp*QTI6iRR_bl3v@&dwwIF^9`!V3(*8-ULmze9s9r&2v_z1v!>vKds9;V5t*Gna;{QRw;{mX?1CZ~d1BsJ;6n(zDN4 zc@z_~3WA>Vz1-CFWc2&)^<^GA6Y6#NdhtQr{O25oll>@?i?P#l6lP+<-QjNB9{dTF z7Bd{C1fGtKBe3jN%mDbGtS@USwZm;&i{&-ng3TWfMy{jWQjJFYawKP`ao|xKD&z<& zFAAI4iRXzp{GQGjmrkd9I{LS_SjiY>XcFFr(`c}-X6ft3{5aN!;2$Tz(QB-%DWepN z>_D74u&0rgkeo~g?nW;AhT>=0*i|MFvB~`-njGtl;OFrnoPFwr)11j~pQ;O}weP}; z(k(%5e0J`}e@s+Ipl8rHU zIgy+Q49)cUejW0$fT>py9`r+6Ldk{IAM8gZzo;{l$!xBvS)k_4l!HhTIjoV)zP}S)WN_kl zq-G<=TaoNUed!7`l&s2XirA5*)L&Iy^TteXpIlD}Av;8oFgvS;ojIKg(JVFWTv1W^ bj-CGpV^3H~a~vrn00000NkvXXu0mjfc^9ui literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/add-16.png b/htdocs/opensurvey/img/add-16.png new file mode 100755 index 0000000000000000000000000000000000000000..23d5bed776023cee0402e7c0b1649d57704e36d3 GIT binary patch literal 845 zcmV-T1G4;yP)|8WvWN;ij47sw?j7x|_Q?^be&3;f({(`?mg#x_uO;8OYpDlu%$EA zuI)_08kf3~5Dg=PhA~gC`Z^j=n`pc{F_|RbG;;=ff73Dh!F}Z_$ypIYvPFd)CkRH8 zFyS|%$E|674QDu1^om z4GRUdj@Jnc>8AE0x1B{bB>{*sgK2u=tYCmbPggZiClKOvf8L1Mc>^Ueqwlh>BOZwD zULZKQ<^0mts}}=$(CartQV3YWp={MNy}cH11r$v{jFOCmID|zO@7e(0U2iENX=Zoh zdqYWPs)R2-D`K>R1zT#_fa=^%9XAc{#FW^thTMNd>FUGgcaDkycR~r z0*-aUZOXa`9)tk2x67Y+FPAjnZVL=n#> zu3=(+9KBy0`0;ciK$fj#+;uPQB_I8E_=Vpypih@;Uyp`uE&B5G+cFGC1{PHlj<6W= zS`fYFY15za#6x?lbsdLZJ{6kwE6L?phe!F%I z+R$Fnl(x$&CBqZ7>xuLdc(S!g$4B2)LxiB?XpkT@#XxEBw1XG-{E>2I)@D;z{)O~B zo)&%;Y?xJ9D8FjJasZ=fh|j2)3u;gve;dR|q;OHnzb)OmjBRvPr4=V{w2_c(#EhJz z3nwlCl1SzJDWWMa$6FDKo&5VVC0d~|m964j)&k-*X3JE*Qa~D$hiALAh`ey8p2Xyz X@8?yrXY&hd00000NkvXXu0mjf$sm%K literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/add-24.png b/htdocs/opensurvey/img/add-24.png new file mode 100755 index 0000000000000000000000000000000000000000..c63af7f39062ad0d5b9f1c5f9afa617e7ada0d5d GIT binary patch literal 1393 zcmV-%1&;cOP)6#sqq-gdW-t$P6jF>D#QF+f0xI6@`_MgoI~JVHX0#Az@Rd1!=13>pF5Wz9XWWc(0uI%Mny0zW9+x2yOZ?9i(N7-nn;Up(HJ?A^;_ucdQ zO7P$GBIWg*1|<`6$@HuVN*19CS1)n*b}1G~#C7_!hVs3!0+2EE^B4}5`LFSd=ap&6 zoDyL2gfMb4M6j#^$AA_#hX!~50PdU*D{WVUzeglgP`}&%2f$F?mo;1e$-HtCJFQSg z(G)+jGbC`F0x3cuN(@4j{UHV(frZ1VMQ0nq?c;*%yzBpx`hP|_k_>>Qd~)Kd?2U8Q z7_hR~jTfE|(4f(PPXa&Y*l(iBeQpkI?L3-medsyo`T+{wq_O0u0ghyru4^f1@@;i`2UrSZ0n1X!LjE91h--A1x) zjV+!E!Ovnq;1Cj-q=ga{27@98Aw9gL2)qgqpqFW=?#))e1j$R(V06Xfo>+{Yc*SJWPJBO~JrsIuKc7cA0#c5DM25Ir@j|vcP z^_4{ds+S$edAnkZQ%y^^D+NwLn~;w3slQ^PevT?X@;9Q|x+LL@T}Xk|rB`dxT1VUY zptYJn$F)?|8wzLS`QfFvHrotPl*D|$S8xTBh5_sp;M>-v31^~ice+jR1UL)~aA^Ig zwV9+$)&**sWIm!0bhvmp1`}@|r4I@(W3pkkD);#A;Tub7(sSMYJX(7VYUf#Yclt^0 z%NphIl~~s_+EU>Qv6z}xjE#ARVdS#ojvT{-A+c_XC=uFe!MJTma^Y0R4p@acc!Ml3f z+xxRlA64A!N>>3k=O4ntNo$`8;D-GSjy?R40ubCB25?vX9VDrlFdu9*7Ks$O-e!U? zOvgepU|IGiq-nF_0T$)Gj&xltWuAZw*E-IPXi+yVxlSU;`QWE1`pcTCPPk{!1530` zkMFr`EYHm4(Cjv%$IFjyi(xu4|13@0%;9u2VSD|EIT*2U`ua6!x6`4siwNvDpNN`P zlx|76uw<(q{Q(Vb^=2eZ!Lj1gC@{qUS_hl3xo%zZT6E~>24E4qXovjUBX!VNoryH< zxR_qZ=vdtEH^JuT6CA%=_#=waXQ*<1%cSAh|-GL ztNHV#pQaH%t-)<~1_Vhn%DEzc7s_XCRORXir%?Iut5NoF2yogs1nDl4PIoG3aIT>0 zUq-I$uNUo1+gh;7s1~|WFu^UQJSoQzi)H%Qa9#3W1~JNUTO^>s=OnSnp zB+X|us2smAwIp+aiD>f;2orYHb14RZpw)*^L%$Mf?7s?G*+u;to(?n?z+;+Ac^%PS8~fPv4sYG{I}))SONY8M7L~y&{-FO00000NkvXXu0mjf-!+?f literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/add.png b/htdocs/opensurvey/img/add.png new file mode 100755 index 0000000000000000000000000000000000000000..7409ef332d2435c3fb43c879a80c9fcb5820f796 GIT binary patch literal 2017 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 Hu0mjf!zXq{ literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/info.png b/htdocs/opensurvey/img/info.png new file mode 100755 index 0000000000000000000000000000000000000000..4c665a4f0a10633d475480553f673bceb10f594a GIT binary patch literal 777 zcmV+k1NQuhP)2Rxem5IpiJG?3n;E5IYLG=}N_7!xQP~$15m*-)L}4Iw6GYKXN|*+M zrQQg2;YafWLX*(SCOWm5Ij3$qx3%qkdz?+|5kZ3BwVCn0t=d9> zXg}b{sq^mi!mCn2wiO<)hvb8p@nGcH=i{+zX0?nEnUu=nz%QHewz+DC05N_*@yYT* zU2a)gtS$o!HXcD@K&oKykY9lpz`5Xu5Yb=8#9%K*3^knu$O)8CrQMcVnOAbz-!{7& zSfB+lb%E{?5i}=eYtMzFuD3qA1IPT-bpqTA0KzF7^#$j`)A#LyOvYey3RDW6PG!iY z1S8P=BGA>`3R7PrWRtyl4L#%S8z0gkN-aC`%DA-LZ0NNNQ4$8)2kVl6&Pia{@Crsl zBjhFna^kG$`iMPs1J=Ivr%aFolxjoN8ck$eDpZ@c_%CnCV#3_S5LRZ4keT}-ag5&YGbu)2kHks7bO=lgU1AuDDys3k>KYjSBeJ)s zauOp}+N0$R`|Cd8#ba3%?*>FV*vg00000NkvXX Hu0mjf>jh(& literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/medaille.png b/htdocs/opensurvey/img/medaille.png new file mode 100755 index 0000000000000000000000000000000000000000..97a22b72eea2e8d65655993c68a9e03f6a40aa9e GIT binary patch literal 753 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 literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/next.png b/htdocs/opensurvey/img/next.png new file mode 100755 index 0000000000000000000000000000000000000000..24d94e830a33157c791a714ab60565f9aebf0d6e GIT binary patch literal 1349 zcmV-L1-kl)P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igW1 z5hpUz)>8fe00hNJL_t(Y$BmXrY+OYUhQIE9%e?W79pfwxORy4$m?T&sL1aOg9fCLj zVmSbU2ysD3zzKwekPrwFaRG!7%LNhO64na{5MqgR~3P>KRv+y>qK7QzA9w{sEjCZIv>H#~45ati_dLTsgtUF*b^@afC}s1eG>S9HCi`HZo8pNMcO68$YuDY#H6V z6&Q4YBP_pFU3>Se8OxRwo{3<>5F15c45)$}A*vYXaBXF94yn}(Z;}{|=9tFrEh~`x z84Iip=dbB&?_b&i$2nj!496j^oDj~Q*)m?5dm`Z}EBk=UEO1TRic4_iQUMPC&cO27 z3D2(W<>GnmXr3KYda4073J5yeQ4vhwDD|!axW*E-tuCLo1Vm5~)C-#XmVv7m&g9bh zT|9S19~-V*!onG)qdfTOz*yl)rHpYF6(O8G55n>)>#DPQf{tndo_jRU(L5&~87UG) zwU~|J+*3Pw=ceU6c>V%9LetXyS3IsQLA_w25L-T>$GS?j)Fg4LGC+1<7*r0+#K2nC zEkBu$Z(GGp{c~IU&2uIUix7)ohSzcgxk01MUD3IF0PqTe{76&s=1{BS*g48fP z%7c;G1dqM3jTb%}!bf2X&^IznSa>Y;2@oMaxDQRowm2ZSrOJ(Q&lyFYH5Eo{$oK@a z+hWc;eJ&f`|CV)6f57J7Mp0v0L>?X*!5^xjxhLKA5&3~1?>B%mN%gz#JD=|}VM2bW zhNKNN_n7)PT2644GBS}K%|m@0lY6L?!CJJDA+>QNtugxcLp!ulU+MrQZ|s)Z$PIDt z*~U0qfO&x+00m96Vtu4oSLldBo+INEs0ia=PbYk z0h%@nKANHUFYz92G{6h#;3m?Y?>`AVb!0zyFa7b$MJ7y^hTXj_(lnb)ykh~YVnk8z zQ4!MbKV*FS8?OMjAFJUg@Oootdzc>>S`*IcwYF5jMj-@6bu~rJz!-xuwy5MH__1N? zTVKx8!A%bXcTH`X(>48-xL|$UyLzCsaFq#WEdb*VOCrru^8JIPL!WEo=Py1){5`-I z$NQ>ijx&L4vB7|ApS8%ul`a%y;?S^+{ka3lo6nYSrUUo~KxWuI!U%fE00000NkvXX Hu0mjfSMp}6 literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/object_opensurvey.png b/htdocs/opensurvey/img/object_opensurvey.png new file mode 100755 index 0000000000000000000000000000000000000000..042d82172576c5653ed257e778eb73fa1ddfefda GIT binary patch literal 828 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 UcZA@0Z2$lO07*qoM6N<$f_;aIJpcdz literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/opensurvey_logo.png b/htdocs/opensurvey/img/opensurvey_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..eb266ae05cf56559595b9580f33aeb9f4c4fced1 GIT binary patch literal 37593 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 Td-d literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/img/previous.png b/htdocs/opensurvey/img/previous.png new file mode 100755 index 0000000000000000000000000000000000000000..b4b79aeec517f11788920581a3b6044a2bf80930 GIT binary patch literal 1388 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 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/index.php + * \ingroup opensurvey + * \brief Home page of opensurvey area + */ + +require_once('../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); + + + +/* + * View + */ + +$langs->load("opensurvey@opensurvey"); +llxHeader(); + +$nbsondages=0; +$sql='SELECT COUNT(*) as nb FROM '.MAIN_DB_PREFIX.'opensurvey_sondage'; +$resql=$db->query($sql); +if ($resql) +{ + $obj=$db->fetch_object($resql); + $nbsondages=$obj->nb; +} +else dol_print_error($db,''); + +print_fiche_titre($langs->trans("OpenSurveyArea")); + +echo $langs->trans("NoSurveysInDatabase",$nbsondages).'

'."\n"; + + +// Link +print img_picto('','object_globe.png').' '.$langs->trans("PublicLinkToCreateSurvey").':
'; + +// Define $urlwithroot +$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + +$url=$urlwithouturlroot.dol_buildpath('/opensurvey/public/index.php',1); +$urllink=''.$url.''; +print $urllink; + + + +llxFooter(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/langs/en_US/opensurvey.lang b/htdocs/opensurvey/langs/en_US/opensurvey.lang new file mode 100755 index 00000000000..8ab49021259 --- /dev/null +++ b/htdocs/opensurvey/langs/en_US/opensurvey.lang @@ -0,0 +1,68 @@ +# Dolibarr language file - en_US - opensurvey +CHARSET=UTF-8 +Survey=Survey +Surveys=Surveys +OrganizeYourMeetingEasily=Organize your meeting and surveys easily. First select type of survey... +NewSurvey=New survey +NoSurveysInDatabase=%s survey(s) into database. +OpenSurveyArea=Surveys area +AddACommentForPoll=You can add a comment into survey... +AddComment=Add comment +CreatePoll=Create poll +PollTitle=Poll title +OpenSurveyYourName=Your name +OpenSurveyYourEMail=Your email address +VotersCanModify=Voters can modify vote of others +ToReceiveEMailForEachVote=To receive an email for each vote +TypeDate=Type date +TypeClassic=Type standard +YouAreInPollCreateArea=You are in the poll creation section +FieldMandatory=Field mandatory +OpenSurveyDesc=Online service to plan a rendez-vous or do a survey quickly and easily. +OpenSurveyNoRegistration=No registration required. +OpenSurveyStep2=Select your dates amoung the free days (green). The selected days are in blue. You can unselect a day previously selected by clicking again on it +RemoveAllDays=Remove all days +CopyHoursOfFirstDay=Copy hours of first day +RemoveAllHours=Remove all hours +SelectedDays=Selected days +TheBestChoice=The best choice currently is +TheBestChoices=The best choices currently are +with=with +OpenSurveyHowTo=If you agree to vote in this poll, you have to give your name, choose the values that fit best for you (without paying attention to the choices of the other voters) and validate with the plus button at the end of the line. +InitiatorOfPoll=Initiator of the poll +CommentsOfVoters=Comments of voters +ConfirmRemovalOfPoll=Are you sure you want to remove this poll (and all votes) +RemovePoll=Remove poll +PollManagement=Poll's management +BackToHoursSetup=Back to hours setup +UrlForSurvey=URL to communicate to get a direct access to survey +PollOnChoice=Your are creating a poll to make a multi-choice for a poll. First enter all possible choices for your poll: +CheckBox=Simple checkbox +YesNoList=List (empty/yes/no) +PourContreList=List (empty/for/against) +AddNewColumn=Add new colum +TitleChoice=Choice label +InfoAfterCreate=Once you have confirmed the creation of your poll, you will be automatically redirected on the page of your poll.
You should also receive an email with link to your poll for sending it to the voters. +ExportSpreadsheet=Export result spreadsheet +ExpireDate=Limit date +NbOfVoters=Nb of voters +SurveyResults=Results +PollAdminDesc=You are allowed to change all vote lines of this poll with button "Edit". You can, as well, remove a column or a line with %s. You can also add a new column with %s. +5MoreChoices=5 more choices +Abstention=Abstention +Against=Against +YouAreInivitedToVote=You are invited to vote for this poll +VoteNameAlreadyExists=This name was already used for this poll +ErrorPollDoesNotExists=Error, poll %s does not exists. +OpenSurveyNothingToSetup=There is no specific setup to do. +PollWillExpire=Your poll will expire automatically %s days after the last date of your poll. +RemovalDate=Removal date +AddADate=Add a date +AddStartHour=Add start hour +AddEndHour=Add end hour +votes=vote(s) +NoCommentYet=No comment yet posted for this poll +CanEditVotes=Can change vote of others +SelectDayDesc=For each selected day, you can choose, or not, meeting hours in the following format :
- empty,
- "8h", "8H" or "8:00" to give a meeting's start hour,
- "8-11", "8h-11h", "8H-11H" or "8:00-11:00" to give a meeting's start and end hour,
- "8h15-11h15", "8H15-11H15" or "8:15-11:15" for the same thing but with minutes. +BackToCurrentMonth=Back to current month +PublicLinkToCreateSurvey=Public link to allow everybody to create a survey \ No newline at end of file diff --git a/htdocs/opensurvey/langs/fr_FR/opensurvey.lang b/htdocs/opensurvey/langs/fr_FR/opensurvey.lang new file mode 100755 index 00000000000..12fc74f258d --- /dev/null +++ b/htdocs/opensurvey/langs/fr_FR/opensurvey.lang @@ -0,0 +1,68 @@ +# Dolibarr language file - fr_FR - opensurvey +CHARSET=UTF-8 +Survey=Sondage +Surveys=Sondages +OrganizeYourMeetingEasily=Organiser vos rendez-vous ou votes facilement, librement. Sélectionnez d'abord le type de sondage... +NewSurvey=Nouveau sondage +NoSurveysInDatabase=%s sondage(s) en base. +OpenSurveyArea=Espace sondage +AddACommentForPoll=Vous pouvez ajouter un commentaire au sondage... +AddComment=Ajouter commentaire +CreatePoll=Créer sondage +PollTitle=Titre sondage +OpenSurveyYourName=Votre nom +OpenSurveyYourEMail=Votre adresse email +VotersCanModify=Les votants peuvent modifier les votes des autres +ToReceiveEMailForEachVote=Pour recevoir un email à chaque vote +TypeDate=Type date +TypeClassic=Type classique +YouAreInPollCreateArea=Vous êtes dans l'espace de création de sondage +FieldMandatory=Champ obligatoire +OpenSurveyDesc=Service en ligne permettant de planifier un rendez-vous ou réaliser un sondage rapidement et simplement. +OpenSurveyNoRegistration=Aucune inscription préalable n'est nécessaire. +OpenSurveyStep2=Sélectionner les dates parmis les jours libres (en vert). Les jours sélectionné sont bleus. Vou spouvez désélectionner un jour en cliquant à nouveau dessus. +RemoveAllDays=Efface tous les jours +CopyHoursOfFirstDay=Copier heures du premier jour +RemoveAllHours=Efface toutes les heures +SelectedDays=Jours sélectionnés +TheBestChoice=Le meilleur choix actuellement est +TheBestChoices=Les meilleurs choix actuellement sont +with=avec +OpenSurveyHowTo=Si vous acceptez de voter pour ce sondage, vous devez saisir votre nom, choisir les valeurs qui correspondent à votre choix (sans prêter attention aux choix des autres déjà saisis) et valider en cliquant sur le bouton + à la fin de la ligne. +InitiatorOfPoll=Initiateur du sondage +CommentsOfVoters=Commentaires des votants +ConfirmRemovalOfPoll=Etes vous sur de vouloir supprimer ce sondage (et tous ces votes) +RemovePoll=Suppression du sondage +PollManagement=Gestion du sondage +BackToHoursSetup=Retour configuration heures +UrlForSurvey=URL à communiquer pour accès direct au sondage +PollOnChoice=Vous êtes en train de créer un sondage à choix multiples. Renseigner les différents choix possible de votre sondage: +CheckBox=Case à cochée +YesNoList=Liste (vide/oui/non) +PourContreList=Liste (vide/pour/contre) +AddNewColumn=Ajouter nouvelle colonne +TitleChoice=Libellé du choix +InfoAfterCreate=Une fois la confirmation de la création de votre sondage réalisée, vous serez redirigé vers la page de vote du sondage.
Vous devriez de plus recevoir un email avec le lien de la page sondage pour diffusion auprès des votants. +ExportSpreadsheet=Exporter feuille de résultats +ExpireDate=Date expiration +NbOfVoters=Nb de votants +SurveyResults=Résultats +PollAdminDesc=Vous êtes habilités à modifier toutes les lignes de votes par le bouton "Editer". Vous pouvez supprimer une colonne ou ligne avec %s. Vous pouvez aussi ajouter une nouvelle colonne avec %s. +5MoreChoices=5 choix suplémentaires +Abstention=Abstention +Against=Contre +YouAreInivitedToVote=Vous êtes invité à vous prononcer sur ce vote/sondage +VoteNameAlreadyExists=Ce nom a déjà été utilisé pour ce vote +ErrorPollDoesNotExists=Erreur, le sondage %s n'existe pas. +OpenSurveyNothingToSetup=Aucune configuration particulière n'est requise. +PollWillExpire=Ce sondage expirera automatiquement %s jours après la date de dernier choix. +Removal date=Date d'expiration +AddADate=Ajouter une date +AddStartHour=Ajouter heure de début +AddEndHour=Ajouter heure de fin +votes=vote(s) +NoCommentYet=Pas de commentaires laissés pour le moment sur ce sondage +CanEditVotes=Modification des votes des autres autorisés +SelectDayDesc=Pour chaque jour, vous pouvez choisir, ou pas, les heures au format suivant :
- laisser vide,
- "8h", "8H" ou "8:00" pour définir uniquement une heure de début,
- "8-11", "8h-11h", "8H-11H" ou "8:00-11:00" pour définir une heure de début et de fin,
- "8h15-11h15", "8H15-11H15" ou "8:15-11:15" pour définir une heure de début et fin avec précision sur les minutes. +BackToCurrentMonth=Retour au mois en cours +PublicLinkToCreateSurvey=Lien publique pour permettre à tout le monde de créer un sondage diff --git a/htdocs/opensurvey/list.php b/htdocs/opensurvey/list.php new file mode 100755 index 00000000000..20a3ed50d94 --- /dev/null +++ b/htdocs/opensurvey/list.php @@ -0,0 +1,145 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/list.php + * \ingroup opensurvey + * \brief Page to list surveys + */ + +require_once('../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); + +$action=GETPOST('action'); +$id=GETPOST('id'); + +if (! $sortorder) $sortorder="ASC"; +if (! $sortfield) $sortfield="p.titre"; +if ($page < 0) { + $page = 0; +} +$limit = $conf->liste_limit; +$offset = $limit * $page; + + +/* + * Actions + */ + +if ($action == 'delete_confirm') +{ + $db->begin(); + + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_comments WHERE id_sondage_admin = '".$id."'"; + dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); + $resql=$db->query($sql); + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage_admin = '".$id."'"; + dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); + $resql=$db->query($sql); + $sql='DELETE FROM '.MAIN_DB_PREFIX."opensurvey_sondage WHERE id_sondage_admin = '".$id."'"; + dol_syslog("Delete poll sql=".$sql, LOG_DEBUG); + $resql=$db->query($sql); + + $db->commit(); +} + + + +/* + * View + */ + +$form=new Form($db); + +$langs->load("opensurvey@opensurvey"); +llxHeader(); + +print '
'."\n"; + +print_fiche_titre($langs->trans("OpenSurveyArea")); + + +if ($action == 'delete') +{ + print $form->formconfirm($_SERVER["PHP_SELF"].'?&id='.$id, $langs->trans("RemovePoll"), $langs->trans("ConfirmRemovalOfPoll",$id), 'delete_confirm', '', '', 1); +} + + +// tableau qui affiche tous les sondages de la base +print ''."\n"; +print ''."\n"; + +$sql = "SELECT id_sondage, id_sondage_admin, mail_admin, format, origin, date_fin, titre, nom_admin"; +$sql.= " FROM ".MAIN_DB_PREFIX."opensurvey_sondage as p"; +// Count total nb of records +$nbtotalofrecords = 0; +if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) +{ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); +} +$sql.= " ORDER BY $sortfield $sortorder "; +$sql.= " ".$db->plimit($conf->liste_limit+1, $offset); + +$resql=$db->query($sql); +if (! $resql) dol_print_error($db); + +$num=$db->num_rows($resql); + +$i = 0; $var = true; +while ($i < min($num,$limit)) +{ + $obj=$db->fetch_object($resql); + + $sql2='select COUNT(*) as nb from '.MAIN_DB_PREFIX."opensurvey_user_studs where id_sondage='".$db->escape($obj->id_sondage)."'"; + $resql2=$db->query($sql2); + if ($resql2) + { + $obj2=$db->fetch_object($resql2); + $nbuser=$obj2->nb; + } + else dol_print_error($db); + + $var=!$var; + print ''; + print ''; + + print ''; + + print''."\n"; + print ''."\n"; + + print ''."\n"; + $i++; +} + +print '
'. $langs->trans("Survey").''. $langs->trans("Type") .''. $langs->trans("Title") .''. $langs->trans("Author") .''. $langs->trans("ExpireDate") .''. $langs->trans("NbOfVoters") .' 
'; + print ''.img_picto('','object_opensurvey@opensurvey').' '.$obj->id_sondage.''; + print ''; + $type=($obj->format=='A' || $obj->format=='A+')?'classic':'date'; + print img_picto('',dol_buildpath('/opensurvey/img/'.($type == 'classic'?'chart-32.png':'calendar-32.png'),1),'width="16"',1); + print ' '.$langs->trans($type=='classic'?"TypeClassic":"TypeDate"); + print ''.$obj->titre.''.$obj->nom_admin.''.dol_print_date($db->jdate($obj->date_fin),'day'); + if ($db->jdate($obj->date_fin) < time()) { print ' '.img_warning(); } + print ''.$nbuser.''.img_picto('', 'delete.png').'
'."\n"; +print '
'."\n"; + +llxFooter(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/public/choix_autre.php b/htdocs/opensurvey/public/choix_autre.php new file mode 100755 index 00000000000..5975f9d4a0c --- /dev/null +++ b/htdocs/opensurvey/public/choix_autre.php @@ -0,0 +1,222 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/public/choix_autre.php + * \ingroup opensurvey + * \brief Page to create a new survey (choice selection) + */ + +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + +$erreur = false; +$testdate = true; +$date_selected = ''; + +$origin=GETPOST('origin','alpha'); + + + +/* + * Action + */ + +// Set session vars +$erreur_injection = false; +if (isset($_SESSION["nbrecases"])) { + for ($i = 0; $i < $_SESSION["nbrecases"]; $i++) { + if (isset($_POST["choix"][$i])) { + $_SESSION["choix$i"]=$_POST["choix"][$i]; + } + if (isset($_POST["typecolonne"][$i])) { + $_SESSION["typecolonne$i"]=$_POST["typecolonne"][$i]; + } + } +} else { //nombre de cases par défaut + $_SESSION["nbrecases"]=5; +} + +if (isset($_POST["ajoutcases"]) || isset($_POST["ajoutcases_x"])) { + $_SESSION["nbrecases"]=$_SESSION["nbrecases"]+5; +} + +// Create survey into database +if (isset($_POST["confirmecreation"]) || isset($_POST["confirmecreation_x"])) +{ + //recuperation des données de champs textes + $toutchoix = ''; + for ($i = 0; $i < $_SESSION["nbrecases"] + 1; $i++) + { + if (! empty($_POST["choix"][$i])) + { + $toutchoix.=','; + $toutchoix.=str_replace(array(",","@"), " ", $_POST["choix"][$i]).(empty($_POST["typecolonne"][$i])?'':'@'.$_POST["typecolonne"][$i]); + } + } + + $toutchoix=substr("$toutchoix",1); + $_SESSION["toutchoix"]=$toutchoix; + + if (GETPOST('champdatefin')) + { + $registredate=explode("/",$_POST["champdatefin"]); + if (is_array($registredate) === false || count($registredate) !== 3) { + $testdate = false; + $date_selected = $_POST["champdatefin"]; + } else { + $time = mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]); + if ($time === false || date('d/m/Y', $time) !== $_POST["champdatefin"]) { + $testdate = false; + $date_selected = $_POST["champdatefin"]; + } else { + if (mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]) > time() + 250000) { + $_SESSION["champdatefin"]=mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]); + } + } + } + } else { + $_SESSION["champdatefin"]=time()+15552000; + } + + if ($testdate === true) + { + //format du sondage AUTRE + $_SESSION["formatsondage"]="A"; + $_SESSION["caneditsondage"]=$_SESSION["canedit"]; + + // Add into database + ajouter_sondage($origin); + } else { + $_POST["fin_sondage_autre"] = 'ok'; + } +} + + + + +/* + * View + */ + +$form=new Form($db); + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeaderSurvey($langs->trans("OpenSurvey"), "", 0, 0, $arrayofjs, $arrayofcss); + +if (empty($_SESSION['titre']) || empty($_SESSION['nom']) || empty($_SESSION['adresse'])) +{ + dol_print_error('',"You haven't filled the first section of the poll creation"); + llxFooterSurvey(); + exit; +} + + +//partie creation du sondage dans la base SQL +//On prépare les données pour les inserer dans la base + +print '
'."\n"; +print ''; + +print '
'. $langs->trans("CreatePoll")." (2 / 2)" .'
'."\n"; + +print '
'."\n"; +print '
'. $langs->trans("PollOnChoice") .'

'."\n"; +print ''."\n"; + +//affichage des cases texte de formulaire +for ($i = 0; $i < $_SESSION["nbrecases"]; $i++) { + $j = $i + 1; + if (isset($_SESSION["choix$i"]) === false) { + $_SESSION["choix$i"] = ''; + } + print ''."\n"; +} + +print '
'. $langs->trans("TitleChoice") .' '.$j.' : '; + $tmparray=array('checkbox'=>$langs->trans("CheckBox"),'yesno'=>$langs->trans("YesNoList"),'foragainst'=>$langs->trans("PourContreList")); + print '   '.$langs->trans("Type").' '.$form->selectarray("typecolonne[]", $tmparray, $_SESSION["typecolonne$i"]); + print '
'."\n"; + +//ajout de cases supplementaires +print ''."\n"; +print ''."\n"; +print '
'. $langs->trans("5MoreChoices") .'
'."\n"; +print'
'."\n"; + +print ''."\n"; +print ''."\n"; +print '
'."\n"; + +//test de remplissage des cases +$testremplissage = ''; +for ($i=0;$i<$_SESSION["nbrecases"];$i++) +{ + if (isset($_POST["choix"][$i])) + { + $testremplissage="ok"; + } +} + +//message d'erreur si aucun champ renseigné +if ($testremplissage != "ok" && (isset($_POST["fin_sondage_autre"]) || isset($_POST["fin_sondage_autre_x"]))) { + print "
" . $langs->trans("Enter at least one choice") . "

"."\n"; + $erreur = true; +} + +//message d'erreur si mauvaise date +if ($testdate === false) { + print "
" . _("Date must be have the format DD/MM/YYYY") . "

"."\n"; +} + +if ($erreur_injection) { + print "" . _("Characters \" < and > are not permitted") . "

\n"; +} + +if ((isset($_POST["fin_sondage_autre"]) || isset($_POST["fin_sondage_autre_x"])) && !$erreur && !$erreur_injection) { + //demande de la date de fin du sondage + print '
'."\n"; + print '
'."\n"; + print '
'. _("Your poll will be automatically removed after 6 months.
You can fix another removal date for it.") .'

'."\n"; + print _("Removal date (optional)") .' : '. _("(DD/MM/YYYY)") ."\n"; + print '
'."\n"; + print '
'."\n"; + print ''. $langs->trans("InfoAfterCreate") .''."\n"; + print '
'."\n"; + print '
'."\n"; + print ''."\n"; + print ''."\n"; + print '
'. $langs->trans("CreatePoll") .'
'."\n"; +} + +//fin du formulaire et bandeau de pied +print ''."\n"; + + +print ''."\n"; +print '


'."\n"; +print '
'."\n"; + +llxFooterSurvey(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/public/choix_date.php b/htdocs/opensurvey/public/choix_date.php new file mode 100755 index 00000000000..72a24357436 --- /dev/null +++ b/htdocs/opensurvey/public/choix_date.php @@ -0,0 +1,573 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/public/choix_date.php + * \ingroup opensurvey + * \brief Page to create a new survey (date selection) + */ + +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + +$origin=GETPOST('origin','alpha'); + + +/* + * Actions + */ + +// Insert survey +if (GETPOST('confirmation') || GETPOST('confirmation_x')) +{ + if (is_array($_SESSION['totalchoixjour'])) + { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + if ($_SESSION["horaires$i"][0] == "" && $_SESSION["horaires$i"][1] == "" && $_SESSION["horaires$i"][2] == "" && $_SESSION["horaires$i"][3] == "" && $_SESSION["horaires$i"][4] == "") { + $choixdate.=","; + $choixdate .= $_SESSION["totalchoixjour"][$i]; + } else { + for ($j=0;$j<$_SESSION["nbrecaseshoraires"];$j++) { + if ($_SESSION["horaires$i"][$j]!="") { + $choixdate.=","; + $choixdate .= $_SESSION["totalchoixjour"][$i]; + $choixdate.="@"; + // On remplace la virgule et l'arobase pour ne pas avoir de problème par la suite + $choixdate .= str_replace(array(',', '@'), array(',', '@'), $_SESSION["horaires$i"][$j]); + } + } + } + } + } + else dol_print_error('','array not defined'); + + $_SESSION["toutchoix"]=substr("$choixdate",1); + ajouter_sondage($origin); +} + +// Reset days +if (GETPOST('reset')) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + unset($_SESSION["horaires$i"][$j]); + } + } + + unset($_SESSION["totalchoixjour"]); + unset($_SESSION["nbrecaseshoraires"]); +} + + + +/* + * View + */ + +if (! isset($_SESSION['nom']) && ! isset($_SESSION['adresse']) && ! isset($_SESSION['commentaires']) && ! isset($_SESSION['mail'])) +{ + dol_print_error('',"You haven't filled the first section of the poll creation"); + exit; +} + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeaderSurvey($langs->trans("OpenSurvey"), "", 0, 0, $arrayofjs, $arrayofcss); + +//nombre de cases par défaut +if (! isset($_SESSION["nbrecaseshoraires"])) +{ + $_SESSION["nbrecaseshoraires"]=5; +} +elseif ((GETPOST('ajoutcases') || GETPOST('ajoutcases_x')) && $_SESSION["nbrecaseshoraires"] == 5) +{ + $_SESSION["nbrecaseshoraires"]=10; +} + +//valeurs de la date du jour actuel +$jourAJ=date("j"); +$moisAJ=date("n"); +$anneeAJ=date("Y"); + +// Initialisation des jour, mois et année +if (! isset($_SESSION['jour'])) $_SESSION['jour']= date('j'); +if (! isset($_SESSION['mois'])) $_SESSION['mois']= date('n'); +if (! isset($_SESSION['annee'])) $_SESSION['annee']= date('Y'); + +//mise a jour des valeurs de session si bouton retour a aujourd'hui +if ((!issetAndNoEmpty('anneeavant_x') && !issetAndNoEmpty('anneeapres_x') && !issetAndNoEmpty('moisavant_x') && !issetAndNoEmpty('moisapres_x') && !issetAndNoEmpty('choixjourajout')) && !issetAndNoEmpty('choixjourretrait') || (issetAndNoEmpty('retourmois') || issetAndNoEmpty('retourmois_x'))){ + $_SESSION["jour"]=date("j"); + $_SESSION["mois"]=date("n"); + $_SESSION["annee"]=date("Y"); +} + +//mise a jour des valeurs de session si mois avant +if (issetAndNoEmpty('moisavant') || issetAndNoEmpty('moisavant_x')) { + if ($_SESSION["mois"] == 1) { + $_SESSION["mois"] = 12; + $_SESSION["annee"] = $_SESSION["annee"]-1; + } else { + $_SESSION["mois"] -= 1; + } + + //On sauvegarde les heures deja entrées + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } +} + +//mise a jour des valeurs de session si mois apres +if (issetAndNoEmpty('moisapres') || issetAndNoEmpty('moisapres_x')) { + if ($_SESSION["mois"] == 12) { + $_SESSION["mois"] = 1; + $_SESSION["annee"] += 1; + } else { + $_SESSION["mois"] += 1; + } + + //On sauvegarde les heures deja entrées + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } +} + +//mise a jour des valeurs de session si annee avant +if (issetAndNoEmpty('anneeavant') || issetAndNoEmpty('anneeavant_x')) { + $_SESSION["annee"] -= 1; + + //On sauvegarde les heures deja entrées + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } +} + +//mise a jour des valeurs de session si annee apres +if (issetAndNoEmpty('anneeapres') || issetAndNoEmpty('anneeapres_x')) { + $_SESSION["annee"] += 1; + + //On sauvegarde les heures deja entrées + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0;$j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } +} + +//valeurs du nombre de jour dans le mois et du premier jour du mois +$nbrejourmois = date("t", mktime(0, 0, 0, $_SESSION["mois"], 1, $_SESSION["annee"])); +$premierjourmois = date("N", mktime(0, 0, 0, $_SESSION["mois"], 1, $_SESSION["annee"])) - 1; + +//le format du sondage est DATE +$_SESSION["formatsondage"] = "D"; +$_SESSION["formatcanedit"] = $_SESSION["canedit"]; + +//traduction de la valeur du mois +if (is_integer($_SESSION["mois"]) && $_SESSION["mois"] > 0 && $_SESSION["mois"] < 13) +{ + $motmois=dol_print_date(mktime(0, 0, 0, $_SESSION["mois"], 10), '%B'); +} +else +{ + $motmois=dol_print_date(dol_now(), '%B'); +} + + +//Debut du formulaire et bandeaux de tete +print '
'."\n"; +print ''; + +print '
'. $langs->trans("CreatePoll")." (2 / 2)" .'
'."\n"; + +//affichage de l'aide pour les jours +print '
'."\n"; +print $langs->trans("OpenSurveyStep2")."\n"; +print '
'."\n"; + +//debut du tableau qui affiche le calendrier +print '
'."\n"; +print ''."\n"; +print ''; +print ''; +print ''."\n"; +print '
'.$motmois.' '.$_SESSION["annee"].'
'; +print ''; +print '
'; +print '
'."\n"; +print ''."\n"; +print ''."\n"; + +//affichage des jours de la semaine en haut du tableau +for($i = 0; $i < 7; $i++) +{ + print ''; +} + +print ''."\n"; + +//ajout d'une entrée dans la variable de session qui contient toutes les dates +if (issetAndNoEmpty('choixjourajout')) { + if (!isset($_SESSION["totalchoixjour"])) { + $_SESSION["totalchoixjour"]=array(); + } + + // Test pour éviter les doublons dans la variable qui contient toutes les dates + $journeuf = true; + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true && issetAndNoEmpty('choixjourajout') === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + if ($_SESSION["totalchoixjour"][$i] == mktime(0, 0, 0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"])) { + $journeuf=false; + } + } + } + + // Si le test est passé, alors on insere la valeur dans la variable de session qui contient les dates + if ($journeuf && issetAndNoEmpty('choixjourajout') === true) { + array_push ($_SESSION["totalchoixjour"],mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"])); + sort ($_SESSION["totalchoixjour"]); + $cle=array_search (mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"]), $_SESSION["totalchoixjour"]); + + //On sauvegarde les heures deja entrées + for ($i = 0; $i < $cle; $i++) { + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + if (issetAndNoEmpty('horaires'.$i) === true && issetAndNoEmpty($i, $_POST['horaires'.$i]) === true) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } + + for ($i = $cle; $i < count($_SESSION["totalchoixjour"]); $i++) { + $k = $i + 1; + if (issetAndNoEmpty('horaires'.$i) === true && issetAndNoEmpty($i, $_POST['horaires'.$i]) === true) { + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$k"][$j] = $_POST["horaires$i"][$j]; + } + } + } + + unset($_SESSION["horaires$cle"]); + } +} + +//retrait d'une entrée dans la variable de session qui contient toutes les dates +if (issetAndNoEmpty('choixjourretrait')) { + //On sauvegarde les heures deja entrées + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + if ($_SESSION["totalchoixjour"][$i] == mktime(0, 0, 0, $_SESSION["mois"], $_POST["choixjourretrait"][0], $_SESSION["annee"])) { + for ($j = $i; $j < count($_SESSION["totalchoixjour"]); $j++) { + $k = $j+1; + $_SESSION["horaires$j"] = $_SESSION["horaires$k"]; + } + + array_splice($_SESSION["totalchoixjour"], $i,1); + } + } +} + +//report des horaires dans toutes les cases +if (issetAndNoEmpty('reporterhoraires')) { + $_SESSION["horaires0"] = $_POST["horaires0"]; + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + $j = $i+1; + $_SESSION["horaires$j"] = $_SESSION["horaires$i"]; + } +} + +//report des horaires dans toutes les cases +if (issetAndNoEmpty('resethoraires')) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + unset ($_SESSION["horaires$i"]); + } +} + +// affichage du calendrier +print ''."\n"; + +for ($i = 0; $i < $nbrejourmois + $premierjourmois; $i++) { + $numerojour = $i-$premierjourmois+1; + + // On saute a la ligne tous les 7 jours + if (($i%7) == 0 && $i != 0) { + print ''."\n"; + } + + // On affiche les jours precedants en gris et incliquables + if ($i < $premierjourmois) { + print ''."\n"; + } else { + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true) { + for ($j = 0; $j < count($_SESSION["totalchoixjour"]); $j++) { + //affichage des boutons ROUGES + if (date("j", $_SESSION["totalchoixjour"][$j]) == $numerojour && date("n", $_SESSION["totalchoixjour"][$j]) == $_SESSION["mois"] && date("Y", $_SESSION["totalchoixjour"][$j]) == $_SESSION["annee"]) { + print ''."\n"; + $dejafait = $numerojour; + } + } + } + + //Si pas de bouton ROUGE alors on affiche un bouton VERT ou GRIS avec le numéro du jour dessus + if (isset($dejafait) === false || $dejafait != $numerojour){ + //bouton vert + if (($numerojour >= $jourAJ && $_SESSION["mois"] == $moisAJ && $_SESSION["annee"] == $anneeAJ) || ($_SESSION["mois"] > $moisAJ && $_SESSION["annee"] == $anneeAJ) || $_SESSION["annee"] > $anneeAJ) { + print ''."\n"; + } else { //bouton gris + print ''."\n"; + } + } + } +} + +//fin du tableau +print ''."\n"; +print '
'. dol_print_date(mktime(0,0,0,0, $i,10),'%A') .'
'.$numerojour.'
'."\n"; +print '
'."\n"; + +//traitement de l'entrée des heures dans les cases texte +$errheure = $erreur = false; +if (issetAndNoEmpty('choixheures') || issetAndNoEmpty('choixheures_x')) { + //On sauvegarde les heures deja entrées + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true && issetAndNoEmpty('nbrecaseshoraires', $_SESSION) === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } + + //affichage des horaires + if (issetAndNoEmpty('totalchoixjour', $_SESSION) === true && issetAndNoEmpty('nbrecaseshoraires', $_SESSION) === true) { + for ($i = 0; $i < count($_SESSION["totalchoixjour"]); $i++) { + //affichage des 5 cases horaires + for ($j = 0; $j < $_SESSION["nbrecaseshoraires"]; $j++) { + $case = $j + 1; + + if (isset($_POST['horaires'.$i]) === false || isset($_POST['horaires'.$i][$j]) === false) { + $errheure[$i][$j]=true; + $erreur=true; + $_SESSION["horaires$i"][$j]=$_POST["horaires$i"][$j]; + continue; + } + + //si c'est un creneau type 8:00-11:00 + if (preg_match("/(\d{1,2}:\d{2})-(\d{1,2}:\d{2})/", $_POST["horaires$i"][$j], $creneaux)) { + //on recupere les deux parties du preg_match qu'on redécoupe autour des ":" + $debutcreneau=explode(":", $creneaux[1]); + $fincreneau=explode(":", $creneaux[2]); + + //comparaison des heures de fin et de debut + //si correctes, on entre les données dans la variables de session + if ($debutcreneau[0] < 24 && $fincreneau[0] < 24 && $debutcreneau[1] < 60 && $fincreneau[1] < 60 && ($debutcreneau[0] < $fincreneau[0] || ($debutcreneau[0] == $fincreneau[0] && $debutcreneau[1] < $fincreneau[1]))) { + $_SESSION["horaires$i"][$j] = $creneaux[1].'-'.$creneaux[2]; + } else { //sinon message d'erreur et nettoyage de la case + $errheure[$i][$j]=true; + $erreur=true; + } + } elseif (preg_match(";^(\d{1,2}h\d{0,2})-(\d{1,2}h\d{0,2})$;i", $_POST["horaires$i"][$j], $creneaux)) { //si c'est un creneau type 8h00-11h00 + //on recupere les deux parties du preg_match qu'on redécoupe autour des "H" + $debutcreneau=preg_split("/h/i", $creneaux[1]); + $fincreneau=preg_split("/h/i", $creneaux[2]); + + //comparaison des heures de fin et de debut + //si correctes, on entre les données dans la variables de session + if ($debutcreneau[0] < 24 && $fincreneau[0] < 24 && $debutcreneau[1] < 60 && $fincreneau[1] < 60 && ($debutcreneau[0] < $fincreneau[0] || ($debutcreneau[0] == $fincreneau[0] && $debutcreneau[1] < $fincreneau[1]))) { + $_SESSION["horaires$i"][$j] = $creneaux[1].'-'.$creneaux[2]; + } else { //sinon message d'erreur et nettoyage de la case + $errheure[$i][$j]=true; + $erreur=true; + } + } elseif (preg_match(";^(\d{1,2}):(\d{2})$;", $_POST["horaires$i"][$j], $heures)) { //si c'est une heure simple type 8:00 + //si valeures correctes, on entre les données dans la variables de session + if ($heures[1] < 24 && $heures[2] < 60) { + $_SESSION["horaires$i"][$j] = $heures[0]; + } else { //sinon message d'erreur et nettoyage de la case + $errheure[$i][$j]=true; + $erreur=true; + } + } elseif (preg_match(";^(\d{1,2})h(\d{0,2})$;i", $_POST["horaires$i"][$j], $heures)) { //si c'est une heure encore plus simple type 8h + //si valeures correctes, on entre les données dans la variables de session + if ($heures[1] < 24 && $heures[2] < 60) { + $_SESSION["horaires$i"][$j] = $heures[0]; + } else { //sinon message d'erreur et nettoyage de la case + $errheure[$i][$j]=true; + $erreur=true; + } + } elseif (preg_match(";^(\d{1,2})-(\d{1,2})$;", $_POST["horaires$i"][$j], $heures)) { //si c'est un creneau simple type 8-11 + //si valeures correctes, on entre les données dans la variables de session + if ($heures[1] < $heures[2] && $heures[1] < 24 && $heures[2] < 24) { + $_SESSION["horaires$i"][$j] = $heures[0]; + } else { //sinon message d'erreur et nettoyage de la case + $errheure[$i][$j]=true; + $erreur=true; + } + } elseif (preg_match(";^(\d{1,2})h-(\d{1,2})h$;", $_POST["horaires$i"][$j], $heures)) { //si c'est un creneau H type 8h-11h + //si valeures correctes, on entre les données dans la variables de session + if ($heures[1] < $heures[2] && $heures[1] < 24 && $heures[2] < 24) { + $_SESSION["horaires$i"][$j] = $heures[0]; + } else { //sinon message d'erreur et nettoyage de la case + $errheure[$i][$j]=true; + $erreur=true; + } + } elseif ($_POST["horaires$i"][$j]=="") { //Si la case est vide + unset($_SESSION["horaires$i"][$j]); + } else { //pour tout autre format, message d'erreur + //$errheure[$i][$j]=true; + //$erreur=true; + $_SESSION["horaires$i"][$j] = $_POST["horaires$i"][$j]; + } + } + } + } +} + +print '
'."\n"; + +// affichage de tous les jours choisis +if (issetAndNoEmpty('totalchoixjour', $_SESSION) && (!issetAndNoEmpty('choixheures_x') || $erreur)) +//if (1==1 || GETPOST($_SESSION['totalchoixjour']) && (! GETPOST('choixheures_x') || $erreur)) +{ + //affichage des jours + print '
'."\n"; + print ''. $langs->trans("SelectedDays") .' :'."
\n"; + print $langs->trans("SelectDayDesc")."
\n"; + print ''."\n"; + print ''."\n"; + print ''."\n"; + + for ($i = 0; $i < $_SESSION["nbrecaseshoraires"]; $i++) { + $j = $i+1; + print ''."\n"; + } + + if ($_SESSION["nbrecaseshoraires"] < 10) { + print ''."\n"; + } + + print ''."\n"; + + //affichage de la liste des jours choisis + for ($i=0;$i'."\n"; + print ''; + + $affichageerreurfindeligne=false; + + //affichage des cases d'horaires + for ($j=0;$j<$_SESSION["nbrecaseshoraires"];$j++) { + //si on voit une erreur, le fond de la case est rouge + if (isset($errheure[$i][$j]) && $errheure[$i][$j]) { + print ''."\n"; + $affichageerreurfindeligne=true; + } else { //sinon la case est vide normalement + if (issetAndNoEmpty('horaires'.$i, $_SESSION) === false || issetAndNoEmpty($j, $_SESSION['horaires'.$i]) === false) { + if (issetAndNoEmpty('horaires'.$i, $_SESSION) === true) { + $_SESSION["horaires$i"][$j] = ''; + } else { + $_SESSION["horaires$i"] = array(); + $_SESSION["horaires$i"][$j] = ''; + } + } + + print ''."\n"; + } + } + + if ($affichageerreurfindeligne) { + print ''."\n"; + } + + print ''."\n"; + } + + print '
'. $langs->trans("Time") .' '.$j.'
'.dol_print_date($_SESSION["totalchoixjour"][$i], 'daytext').' ('.dol_print_date($_SESSION["totalchoixjour"][$i], '%A').')'. _("Bad format!") .'
'."\n"; + + //affichage des boutons de formulaire pour annuler, effacer les jours ou créer le sondage + print ''."\n"; + print ''."\n"; + print ''."\n"; + print''."\n"; + print ''."\n"; + print '


'."\n"; + + //si un seul jour et aucunes horaires choisies, : message d'erreur + if ((GETPOST('choixheures') || GETPOST('choixheures_x')) && (count($_SESSION["totalchoixjour"])=="1" && $_POST["horaires0"][0]=="" && $_POST["horaires0"][1]=="" && $_POST["horaires0"][2]=="" && $_POST["horaires0"][3]=="" && $_POST["horaires0"][4]=="")) { + print '
'. _("Enter more choices for the voters") .'
'."\n"; + $erreur=true; + } +} + +//s'il n'y a pas d'erreur et que le bouton de creation est activé, on demande confirmation +if (!$erreur && (GETPOST('choixheures') || GETPOST('choixheures_x'))) { + $taille_tableau=sizeof($_SESSION["totalchoixjour"])-1; + $jour_arret = $_SESSION["totalchoixjour"][$taille_tableau]+200000; + $date_fin=dol_print_date($jour_arret, 'dayhourtext'); + + print '
'. $langs->trans("PollWillExpire",2) .'
'. $langs->trans("RemovalDate") .' : '.$date_fin.'
'."\n"; + print '
'."\n"; + print '
'."\n"; + print ''. _("Once you have confirmed the creation of your poll, you will be automatically redirected on the page of your poll.
Then, you will receive quickly an email contening the link to your poll for sending it to the voters.") .'
'."\n"; + print'
'."\n"; + // print'

'."\n"; + // print 'Pour finir la création du sondage, cliquez sur le bouton ajout ci-dessous'."\n"; + // print '

'."\n"; + print ''."\n"; + print ''."\n"; + print''."\n"; + print '
'. $langs->trans("BackToHoursSetup") .'
'. $langs->trans("CreatePoll") .'
'."\n"; +} + +print ''."\n"; +print ''."\n"; +print ''."\n"; +//fin du formulaire et bandeau de pied +print ''."\n"; +//bandeau de pied +print '



'."\n"; +print '
'."\n"; + +llxFooterSurvey(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/public/create_survey.php b/htdocs/opensurvey/public/create_survey.php new file mode 100755 index 00000000000..c5af8db0cab --- /dev/null +++ b/htdocs/opensurvey/public/create_survey.php @@ -0,0 +1,199 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/public/create_survey.php + * \ingroup opensurvey + * \brief Page to create a new survey + */ + +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + +$langs->load("opensurvey@opensurvey"); + +$origin=GETPOST('origin','alpha'); + + +// On teste toutes les variables pour supprimer l'ensemble des warnings PHP +// On transforme en entites html les données afin éviter les failles XSS +$post_var = array('titre', 'nom', 'adresse', 'commentaires', 'canedit', 'mailsonde', 'creation_sondage_date', 'creation_sondage_date_x', 'creation_sondage_autre', 'creation_sondage_autre_x'); +foreach ($post_var as $var) +{ + $$var = GETPOST($var); +} + +// On initialise egalement la session car sinon bonjour les warning :-) +$session_var = array('titre', 'nom', 'adresse', 'commentaires', 'mailsonde', 'canedit'); +foreach ($session_var as $var) +{ + if (isset($_SESSION[$var])) $_SESSION[$var] = null; +} + +// On initialise également les autres variables +$erreur_adresse = false; +$erreur_injection_titre = false; +$erreur_injection_nom = false; +$erreur_injection_commentaires = false; +$cocheplus = ''; +$cochemail = ''; + +// Jump to correct page +if (GETPOST("creation_sondage_date") || GETPOST("creation_sondage_autre") || GETPOST("creation_sondage_date_x") || GETPOST("creation_sondage_autre_x")) +{ + $_SESSION["titre"] = $titre; + $_SESSION["nom"] = $nom; + $_SESSION["adresse"] = $adresse; + $_SESSION["commentaires"] = $commentaires; + + unset($_SESSION["canedit"]); + $_SESSION["canedit"] = $canedit; + + unset($_SESSION["mailsonde"]); + if ($mailsonde !== null) { + $_SESSION["mailsonde"] = true; + } else { + $_SESSION["mailsonde"] = false; + } + + if(validateEmail($adresse) === false) { + $erreur_adresse = true; + } + + //var_dump($titre.' - '.$nom.' - '.$adresse.' - '.!$erreur_adresse.' - '.! $erreur_injection_titre.' - '.! $erreur_injection_commentaires.' - '.! $erreur_injection_nom.' - '.$creation_sondage_date.' - '.$creation_sondage_autre); exit; + + if ($titre && $nom && $adresse && !$erreur_adresse && ! $erreur_injection_titre && ! $erreur_injection_commentaires && ! $erreur_injection_nom) + { + if (! empty($creation_sondage_date)) + { + header("Location: choix_date.php".($origin?'?origin='.$origin:'')); + exit(); + } + + if (! empty($creation_sondage_autre)) + { + header("Location: choix_autre.php".($origin?'?origin='.$origin:'')); + exit(); + } + } +} + + + + +/* + * View + */ + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeaderSurvey($langs->trans("OpenSurvey"), "", 0, 0, $arrayofjs, $arrayofcss); + + +print '
'. $langs->trans("CreatePoll").' (1 / 2)' .'
'."\n"; + + +//debut du formulaire +print '
'."\n"; +print ''; + +print '
'."\n"; +print '
'. $langs->trans("YouAreInPollCreateArea") .'

'."\n"; + +//Affichage des différents champs textes a remplir +print ''."\n"; + +print ''."\n"; +if (! $_SESSION["titre"] && (GETPOST('creation_sondage_date') || GETPOST('creation_sondage_autre') || GETPOST('creation_sondage_date_x') || GETPOST('creation_sondage_autre_x'))) +{ + print ""."\n"; +} + +print ''."\n"; +print ''."\n"; +print ''."\n"; +print ''."\n"; + +if (! $_SESSION["nom"] && (GETPOST('creation_sondage_date') || GETPOST('creation_sondage_autre') || GETPOST('creation_sondage_date_x') || GETPOST('creation_sondage_autre_x'))) +{ + print ""."\n"; +} + +print ''."\n"; +print ''."\n"; + +if (!$_SESSION["adresse"] && (GETPOST('creation_sondage_date') || GETPOST('creation_sondage_autre') || GETPOST('creation_sondage_date_x') || GETPOST('creation_sondage_autre_x'))) +{ + print ""."\n"; +} elseif ($erreur_adresse && (GETPOST('creation_sondage_date') || GETPOST('creation_sondage_autre') || GETPOST('creation_sondage_date_x') || GETPOST('creation_sondage_autre_x'))) +{ + print ""."\n"; +} + +print ''."\n"; +print '
'. $langs->trans("PollTitle") .'" . $langs->trans("FieldMandatory") . "
'. $langs->trans("Description") .'
'. $langs->trans("OpenSurveyYourName") .''; + +print '" . $langs->trans("FieldMandatory") . "
'. $langs->trans("OpenSurveyYourEMail") .''; + +print '" .$langs->trans("FieldMandatory") . " " . _("The address is not correct! (You should enter a valid email address in order to receive the link to your poll)") . "
'."\n"; + +//focus javascript sur le premier champ +print ''."\n"; + +print '
'."\n"; + +#affichage du cochage par défaut +$cocheplus=''; +if ($_SESSION["canedit"]) $cocheplus="checked"; + +print ''. $langs->trans("VotersCanModify") .'
'."\n"; + +if ($_SESSION["mailsonde"]) $cochemail="checked"; + +print ''. $langs->trans("ToReceiveEMailForEachVote") .'
'."\n"; + +if (GETPOST('choix_sondage')) +{ + if (GETPOST('choix_sondage') == 'date') print ''; + else print ''; + print ''; + print '
trans("TypeDate"):$langs->trans("TypeClassic")).')">'; +} +else +{ + //affichage des boutons pour choisir sondage date ou autre + print '
'."\n"; + print ' '."\n"; + print ''."\n"; + print ' '."\n"; + print ''."\n"; + print '
'. _("Schedule an event") .'
'. _("Make a choice") .'
'."\n"; +} +print '


'."\n"; +print '
'."\n"; +print '
'."\n"; + +llxFooterSurvey(); + +$db->close(); +?> diff --git a/htdocs/opensurvey/public/exportcsv.php b/htdocs/opensurvey/public/exportcsv.php new file mode 100755 index 00000000000..b2ee0cc1eea --- /dev/null +++ b/htdocs/opensurvey/public/exportcsv.php @@ -0,0 +1,154 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/public/exportcsv.php + * \ingroup opensurvey + * \brief Page to list surveys + */ + + +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php"); + +$action=GETPOST('action'); +$numsondage = $numsondageadmin = ''; +if (GETPOST('sondage')) +{ + if (strlen(GETPOST('sondage')) == 24) // recuperation du numero de sondage admin (24 car.) dans l'URL + { + $numsondageadmin=GETPOST("sondage",'alpha'); + $numsondage=substr($numsondageadmin, 0, 16); + } + else + { + $numsondageadmin=''; + $numsondage=GETPOST("sondage",'alpha'); + } +} + +$object=new Opensurveysondage($db); +$result=$object->fetch(0,$numsondage); +if ($result <= 0) dol_print_error('','Failed to get survey id '.$numsondage); + + +/* + * Actions + */ + + + +/* + * View + */ + +$now=dol_now(); + +$nbcolonnes=substr_count($object->sujet,',')+1; +$toutsujet=explode(",",$object->sujet); +#$toutsujet=str_replace("°","'",$toutsujet); + +// affichage des sujets du sondage +$input.=$langs->trans("Name").";"; +for ($i=0;$toutsujet[$i];$i++) +{ + if ($object->format=="D"||$object->format=="D+") + { + $input.=''.dol_print_date($toutsujet[$i],'dayhour').';'; + } else { + $input.=''.$toutsujet[$i].';'; + } +} + +$input.="\r\n"; + +if (strpos($object->sujet,'@') !== false) +{ + $input.=";"; + for ($i=0;$toutsujet[$i];$i++) + { + $heures=explode("@",$toutsujet[$i]); + $input.=''.$heures[1].';'; + } + + $input.="\r\n"; +} + + +$sql ='SELECT nom, reponses'; +$sql.=' FROM '.MAIN_DB_PREFIX."opensurvey_user_studs"; +$sql.=" WHERE id_sondage='" . $db->escape($numsondage) . "'"; +$sql.=" ORDER BY id_users"; +dol_syslog("sql=".$sql); +$resql=$db->query($sql); +if ($resql) +{ + $num=$db->num_rows($resql); + $i=0; + while ($i < $num) + { + $obj=$db->fetch_object($resql); + + // Le nom de l'utilisateur + $nombase=str_replace("°","'",$obj->nom); + $input.=$nombase.';'; + + //affichage des resultats + $ensemblereponses=$obj->reponses; + for ($k=0;$k<$nbcolonnes;$k++) + { + $car=substr($ensemblereponses,$k,1); + if ($car == "1") + { + $input.='OK;'; + $somme[$k]++; + } + else if ($car == "2") + { + $input.='KO;'; + $somme[$k]++; + } + else + { + $input.=';'; + } + } + + $input.="\r\n"; + $i++; + } +} +else dol_print_error($db); + + +$filesize = strlen( $input ); +$filename=$numsondage."_".dol_print_date($now,'%Y%m%d%H%M').".csv"; + + + +header( 'Content-Type: text/csv; charset=utf-8' ); +header( 'Content-Length: '.$filesize ); +header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); +header( 'Cache-Control: max-age=10' ); +echo $input; + +exit; +?> \ No newline at end of file diff --git a/htdocs/opensurvey/public/images/accept-24.png b/htdocs/opensurvey/public/images/accept-24.png new file mode 100755 index 0000000000000000000000000000000000000000..65ca043ee12627bd42bb6e8563fb73ed61e07d06 GIT binary patch literal 1696 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 P00000NkvXXu0mjfpFpSJ literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/accept.png b/htdocs/opensurvey/public/images/accept.png new file mode 100755 index 0000000000000000000000000000000000000000..ada57a9ae60ebccf4cf8f4fcb9523cffbc6c51d0 GIT binary patch literal 901 zcmV;01A6?4P)dCy7H)TT{LFKH{8ZL@ZD61C8Mkl_ujB9adZqJv$Wvbir}b(lh?Vj@yy zDnk@6=ob|fyNMvPxT#26S7&h_#@ZFqW~3%<(zI#pN#FFGvo{Bgm-o}*egDtz{BIA3 z_fBYJ*hNHfhb+r0HC=NVmpVd9M){3WdZE6yKJ<1x_xfWbJRe9DU?H*mDuKLMu!}dV|-2 z45dgg;18dCg;ra0C(CAY4q}9iMqdPei9Yrn>bnGIu^lD>ka-;?R*t=c9xG1%eKlLHJi06p~{2TaLg&ig2L! z6s`_-;ojO)S(C!Mxp*QTI6iRR_bl3v@&dwwIF^9`!V3(*8-ULmze9s9r&2v_z1v!>vKds9;V5t*Gna;{QRw;{mX?1CZ~d1BsJ;6n(zDN4 zc@z_~3WA>Vz1-CFWc2&)^<^GA6Y6#NdhtQr{O25oll>@?i?P#l6lP+<-QjNB9{dTF z7Bd{C1fGtKBe3jN%mDbGtS@USwZm;&i{&-ng3TWfMy{jWQjJFYawKP`ao|xKD&z<& zFAAI4iRXzp{GQGjmrkd9I{LS_SjiY>XcFFr(`c}-X6ft3{5aN!;2$Tz(QB-%DWepN z>_D74u&0rgkeo~g?nW;AhT>=0*i|MFvB~`-njGtl;OFrnoPFwr)11j~pQ;O}weP}; z(k(%5e0J`}e@s+Ipl8rHU zIgy+Q49)cUejW0$fT>py9`r+6Ldk{IAM8gZzo;{l$!xBvS)k_4l!HhTIjoV)zP}S)WN_kl zq-G<=TaoNUed!7`l&s2XirA5*)L&Iy^TteXpIlD}Av;8oFgvS;ojIKg(JVFWTv1W^ bj-CGpV^3H~a~vrn00000NkvXXu0mjfc^9ui literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/add-16.png b/htdocs/opensurvey/public/images/add-16.png new file mode 100755 index 0000000000000000000000000000000000000000..23d5bed776023cee0402e7c0b1649d57704e36d3 GIT binary patch literal 845 zcmV-T1G4;yP)|8WvWN;ij47sw?j7x|_Q?^be&3;f({(`?mg#x_uO;8OYpDlu%$EA zuI)_08kf3~5Dg=PhA~gC`Z^j=n`pc{F_|RbG;;=ff73Dh!F}Z_$ypIYvPFd)CkRH8 zFyS|%$E|674QDu1^om z4GRUdj@Jnc>8AE0x1B{bB>{*sgK2u=tYCmbPggZiClKOvf8L1Mc>^Ueqwlh>BOZwD zULZKQ<^0mts}}=$(CartQV3YWp={MNy}cH11r$v{jFOCmID|zO@7e(0U2iENX=Zoh zdqYWPs)R2-D`K>R1zT#_fa=^%9XAc{#FW^thTMNd>FUGgcaDkycR~r z0*-aUZOXa`9)tk2x67Y+FPAjnZVL=n#> zu3=(+9KBy0`0;ciK$fj#+;uPQB_I8E_=Vpypih@;Uyp`uE&B5G+cFGC1{PHlj<6W= zS`fYFY15za#6x?lbsdLZJ{6kwE6L?phe!F%I z+R$Fnl(x$&CBqZ7>xuLdc(S!g$4B2)LxiB?XpkT@#XxEBw1XG-{E>2I)@D;z{)O~B zo)&%;Y?xJ9D8FjJasZ=fh|j2)3u;gve;dR|q;OHnzb)OmjBRvPr4=V{w2_c(#EhJz z3nwlCl1SzJDWWMa$6FDKo&5VVC0d~|m964j)&k-*X3JE*Qa~D$hiALAh`ey8p2Xyz X@8?yrXY&hd00000NkvXXu0mjf$sm%K literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/add-24.png b/htdocs/opensurvey/public/images/add-24.png new file mode 100755 index 0000000000000000000000000000000000000000..c63af7f39062ad0d5b9f1c5f9afa617e7ada0d5d GIT binary patch literal 1393 zcmV-%1&;cOP)6#sqq-gdW-t$P6jF>D#QF+f0xI6@`_MgoI~JVHX0#Az@Rd1!=13>pF5Wz9XWWc(0uI%Mny0zW9+x2yOZ?9i(N7-nn;Up(HJ?A^;_ucdQ zO7P$GBIWg*1|<`6$@HuVN*19CS1)n*b}1G~#C7_!hVs3!0+2EE^B4}5`LFSd=ap&6 zoDyL2gfMb4M6j#^$AA_#hX!~50PdU*D{WVUzeglgP`}&%2f$F?mo;1e$-HtCJFQSg z(G)+jGbC`F0x3cuN(@4j{UHV(frZ1VMQ0nq?c;*%yzBpx`hP|_k_>>Qd~)Kd?2U8Q z7_hR~jTfE|(4f(PPXa&Y*l(iBeQpkI?L3-medsyo`T+{wq_O0u0ghyru4^f1@@;i`2UrSZ0n1X!LjE91h--A1x) zjV+!E!Ovnq;1Cj-q=ga{27@98Aw9gL2)qgqpqFW=?#))e1j$R(V06Xfo>+{Yc*SJWPJBO~JrsIuKc7cA0#c5DM25Ir@j|vcP z^_4{ds+S$edAnkZQ%y^^D+NwLn~;w3slQ^PevT?X@;9Q|x+LL@T}Xk|rB`dxT1VUY zptYJn$F)?|8wzLS`QfFvHrotPl*D|$S8xTBh5_sp;M>-v31^~ice+jR1UL)~aA^Ig zwV9+$)&**sWIm!0bhvmp1`}@|r4I@(W3pkkD);#A;Tub7(sSMYJX(7VYUf#Yclt^0 z%NphIl~~s_+EU>Qv6z}xjE#ARVdS#ojvT{-A+c_XC=uFe!MJTma^Y0R4p@acc!Ml3f z+xxRlA64A!N>>3k=O4ntNo$`8;D-GSjy?R40ubCB25?vX9VDrlFdu9*7Ks$O-e!U? zOvgepU|IGiq-nF_0T$)Gj&xltWuAZw*E-IPXi+yVxlSU;`QWE1`pcTCPPk{!1530` zkMFr`EYHm4(Cjv%$IFjyi(xu4|13@0%;9u2VSD|EIT*2U`ua6!x6`4siwNvDpNN`P zlx|76uw<(q{Q(Vb^=2eZ!Lj1gC@{qUS_hl3xo%zZT6E~>24E4qXovjUBX!VNoryH< zxR_qZ=vdtEH^JuT6CA%=_#=waXQ*<1%cSAh|-GL ztNHV#pQaH%t-)<~1_Vhn%DEzc7s_XCRORXir%?Iut5NoF2yogs1nDl4PIoG3aIT>0 zUq-I$uNUo1+gh;7s1~|WFu^UQJSoQzi)H%Qa9#3W1~JNUTO^>s=OnSnp zB+X|us2smAwIp+aiD>f;2orYHb14RZpw)*^L%$Mf?7s?G*+u;to(?n?z+;+Ac^%PS8~fPv4sYG{I}))SONY8M7L~y&{-FO00000NkvXXu0mjf-!+?f literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/add.png b/htdocs/opensurvey/public/images/add.png new file mode 100755 index 0000000000000000000000000000000000000000..7409ef332d2435c3fb43c879a80c9fcb5820f796 GIT binary patch literal 2017 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≫m{EQP0 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 QB*afaMip8uW%lL&0DDlgIRF3v literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/fforward.png b/htdocs/opensurvey/public/images/fforward.png new file mode 100755 index 0000000000000000000000000000000000000000..369084cdf149b47c66e5ef6dc31a21876f3feb40 GIT binary patch literal 1359 zcmV-V1+e;wP)CZi$4qnQcVbffDjdk z2}(pIQA7kZ0+p92L=;N3K%u!|Qg#-Fyw2a+==nqj|9}0M>^+4;Jeti)-o(Y23>US-C)x z6GnUjAX&hILBQJy+^T_g>7=3G_~UnIYB}vY|0Dtn&9#={xvOmjuS-&T2I7(jz#eah z)xuyg3>dl&UDKhc8kDetus;aB^&XTnyEVP3W+UzYfTrFXfkbn+ZQ_C@_PqIU3`;{o zvV)eIps^=`^QUQ}Cw&hGWQ5!uP--e^9{dh4mJ*isIKfui#D!&!DX+pgYB(5qj3|&n z3rQNTKPS>v6}lXTK~Iy=w1pnDL#{cB$i@BJ39qax!CYy??~2f|@*<%cq}IFhdnt=RV*XVj>!7>^=p#f)sMnlm;A z(D=}Y)!(1Pkf&3yr8qBUZ}9~1{ts37`Fg9!8$(ekC)^ab8axM9U*l2tMcRs;Z&(Kn zgHEx`BS2j83>PZqjfYAn+fiAAEywF16Tp%eGV#%(NhGm>uTEUXhRRy_nG~xDdQgT& ziKlklhxf?(FS)re>7~VooimpTcD2(d7G^kXcyscz*z?zI)cGP*i_F9u94Db05fU481fQKDe;!;ocW)c+jOW~JAFIgF1o0T4m{`Me0Ihhnq8)+Ikio?}&cs%LUgQ}P7&W|_$6rf8V4wuF1uIBp>J(ogED1)JBC6~kD zP&5UGq9EYXkjBMfez<4nQ*XPTaCRaB5|PMofXCxHNJYiiKkd>_VaBl7d|p-?2UwsUiH`)6im z?yv$yMMbG9rD{AmB{|(-FhHl*V`yjy3kxpvJ?q7jZYx$-R}l;bVS8$YTrNjPXQ#Wf zqaz%{6L!FlkB`6CL3SG&?$SP=k3DR$SYWf+NL2-PcXv@=Umwm7tyT-C(}}{u!g6wU z{OlqLYieu14BGA5qoX4Pi2c^qRumT(~!u^5Y?}wKVy~N$&;UT#MG=j?2u{vCRsT!qzu8H?ctwUf0&vu#sL z`${Uzkw_m%Q)kJMMFRidrcptD(PKhdAeUsCe7gvI{~G7tEBZ7YHBni200000NkvXX Hu0mjf!zXq{ literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/info.png b/htdocs/opensurvey/public/images/info.png new file mode 100755 index 0000000000000000000000000000000000000000..4c665a4f0a10633d475480553f673bceb10f594a GIT binary patch literal 777 zcmV+k1NQuhP)2Rxem5IpiJG?3n;E5IYLG=}N_7!xQP~$15m*-)L}4Iw6GYKXN|*+M zrQQg2;YafWLX*(SCOWm5Ij3$qx3%qkdz?+|5kZ3BwVCn0t=d9> zXg}b{sq^mi!mCn2wiO<)hvb8p@nGcH=i{+zX0?nEnUu=nz%QHewz+DC05N_*@yYT* zU2a)gtS$o!HXcD@K&oKykY9lpz`5Xu5Yb=8#9%K*3^knu$O)8CrQMcVnOAbz-!{7& zSfB+lb%E{?5i}=eYtMzFuD3qA1IPT-bpqTA0KzF7^#$j`)A#LyOvYey3RDW6PG!iY z1S8P=BGA>`3R7PrWRtyl4L#%S8z0gkN-aC`%DA-LZ0NNNQ4$8)2kVl6&Pia{@Crsl zBjhFna^kG$`iMPs1J=Ivr%aFolxjoN8ck$eDpZ@c_%CnCV#3_S5LRZ4keT}-ag5&YGbu)2kHks7bO=lgU1AuDDys3k>KYjSBeJ)s zauOp}+N0$R`|Cd8#ba3%?*>FV*vg00000NkvXX Hu0mjf>jh(& literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/logo_uds_bandeau.gif b/htdocs/opensurvey/public/images/logo_uds_bandeau.gif new file mode 100755 index 0000000000000000000000000000000000000000..3132c13a75a91be0d8a555378ddcd370e6828b29 GIT binary patch literal 3391 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 >b8vY=(IPpDf^πLu6f#KcpaWJR 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 literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/next.png b/htdocs/opensurvey/public/images/next.png new file mode 100755 index 0000000000000000000000000000000000000000..24d94e830a33157c791a714ab60565f9aebf0d6e GIT binary patch literal 1349 zcmV-L1-kl)P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igW1 z5hpUz)>8fe00hNJL_t(Y$BmXrY+OYUhQIE9%e?W79pfwxORy4$m?T&sL1aOg9fCLj zVmSbU2ysD3zzKwekPrwFaRG!7%LNhO64na{5MqgR~3P>KRv+y>qK7QzA9w{sEjCZIv>H#~45ati_dLTsgtUF*b^@afC}s1eG>S9HCi`HZo8pNMcO68$YuDY#H6V z6&Q4YBP_pFU3>Se8OxRwo{3<>5F15c45)$}A*vYXaBXF94yn}(Z;}{|=9tFrEh~`x z84Iip=dbB&?_b&i$2nj!496j^oDj~Q*)m?5dm`Z}EBk=UEO1TRic4_iQUMPC&cO27 z3D2(W<>GnmXr3KYda4073J5yeQ4vhwDD|!axW*E-tuCLo1Vm5~)C-#XmVv7m&g9bh zT|9S19~-V*!onG)qdfTOz*yl)rHpYF6(O8G55n>)>#DPQf{tndo_jRU(L5&~87UG) zwU~|J+*3Pw=ceU6c>V%9LetXyS3IsQLA_w25L-T>$GS?j)Fg4LGC+1<7*r0+#K2nC zEkBu$Z(GGp{c~IU&2uIUix7)ohSzcgxk01MUD3IF0PqTe{76&s=1{BS*g48fP z%7c;G1dqM3jTb%}!bf2X&^IznSa>Y;2@oMaxDQRowm2ZSrOJ(Q&lyFYH5Eo{$oK@a z+hWc;eJ&f`|CV)6f57J7Mp0v0L>?X*!5^xjxhLKA5&3~1?>B%mN%gz#JD=|}VM2bW zhNKNN_n7)PT2644GBS}K%|m@0lY6L?!CJJDA+>QNtugxcLp!ulU+MrQZ|s)Z$PIDt z*~U0qfO&x+00m96Vtu4oSLldBo+INEs0ia=PbYk z0h%@nKANHUFYz92G{6h#;3m?Y?>`AVb!0zyFa7b$MJ7y^hTXj_(lnb)ykh~YVnk8z zQ4!MbKV*FS8?OMjAFJUg@Oootdzc>>S`*IcwYF5jMj-@6bu~rJz!-xuwy5MH__1N? zTVKx8!A%bXcTH`X(>48-xL|$UyLzCsaFq#WEdb*VOCrru^8JIPL!WEo=Py1){5`-I z$NQ>ijx&L4vB7|ApS8%ul`a%y;?S^+{ka3lo6nYSrUUo~KxWuI!U%fE00000NkvXX Hu0mjfSMp}6 literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/images/previous.png b/htdocs/opensurvey/public/images/previous.png new file mode 100755 index 0000000000000000000000000000000000000000..b4b79aeec517f11788920581a3b6044a2bf80930 GIT binary patch literal 1388 zcmV-y1(W)TP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2igW1 z5he=b&)XpY00itwL_t(Y$BmX-Y+cn6hQC>BU(Px9v13dclL})chM1CCsZ!wtkRy5# z;SGs^#6^GvFQ`(BklLzhMOC#D<*luFXw^3eeJSeYp%;}_1kx%fC@3*V3BiCN5Rww7 ziDMt1z4ux(eb}~%5*ygkXiFol|6eon&&(1&{Tm1F!l#oAZoFRFR}3P8&CSj-d-52u zdKvgVaAYk2S;PNTT=J9~yZKf>{&ivVHfZ-@jV5@9bUHA19;Ocyr~YMn{68-d!}o!M zpGDw+pSa;|KS(DZ@_y)Q^8Q}3Mn>WUXNIYwQK>?tDk_Tk4*K5@srEk;^~B+y15W_D z4CpTc_rSC1_C4Qf?0V3(H;vH0VSqeK@B+>ZRFSBND&CCDK_g4>c@GSYJ4h$>)UhqV zp8&g*;1}ukyC3Pko5K-d4^R1D=RP~Y34|4 zhNaNU(XJh5vtw+ydCL^ytCfvJx!K#brVuGK*1=Ft#Hzc37GYe(YS>qnCQ zHl|vGS&Sl3K>{N_#EzilIlb1Q@`?=EOjv||-;;t&yht3m8^ku1fvt{6#t zZ@aNvLn^i@}R3X*`8UnE_v9jci6KDDR z)CtUNbp};2GtBDfEh<`tPa3o;x-OjkXvSi!BUmC??$G^5Kjfij4sg%Y|K#|||E(4Q zx>#Ukea51q-LeLckvM;5#_7WOSE^I*)lLknDhL5*MrL&`_syK;)+hhM5BL6?a|_*z zBOr9TXjP(Rg@u527Hj|cQ&=&7zyrZGdhg3ezFhZNr(4Tz=|Bvz_KR@ngLCYC;dOch z#)b#k`_eI{-aAuYE-2!JaDE;Ok>dD1!pCp_NB}R*_8UXr{_U8gO~Qo*v|B(~L5x_E zAZfbl=CBZv&LY-oBHm*f(YXb*SYYn2KRs$?XR8N{P`;}R=kCo%Zxrzk?G~5s88d78deoqA``wfZK~4V#f9!HTl3$C9Q$)ndfT z5~5N}@25ES!mog*FWm?KDBgZ;i=@r1>Ch;$JSwVCH{fc(W{4WgDlFc7k;Nl_{2lP< zY757JKa?{^((v)jP3eYF=Ni4ZEQO>_l>mq!B8a$plB*KuXXzY#E)>)Ie+GQ#;+479 z(x1R5PvxUKCmYx9kYxR45Wmu)b=Mb!)6*0)uUh&3p%>BkJ>byieN`-fUjg>ul1bmU uev9P2gBWP{!mQ4pIf{nmXUo)D0RIP6e(WFKzN>Wr00007u0}Ark%-ooabuhQJ(6X(Mb?y4Px9#=sEtCO8Px2={|2_Zr{pWw3GW_>? zndEI=iQ?>hR+O17WinDY+L*J=ESbUrF4Oin$<5~hu;=JUDtK%!cwJL6vQ))}6$5>< zMdYLl;5Z4b9V%E`m8iY~{CQfG?p_N19t~qH*;W1@fr4a9=FpUNBNrOEfrSwa&hw*3 zdKf$}Asl58!U}{){2>M09uBQ`6Pgs$s3HD@^=B$`JpT~z&Tfr-( z1ZYrHAV3}qB9jS4x=AQPdYOnNZd7MVL0!2Yj`G&MgtwwQ!Bq8-^fS}f>)DFg)obXn?7IpjWQt+m`l#ZNZa%eQ%tyebZ74H1Fg@VWA z!#1Z19v}ZWIZO$IvXA`RD_Rki#KgBwBDm+#$OHj$rs}!|ma;|@f{~YE1f|L`S*H&k z_o7cvK?ZMb)4&(tWaBh-KfIRp83v@5LZ#5fJ&*d(=sAO{?c3lEHOo2=-NaaQ=soV+7Yar)#Tige+Gc>$WbF3EeF zM~y~Diky>%>r~FW8V@mO`TDX7UEz!U{P2?3bygiD2}oDxVacH1pymt|=X<#PU@Mxt zuE;?B^b=6rYXgj`TuQbV`x+*qBV?xHp}w#f;STWV=-|=tNyBZX?yC(PzZKC$C5C2) z2CbcO?`P-j#ONOL=;}7?tDl07u>A?|)A^oQQgi{Ss@|w{e2-tut7W~#r9nfRPOd!D z`W8RSAEA`K{xx1THC6+Bp?K^!5352N8JC+s$Hlh&NkjBT_F~M;+X6Q^vAJeMya0j} z|0bgxChPVlu%dAaY0F8KthjDA$|Wi{#i#~ocs+L4y#tfyYEptBX_K(5=qU9?2+Jz^ z%epZ2$7NGmya9I;LBVk5+k94=5>s3?rzHqR873h|(;sK;2dO1v#mg`udoDbp6E&`j z@|m}Cmt#);8rc12tgf2ykbvRpLjq^nogg!0pl(-mBBA3+LnYoKFzhDD7 zAYk5=A;{A9#n#~`pjW2hOv?crZrLiI^HYfaYBb0l?%w#fDdz6MjTiI_GxB-dcIt88 zt9b@|MCN$P$pLVTL!+w}*IXB<2o@1|tYRGa=vpZ{B$s@)-K9j6jhfCTAh4tEaExHu zl%?u3la{Bz6;R?vTly2=y;Az(yRj#zi;d3^JACa}cWp85L`(_Y-DWLK01m-(HbgEy zkQ+3g;mvC5{A)$1fQM7!LPLgr_8Y{uaq6^M!?bT*ytt3cME2vB34!R z16s5QI{2gUsmjynE-}1{>w#)?rTCyAV%8Ob*af*P!qu%`$*~hMy^vUeL#we87 zo;BW3oH5SGR0TSSRHEIVOCbOR8+`~>xuj@~>k@_WQ?jdi8t8chkJfOKxr}GU%ATr0 u3O%10rI8u&hMf_IP*0$b{VuLsaGp!i8j~LTuxn9>yH$%%~H#?nA54VmAPuu zvc=X1Gjx?`x;YK!T7C>f6g2z@5D~o~ANTY9>O9X22r9{8&waS(eV_9?=XcI|&Sm(2 z8Bc2wWUC*EsZTP`&_pl>qazSNps5y`QclnJ(K7m{V0`KjEcY_&36$j-)pE1XXnvdhnb+p>Z1Af^ zHarMXJG!8>+$8`_fP}7IL)VebwNS#@9AKVx-0Xu%E7n7HIZV%GnJAJ6WxPkUP#CeB z%>sba*M6)R%C!^oIKbY7CEHfSPnl*K7sNeWy=h(tZgoY8a-*L<)nmtr0i2rroe2vWlp#9JeFnh)XBkA4G z%?=Gm1VtxS`jJH-gO$>%nkFxyC9Fsa~67jGCX7!oO1J3Rwy z<~$AQfn+zf29c8Br0YoP4^Y{Fg3=1}3jxF$ZwsJ~!`mZFa>rjx-MH^5j;PVSVm6G1 zyc7?%FP@BXBkt3&yZj1%`RgC-ApQ8!!|wxB)MHi2Su+AfrJe{--D+stzoC}9_-#_* zo;NMS(x6i<^9tw@OH9E^e-_?bkPC;+g0D|pM$zw;kVyYl-e|0Ubu!#e8%j=JM`4M1 zk?NrcG-^Ec-Ys+-+WZ{{$oI^Az0CXkQh~0vclHaPN0e@tuwwccln@oQZIN!hffU)m z+y1dAyL1Z`cY@tj)Cq$e2wyme$fcvA(PZZIR41?A<6~AQ)XrePDDJnaE@r_)!h45F z;#T8^dHw6rAbG#3#)yTod$O4C%9(vIK7SSC{PS8i6m8H|)E$zjLU9+J`N@dg_&cAp zfAlSrFT5|lQ{b8~M>L#9RO#f=;EWr+S9hfDB*GP?J4w5SKYC!`upd0LmM?ZqoZH(M zJZa+aqlC(s|Md)@=;h-GSN-}UJz0)N3>+?;+;wp?mdTQPsNh&v6yjGErDu@0 z<{|!R2uifB0QXu|nyR;uvIql=%)XKb*|N=^HP!DJGlf}(XY!F|CbWBW8VU`Y+jWTE zIAg@>&mE^h{Q;dj_fU|JVRs^}h4c%G80000Px#32;bRa{vGf6951U69E94oEQKA00(qQO+^RW1{Mr88W>i22LJ#79cffpbVF}# zZDnqB0000007G(RVRU6=Aa`kWXdp*PO;BVmWd{HNAOJ~3K~#9!?7erGBv*Ad{+?S^ z-P4n2lXkUQ#YGXJfU-aVB|xB0V3GlY5IG1;_%JytUsHS!eD>p?f7{QqJ3T!;J>6Ax&Uw#!-g6FN`)&Je z`)&Je0k_Y6?sMpNyM1|{x3ty+!$U)TwEeJbziq$$&%d2>&N+?J@cXsagUmbx=3xNC z42%FgN}v${V;~wKV3ZUM6VWgc4H2m!rBuICs*i|TNs_2$vpJq_KeXF#+i(AUZ|9zS zZr1H~`?S{mTpB)uhnRT;zzBd*0HXvN1)*>PL?c8rtcZq4sX?V^fQb4VjYdNyNt!5y zBu$Z~DY7&}nq|n+6j`HzEX&YnG?6tjG#kz0u|@-pEJLH&EPkFfkfs@Ky7AhX?G9x7 zZTsy%$MBOp&-?N`H-io6R&y5+q4s_-U3R%NjP~H%jBrJfk;{H_&J{3{qfKIuNB4lTxHeK`8=} z0;$5VO9LkWD8F!Vmr54^&l!|YEAIfz=BNIRiwD{KP#1rOw>yySxBn5hkl>0udSfeH)HjaQ6&S0{*#~L88 zCN5kH17Oxnq==cBh=`flyd7p{Fqjk+Kw#r}7{GQ1vi|Rl^L#)Ti7T zn8Bj}8K^%7!YJSjpGb|AP=8P<)ly2evdkEM5$)5Yi1?|A_L+nB#^{@d)GJB9EX_Dc zQ?`bmB%Fx+UMVU=yo>Y}*^{w&AL>U8pXwsKvB|(GP+{!S+KWhU5QVv4K?}x@Fqfg< zA_DJyutO%oX;ESF%;pyv{@-!G&E$TQgU4ct%ytLz|MNWm+;fv|p0{+K_iNUJta*sR zBSoIiV=%0KQPLYDNA4Bueqs3ih2dwJQpzLtoY7~F$ZKTP9KZZonx@FIj0>(HDImTg zKgXvs$0v*PO>m?h5uaqVFLQjV%k6`R&df~AY@#?ZgN?xxQ33LcpR@HK1>6VO2c21# z@0G~eo=0Vnah?z%B9Uq`kfX9f)M*cF|4-?UdQZ%GU^@FI{Y&M$?>ZfHXFB62G zWAvNNzKY=&TtJF6&9q?jp_BqCg+!?$WRoTLN)#=jerWSWYTYB!S7RcBjsGYDJrhc! zE26HkdopN%rAf=&zA$L#n2I|he*j5`qRf+6IuVHsO16Ncv*N&lxt_7$%FoNcNW@?b zDp5%RdrI#}#1^eEK#H_OI|U#CYtPXZr4|+_4DO(oCxb;!CC|)u2l8J_@L3U0!R&J( z+yO=f+#e&*Xc_fKNU32(G)Sr}=`|Y7zS8LZh@V-*ZZ?_)%r^vIvx!F5C}4ipK%9pUCY!NMhck7pnc=D}GaQ0_=UzvZz7Un-DRxEa=@whgH-Wt%v7Fu<`Ok2@mIGykooicMq&8*fYy45 z86#jGDe`=b75`|A2nOn#Jl~e|wAQUG%bICbn0k-ZZyK22Z2Is&YanYh zI89S7QwAndq?9712&7bD^aLnU3_yueT_xHh#QuS8_KNsHI_$x37pN+EJ|YmEwPrFP z!rCrejxVr38%S>;c97pMFtc#bPLvYxl_ za;)&F`LlE6nE2K&-QPR8WUWAS;FA^}3! zLNSS~Y(^6hssHU9$hqg9n{>NfYxpIzKLTKs!DD4PZ>$vYEJjhsA0btg^bE6~BuQVh z*|c?hWB3-vH=Af=8Jf+$BJ!JZUg-b~ACP95F4cNe*6`s}1; zZ^d%_YLXy<2ifPCgH(cVwn7LO`Nd}@anKDKFeyOK+}`H@u&*MG*BF=w?LDLO4O;g$ zbdysQf6h4C0HHB6QJLbQL=dHSb(a`33Jr(2|r;)MM;l}x;Mz8_^5Ele6J!fe_n`hf)ATQoNp`4hL9_wmk06LMm!1w zlPb9Yn_H8#RRNm|s1K_Fu>3q%Au|WYAItT9`0Vll?|4P?d{djyRL$|3h?K}0$Z;En zuvlPz&v3rNkhPwn%QQ>clgRB+;}9H&%0(I@f^qp?*pRfv-!lo1`=|jrD;x&9<2PSA zLLmneAOUyzaI`{Wey{4wSwuAd861|7%!4X$Am^NOc3-#KEev1l66*7)jrPEzlH6Ma zqA^8OcIv5NrD#y8q@RfT`uh4PO|wF^XTD}W%x^RcR==p>8)wic9YxAXlFD*ksoX1| zKAcn+lFbibzA5cd;1fb-pM!{R$Y;aLkzb1kv1XIQ)|K6C$*V{Ys8TpDpfnS-wPdfZ zFMu_(IQfJcrBV24;y@PzczQt-Ub@e8yZ z+!s!jYyK+Nr$tmA5-%K8k{_=EBpGU?7hQCbo}Hbc{{8_N<8NezK{rJ{?-Y9tH2eCT zxTk>mTyO+Q!R)JqJjI?88vRlpYu)L!jtmT*V zWMMT#kQhdmL@K$yFb}R#A8-%&Ztl;Q;|HlW#HTk^)sjTj=3VyA?;+4Z7>y+<6x3~~ zhDoBBrh-h0L)M@xeq4ZlKLOyV>!=5~RQVZ2^dMACUc7TGbu2_wRDfWs!V)!tf(lOT zU8mF2Q~1+AJA?cC2MQxsM2S)iA}Ax*6~tW}=122;VPsCgV}qTaep+L;Uo{7?HDL7t zKx-o$AdwRjYo;P=q~b#6@}g1{k_|SE2+DMU9H3gFli4~0AYIlHtZTD`mn6?hpJr0* zSY2P_{2mZ8XaU4QIc_2OKKvAk5GmV{L_UJt;~sfFGb_Q|RbaX~-S)!mmE*&d7CD+5 z)Nb~V~FWCgkUkzFPRm+F!$_XMd08_Yz$ zhAi^>WY2Gz>5}2jm@L{gXuGVGsUqFMT(nl$=0LR>x#eu(hY+6Ik+>LvBc$N}=RHh;`YR zQ~c9Jq_mOQYJinRd{!s$_+7cat@*EL-g=6&c4MV3>PR?Uo9%3p!pM~p^i!2s3K3PJd40a_!}K^Jug~%Q>JC>Uc!&#_Vl@X?)<&dh;Xy8ET>t>I z1%(U`T*~T<Qr7oh9nenz#`r&Wj$2grBgXU^Of!b2=B7{@^kv~U=SHe zZjt{>@vSGvg)hY=+2$y6d;*24!3qOk2i;=^FA;*dPktf+;oL~G;WLRn#evBAO=dtK z_R&E_@gvIrK7kg zh7w(;=rxSD58)Ao@L|c$OA|_qiskI)rUg51a`2dAunN6EFGF=Dx(NDmjYnmtTdeX6s@KeMlJ42pg1nPv^bF$jfiEyic-!*djM1?GAW_^OB_W~pna$??fo zz*MVVIs(rPDk}}1nMoBSw-b@r%bks!G$3?EN+|2k<+0IPs}N0=;g94g4AHmj`(r`Q za^#HE6VDWN<9_aOO zTXf=)x$~9cq>3!4z632KroTfAs9qj70qyJae5$4sJz=_EttlOe4!T>YN@g;HO7&<2 zo|g!j>gHFcCMXn|xJSi)@GIe;Vn-=nG zrcmg?Ui}Z1Qk{c6q!(aR$+`pU1E@HYQZ`Fj~NLmZSEn zd4B1?g?3|Jh%Os`S#+XOEWhWTx{?5z$1R+MgZ8VeVLu;4yMWRV>R(wQG1sCZA9+zY zOanC~T=J6XfQ*jG&bhX5YydZcrbmzSBZ!G)EL6-v`ok5Oi5;p;1$rp!t43FEP=aZ; zVGy9_h4D0xBdAx_q1O1TtbI%(Kwi#Aky4!_Z>nWFk_?e-&Wx4l1X&uE=RoKgA$`&{ zD9g=Pk_+IrmW^#>D4}>M&JyeFJG3f4!EWd#OMWGsj#Gu{VV)nYQO*O=%feh#48^`3 zaag2+2haThK*l!`QE}ibS8t{Xu!UL@#`_XaDI|$?0E;}O#=#*}-&9Cc@~U(!85&u+ zlLU$)FXJUAGb4#fVzo5G?-?h;(l#g%z6DV@4Fx$>1)hxE3xV-<3cHvSAP+*t(j5*< zc2q5emfd0=e2=N#hEuZ5arGrCn`QBJ&{3;L0LqGuBRCbP5>6~I#nWBb8$%6UUbE36~cDrkRK4xvr-U; zUzQ^~tj`lt#i;#gkmGn+o!~nZs^jyx(!j$6iuS_H3)4xt=pMT%ffB7JrfRg7$0M5G z`&fkqIqK_^s=i5b5G<>AUnT_hm!~y z!0+;Sf^ekHIIZ;Drc1;`RF6a!3e)2`eyPM{&qPH-qVsrSppZ3=QY6Kw(V|=9j+8xP z&^#cQ?KR3&arnX2U^V9~_&vC4r0i*C6IfVO55=`u8OmJyS9?6(>-)$jDRGxzQ9)kg zXi*9W!?#i>Q6y#9)@u(Hc%Fa+VMmec#TYk%c)l{G5r&yJ$Pk^F%%al5&{`|!49xRg z8BUUuvB3w%M#%dNE_HL?Q#kgqYOLhf)xEiJ4Ak^Z2QQ*5#xZQXF>Y5*bB=()AVr#r zra*Cg?LeCnhUyAZ1XY!x#PK(1aFn0NSEdb{^FmxS^pP)$v>Mhj;tRso&+&=Hd?3Us zcBZq|PR_C?Ic&c-?}Iq3E=awFgyzhFkgOn>iAa+_c~Od$jHKU3hyW{)e|=TR_TJyu zMSOyvve{-yW3x_cV@`o5z_jSz{GMNFVo!+G>$;EJQUqK9vnEAKvk>f&VC#LMjOgmK zFkVFdn$n#w(y4*)hEHKsl#|i2GfMznz4l|Am*1S@m+8EzJ3-1tl{`MEpqMD%OFSj7 z#|1%l@=I)n`60eH5UFaHL3$^~3Zh3DH&XtnGjLiU zXSGmK8HoKxOy_K^Xl8l&(qAI&Oh24A*o@xy|(l-_VxtFsG%*d`o zl*=Y;Q(BBccfs6)Vyr{mjtwfPT5rlt2-^t=HQIHMT{7xs61W{G#32pnYhpN3@s?6D z9f9iP7rX5&45J|r+_9&1?FG|iH?Ewlq(qg$9WaHuPNHpr=ds-lA+KYOy@lpNyF_Np z1W5-ht_@WNSth~91pNk$#)Nz<#7ipmqhffUU?;!tCe zek!xIfXStXu<+iWZ01mv89L;Vv(y`=FGNx&dupjlm`F70_ea6+H1;$`a?GPS^F-Vu zm~WF5a3R0Lvb)kdaV!wCKk}j8vqW5txB5EB*^T3Kdux=*F-zvwT%U@#n9>Kh^%nMm zRuxgSZG7>1VK{V=7CZWR7%Img4&zx@6?T@ap~@8d2!sdXdUy^r1{5d`wS~7F3TAvB zCJNmd+Mh~6t$`<%iXA2 z81E_DqXpa#NwpYEubbfJL}wgwHXPQo{}6aSUvoiNZDiZ3$B@llEE+w@I@q9^W>ptL z+Q3XvKgph2$`~)(E_eBXwZq6n%F52|5FCW!7!l41UNKR6XDx;*lLC8%3Dcq|5WIQM zqb!xGLvelq6n3C~=h#C9j}W4H%I&Zb`KTw3#HqteD4i?y#*(D?!~8dsD8; z)c_8@Q$TB2a4CieD-ts}{CUG9AsN{dR-GKlqGOm9kv8SH5}oM4B^S>z2ZO!gDy~$r z0Mad-6-G7Wn@@PNGiWa$I8u(K(c3&-vZ}Uj$iiW9Z{zGmrpE^K)gfMX1=^r=Wgid5 zJ~CAwa~A`=PFit(Nq%2W&(}m$w$u}`E^J4UGP7-p@1Yzs#A3CUowzTqxiZoRC0t96 zN&?jIlgxF~Y=Uz{UchH5I|#I21xnNG5Be_8Es@f;qF22R!d@5-MK)Av2x2DbNF|IX ztDG$eZ9fNe>bm(Lyc-a1Mf4Oc0(u;{1M7C8w(R!9>|t0CL}#C1 zt;Q&FT$>&KtlTLhcg{2`F~G^3U=WlEpKf&{3>u2iDD1B35`|C^!!*j_OQj%C6IXGQ zCx?eeu)EZ}7l|5bJ~&2W+htMptss%ro)xW((W8}Jl*Hse9-Rlmf?Tmt+cEHB^e%+} z+@S#pme$Gv;;Zq!ge6)Vi=FCI2sbwrT`@0h7&(V)X3gks_5dWQ2QiO z3i+6fVU{B$uNh13@j-31hhw3PYud|9TH`m&sz zNgsQgP^)lVmD9pK)v6c`v(c~uY}T=^?h)cs>IlKK21+5;kO&oJ4Fm7=1z}jD+UsXw z5T3>GSY`pos9J?_{VB5dg}lyITZE64(zX@4_hi@ucAaHKCxq?MWo}|KboAiaB@Avk z3@JDRcj`b1*GpqJJ1P`xBxW-6o4xXoe6JF!YfTJ-QVx1MrSC#uI-?ws8A}W5Av#wj z{2bK!f`MGI^F~$CT};X@gQ_Dyo#u(0w#h)TGM!~0SaKaBe+AmClr`&zMZ0Na@B#@( z+Z#-2(6GBA4JW50k4uRId4wP$+(M7ye5;~0!5+-Cj-ZqFP#KBhuZO6>ct-v1lv)U1 znGjw-l6N7SHNbJE-D+)nLU*TtlJ#-Ju$RceIRhKKQE0A3* zIIvr4N_Q^ctc2@YvjVi7f=|$;Es;Y~0;+Q;4m1i<^0Ea>9xn){M^-E@45B;2+*YM5 z0tuw-z&!9=2@xK1Ei|{(QUyYBw0&NPQ;7`~T`^7aL=Sc+kU&6YM4~qX$0mZ|I}vk& zW#UvBu}pq%I8iX2ip4Jw+uDyeSV#&w$!rsdPb3pf6K=e_Qq0kDv{nj9^TGI9h(3=n zM!FLzh;jWl!8=jx!*_QP$vQX*hFmF9Ma86;`KnD6FAkov(A_vwWeVb2?5|N?x?^Gx zfxI3EhoqDlk7!8QddM!$2!}Z{1&w+kTo*G(goEbl-rG1-cdIQm%b+Pn?=KvtqenoA zT^S^*QsI%Q@~%}Sb^zZ=Ec~7qnzNNwcq&RMq>*i~zFpc4qLrmnj;n-gE@Ut%gw2MP zbBu6ew|(4JoGGY!iy>9YEF2->f0)GR(4rAlGeJ?c#$#v7_^OF$6=oqY-qpFehe!rO zAQNNWV-Q|^9JyGDD;x!kkt@Sj00aZ+?eJv;gAIaVQ>DPnyftmpSTg%(&Hj}N!%idz zML>#DEIlzF0$T`VkAyyN4oUS2l>)GUNf!!J_RGh_!8jv1=21?_qsVfp`Cz)goWif= zl<8GK><19t>&$W!?RutAf)W4#AOJ~3K~%wWUysCcc#dt1i$QbtrmPvwFvCx>h-IJ< zJCSX$kh_!uH|S|z$aE^}`6iMvsypd8IB3LvFGD$_Rm+CM5=Qvk8QE1Oa;%u-;`|wn zs4e5VDjY*94w)oFLBjD6pO61gz!=YX-^=Lt7)3}EyXb8 zYTRzkL1j-3h@eFoi~SxO7oFu)h#12z4W9j0&lqt?ao8S2W)?iD(C?XUW7~-uo3Je9 zTU5iO2Q0b|)j0yyWs5#RDpt1zrkjh@=zR;+;zzQIv`s*ClZ}(;#s!JtIrGAE#UO7n zFxx4=Gy22(BSy=OjlO zI(e+T&lTp~j_!sxxE*j~)8W<`S`sxfKF{WGkelnO?a1+wMGmS7uFR7hZ#u%vWMuE)oR>twV(G(S`qc?&a?A~6`HX}jRnFHrKuoY z?P4iA($G>Nf`Knhz88twi`a@mcvzSQ1k=Yzh`ZeAff#%*gjUSKRCX=OZt+5@V4cMj z_v-X=jyEcmgeq}`UKeVgqUp-c7!9U8c{66&+f?fqb*gU#Wt)#12TZJsuGN4j_O=oR zP#v{Uz3eYyC(k1eTFj{qro)H#)ha^}uZ6mVD#O6oMlBDXn>4_cli3Y9AiGu1ccnyL zK}=O5`24j*?WwX#<26LBz3&X$pn5T?LJkLKt+l;wI}>2@{keNpr!H*_=9JHiamKfCc>Ca zfF--Ms#3}(0#r!?6O;q&4#GP^gyfDME|Ls87e>rnVU~pr@^%P?mH7asTk)O0{SS7y zvzQ@LYKh1x(wx~7Dl4pNs8f;WOa6cv%td8NbH&g-0~7{soo{K__VKZ?F^o@4pxthh zG~kGlQ)TzF`#A@XvEZRRTdAVaNE|8C^;WAj-%$8kgzRxR0XrR^NX9bwi6MTPRmi}* z1~ebWvMpE8y!Gu~5S~op>koAlQ+~KQO1B2SSDAKyo2AXqSngpXvGZufURQ)jJ*<>NgC!tqPjs% z5yQ8JIy^j#$;nB~&d#zZvs1*#ZEmI5VP77VI3PCg_-DYAi)nR}+s9L)C+ zZF%1BhJo3V-pUt}RY-ph#NuI7zt68U`~YnZ116O~?k> zjRPTB#%>~4xk+4-y%1BzU9pUU?RaJ6wfVX(ayJTw{}U;m}=1Kr|p&|!EPTV9Q zIdI469x9OC;%(FNTU4Lm5`W<&$)qqY9a{(>4=)h*rW2b;%_V6aMCnSz7BHQHpINW2 zwU(3RJlLJ4Db}xF52X|q5Va|c;$FLiA*{sS*vj0|3TaBUHW)KXW7P8fde1L$V49`S zosKtcK4~=3P#QBcZGtK-!K`)?!BYzkD{J;+U@*hvhRx`d4!P7^)-N37xI{5HzP8Hg zSK_L+$^ing!?(oZN5AUAa%YnmI^z~Po2rbJiyLB#5fW#rjOGY-!?@vz6t=)2J`Y5$ zQ6RCPM>!1#lp@x;P-3!N+05QxT9Txig<_gLk&fx}VQ6 zlGMTRc+`+kxz_NKECA$60E?ep4%N_|qLVATn^qdF6 zRS3`0M{+otzkH^4OXP<2N>P7*KW1iTuw}~@BuV18Gx$Us)u>9t z2i%S(F@ZY<&BJJ(BuVK&67==A&`^x2sTp)NV`ywChWZkWZ{C2(xf}|1|8b>apmh$` z2@NkDAjc_e4W;7q zHB)K=ox5?`fp5cYPi=tO_eJ=@x4wWqv)gg}POrqD-+ez`y&%pB!TaNK9)6rubb0l?+gT1!f;I({Sz*nLwQr;|6JG+yE zrCx5+sA2pV%u4L7gCqYrGU2>bMOqyYn`;Mh>NpY^Q57pkG8cL{^or`Sx z7C&?TCgL!tR*k=L<3>=is5u5Hed)T#^Rk4Ra+D$a8{&i#NFKXLjQ z&9URs#nfzMxc8=?;DI&MwCjOKVb7%va5jQvV=YWiY{mMGTQRs~DTbTC#*GsgUAhxm z+0*!k4}A`u!%xBsp1m7}maM?yfecey*JHz`X>iuW(BL52oi@6rukh)!4o22&p~VTN*4>E@z4mO39X^I1Ty`g3@vhI} zQy+Lf9=!TraKWcPftxlCVy^>^L-rT%!B}$&kBvWpwQC;2k1o0hzqoH2haI{M4?b`o zCJtI5213>&4aup*90`Rj6t?U_a@H#WD9d0{TFs6*FK2KP5mTZVsRB~Plq#k)VagIh zmJpf=p^*}r8PG@xeJP=t5}FyIukN4sJcVXfyhbA}UNcLGvP2d7gu{MxN);T06L` zlxNWLUz(;!)6{*RBuEkkl_XF}LP?UKAmHV!EnSk`%)m(=0=lDCC+kFg$|AOBT~mDGPhDSY|Q zUxhcm=}i3l{Zkkn8N!x_Z@}Mv^%7it%l%lq;|_S>+N*Hs_pd=WY2&+JIU7H^`2oyK z&Y?Zq#n`HyaNXa%7l$8uBtH11TQIiEQqY4x!=cYU5YIdD#rV<{zs1nvMaUX`80_of z)}LL0PrvUk@SzXA2k(0KIk@@WwMhG#5gi{RX%1lHU033Vw`KU)hu?`;obe8P_QS8k zyU#ck*-Qt`bUiNk;(uV@eG+`@g3sXoEsTe+|9AZC*AF9YbaC5V*WjmjrFiLqDSq&s zZ{p#{*We#N{}J4hAB4Yn`^(UL_!l_;;_qRS=kVy-hp=Judfa{E4gAnkYxt?BxANfV zG9GGLx=Q}jmX|0xmUYldUQD5<%5Z!ZJy$`WK}?BCvV;gZt`Lb*$dcNb)Fh&Lb%<7_ z$)_%w_uN7i+sIdmzA|dZ^4?(n!h9n%wyE^BEiWNNdxbEU5{xZcjIrSX5D0p10*^nr zmRgIJfM&)qKHV{#imZ>9h%twTLZi_@0!=e>b6_MG7#@aVLL+VC_8V@*Omi9bedg|1 zGBk)rLt*`zCo$Ctwk?e-~bM&iBw7ISl`L>kn{1Hj7yT@@|gKTpPJ& zG@1#Xdgwkpy=feMqdQ`cT?cXPKYba$S=q(#?496|{c!wILwNG;2QahyK{#<_3ZH+^ zTXEg}8*%LG--|b#yc(0^v(@R241jWsjqQvjn~p}8XpHWNfz7|i72m%DYks#2ethdA_~=O|;n4?wgYH4k$75Ih9X@oy zcd+89WAKg7{wdODUV~Sxe+c{Te-xH2T8~RFya2}>c`oj{>MEp*j>M{+*Wjl&+>7I1 zbSUN?y%E3o#mzYC;60GoMJi5sk~I3T?(Q3*_dFIS@4FlmGmMj7|2{l#cvtZFjhM}I zyyk=F<3k7Ej%yD36mQf_jU+__io1E6h6b16!{5FXM{W2j|N52R#@daKMLJ{b-%m^Xiwv|8*jiNhwh7g`ax6OsNTjy zd;z&iL3$%3?^M}?EbA#sc2k*vZAbl!4wxQfK1ZT12N4*dN1TVa;hKoQAcGDcbNNvZ zk0skjt6YQ%d5GX=hLBX^_X)03j_fX*u&z%E2~Xq7Oa2NkI`KptarhxP@vUD#YsF&x z;PdCfcnE1Zn6W)OgUu6DP)Q0!Ii7gn z0X*=)-T2itH{zyiug5(PZp7TC2k_OedK{Oc5LOKzKKsGH#`K87rRSfA@BQjtq;n7B<8ON#-un0z;RI7s@fBEycwfSZOdbAq{?fVU@MV{Olh4?HjCVQlwRq{l#Q*rM ztF=lJp3|E9noXT$q-STR`S6ooz!(4XH~F*|9)X$mG|vHAxm1zuLV2yx99@ch%k8*x zeU6n&25{{aU&CKs{3B}jWu$qKo_)w_8XX;@rb>$yGD?vuIy5O&!x-+H#HLNNl&J<~ zeJvW(b9Dc;zf_ynJU}XFx;G7EQ<#{ZrEF*!9q_yt(DROc4h^TX^y{mxruCha zlDLh?(UUgKHM2-00x^%-&sOws+mVK5%%ZVV6*k^6i#eJ8bo5?E&G=8eMF>TT7&I}n zsv!-%a-#TGAus2vg#5vwuV*kjz7c=- zskh+h6JCg8Pd**j-gpCEa?+7F?!;5@qSIc2pFEsn?xA1eb*CMTm%Zatcwl{wq1FUG z`})`6{U7}>&i~54U_vvxD#s%?{{ol)@Q3)(r5EDdFZ~SZXe+W{3SekZ)(BRrL~@z8H>#)FUD&o|$EHxDh{jYs>S%|JYHVV5&{nI~sb zKKMC@^Aiu<%s;vACO-JcW4P7b%7mQn{oUOf`BuK>*EjP-C+D%|CT{F-Fh6sbl~^;k z5&N#*9iyrriOSHI5>0L0jLDfD=z#s7O)K?7bnR{T(%*gLP53`+_NEWN`4~0RZc~~P z6}g{Qj288!4VszWK;si#WGW%JAfaqv08~CVO*=gMWIB+4LtpsnCG?$3zD}R{_?K|? z@7JL(&9M%XnCVRM)c9t8va^QUAf8zFBtQA|1as2nCnwipCTHY&f*+ZDnj1Sli{E_a z>3r>lXXwQ%pT*z0kNNE%Ig5weYoQkp^32)?__D8lf&cQNi~0IH*YOFb{s|wpGx21* z=ZZ7_<7~Bh4g2#zD4OO}CIANPIR(&%f}e$(>M2I#1O`g;iC=m#`JwZm9+PKizNs{S z;By!3d`kTdCoSxA@S!;RxzEC-=UjjXHczAfrfczV-(fgpa1i;^cj2au2jFk_7{!vE z_QBZN>v7$heX!r+&G^up&c@I|FUKBFU5Pim_wRA%PhW$_?|%Smmmh@--gpYG`Sw@& z$>wf!)Uo^Gxcwi(j~~B{fA-y9VD1Zlf@Jdy!h|^G86IyP&e#6vOLY9J-i`PE>k9nx ziSzjFCoV(3&IklFsReWtcHM7(-r@WIK$m{|L7ebsp92&@Q$LRWlMnD;ynYmS-1Y@@ zJ6$x>7G}5Pc>bC1z?uC&MVp9zbLBtas*{h#@r!es(y7yUz%)b>I@2>)dEj%f{Nl^- zjVB53`}V>3;$O~zNn!D#r8Ktlp7_WoUy2P+Zlx7_9*Qlu{0Kj}XA=(Edo^yn>fh+M zr;hPl-l27qZGOSAr-IM=2HtYkWBBcrSMVz?x(pj1x}JXa<0tunT~hEQ@W@ls7+<@F z^Q|+O8QntbW+%W5Oy-+tTu(EoluMG?CQ(G}yfcmA701yhKK?Fz?3|17nK_NoXP(F( ze8X|jb6auZ3totoNsc^Si8J4D2JevPbjYjTj#hdoE4_?9`q@ulcb>uEPRHVl=dH$y zd=>*Qc^`hV-${6Cwt-c`>}`d(6$;MSJx$OQ#9{Yijqzv=3pX9 zyalI9vDaNFFX9dNh1^Jypw*n?%P#vCZvLr)-v7mT=W)yN?N2|2DGcMxcbtWruf7Eb zzUJlJKe(E{ap_m^)&ut9m!Eq!Ena^&-S)c&vG%S@Sm_y_o%;nn)qVpfQ25|izJ^!t z@*sZwb;a3qj(pJowV-)&CdWY9Ku(M#oEg9j>Kmfjd#IMu|MnjI>aX8`4_*E> zdiBw7!xR(dHcVmj#9DNo-hzYQ`~kXfXg^FRIo|)ex8dUFpNv&$Asl>a>soA`oCSk1 zn@?eKa+dpdS%FsnFm>iO;O6UY0{Sy>4ko|ETh!k3IjrAwFS>gijOCAg9GBg<8qeK3 z!=F#jVCyX5gx7t5clp*!>CD&s5dABk#UDL?f3*MoC-m^lYP#^^GjY);F5uhmK9*M= za0t@j2Jd^qTj*Uce~5qm+uO0@p{L{c{ddNG@A?GP4NqXn>VtVz-&R^VxCpC0{&8US zeporM5+B)#k&F{w{pOEC_b*0YdkT5v+$u0OOibaJm;P^De!#0Ri7wKS9kFUaW9>u> zpZMJQNc-F9U=O_i1Mj1>+offvzaIOO0x{^cmz~bUZD4p8I_|igfqWL!H;6sZG2)4|~IA|4t6ac7ohNMY%!RR!tYX`{`hdU$?%px4i;(-lnfMBzMHZ15C&VT^2x z7|fV&_s;*j2plo&g@|5y8FK7vh<0K;iBK-i_g?LYfCx$J%@zxmG)cl&Ci|S{4cc?R zXXD^~R$>3={s}#6G0;t$7#beJllR_=_OfT=gKvH*tz0~Y+rRxf+_CF>=#Ez%hC8mj z6@80#!y8_I79F`;A8nmmjM2_CI$)aJv=*EDw?I=ygWad`$#F7g#j_%eic>k*haqIWL z#Am+$Z)nTZ9GXKX;kCz(;PNkbO6hS*149F7rVU=aY9*~&F^tE4`%B#ZyE}P~6TI|I zAI6b8ba-ZCLX`UFMt5d`fj#iy&wK{^w3cAc^UlFDr&mF39>iBJ{U_|OcOUfP!|?5& zUX8~#K|DI%xt2`c8bO+FDOsYGFq|&fDW)~_1;ATnAYS5H;dF5K$-xX z)^A0+XbfXSAl;_*lQ|Nl&^J1SyxW211g)V4@^%MkG?74~n=`V$1bMd$CPLC6&T|c& zcL9|kQ3bc41#iKui^o{DAl1?f6mcFjPg*0#M3L;XiKZ}Cvd#!bk}OQQwvZ@1U!;#2 zcxZIN-|<9F;sb^mn36&$Cs+2IfK0by3Pvwgi|L)i=LACvL)ox>NO7AsY{}`xZ+REa zdiirPvuQ0RW;S7B{d&%yd=%gN=GSrQckjV1zqtypde2$-&ilTN`zHr^`CgaPac6vh z-f`-lc<YvyGaq%JlZ z5TLaN73FItcij}D;~f!cwKuGF(WzVXQ4s)iIvpc#L$^~7E9kWC3bS@Qw^vA>+cUv= z@r@F`!0Wk@K`r15?Fikvs$=9j4SHkzDh#SCz(Nirm=s3vrf4IwLn2lxC5nzO;=mbD zq?53xqmd3G)bUG^mE>gvCqp4$Q}_CEk1GY^1m~&xR1k;|c*Uav0~!t9bHCluj|n{T z&_hrRGzL>V=asL4-ghyU%pQZco_Qb|S;~7YTSjmE@Y!g#T1c7$c*em8Vvp7y*!B3= zVm4ihLl4;(n>Wqi>sS6OMtAIBvtEQZe&jq*|6(laKN2r^^}DcY)y`PI=0RlRo2ipj z7ndv2G&$SA39orG9X38w8X2KIH$Vp*cdD82fn4X9?I_xHuYI7Ip@=Zo?qX!wP9WB# z0gNtcg0-gR(lLN@-n?-OvY{br0MIkD$fJ#4rh!*+mMZ8x2O~vVWZ^~MiPmnezbmVP znJF*NqtW~MyvqTA_! zlw#4G2)}{Bo_{x9v*<>qLaXE2M9R@YK>0bX7P=%UmFZ+FnFynIQi15X)!+Jqh<&2S znn;q;7p@=>mV-tZn#w8K0qT|h$VQ(?S`yvFD~wl3 zok+}y38%*qrvNNqj`MseT>K;E=+GEm^OpBPWhqoyN^egqoci7m5J1rRo;c#<1WF|! z)^zZG`#}{WsR~G|25`V3%ZQ0c=?=O&#m;-~Ma+zx6-JgUC4xqm`>|}vAWct<)9}~| zcOv8gl5c0oE`}gtgYiKHxmJ7S-)^qO)CH zN{|osf;4)>%-cDWV)i#vV^$dSVsyC)^ilH2~MeU zoQhfeNFb#+NgI@=DFsq{HhtvfbTrtNk;YI-`3-h%?ugt(;E(?!sS_&5N>mKff37jC zBuOwb)CX{b?Y=R&ESbP4)!lByiY~-^g#j~=GjvYi9MCz6uU+$%z+EoB?*e(J_^P`= z-Y&lCj{h}p7Y=;M0l>=RqSv}o1f`M%HqZs%laE+E1ftBM>;QpON5-QU*~oQe*gr(Y z88PfS!>u#eUaMw9hqch1&2?-x*SwGDA~}hmy4`N@xiz}&b{KudAYd`{SabyuAuOAR z8pJZFDxtA4V9WI<3uA>Y_q%8YmxiqK(nxbI zj50UINzffyUtl!=03ZNKL_t&rcNuwyz#YcQ6DeDJBQUkb8Mrm_PT>S{W8n66i}R`T z!q8b4&top`+iuccYsx5S1hY+K#qX*F7+8rA`4bV1Z`s6Ozx1DR&7Dtiu8H^GZHQj; zlIPRjd+i&){^dkj11f|&P8U**WuDh)dqwP+^PvbILJM$)v`|MGlBhssD?mtYQaIXe zfg(Bi`W3E5>Ry7sOIm9vrC7pcVJsy{XZOcI>JF-naOS?U*HQ3#!B-LySs}|Z3=R&V z*=Uq~G-0!yjNoqMg57EAL0&EplNkwL3??NqB4sYcjK+9%UJ7D{0HnyekCq)BGQ!&X zY#-w;BX5)c^NusxGFp?1=;eLwqCM-Z}xjPcM`Dor1{C@Lp?K9C~fHEW*0*S`BhnxN%)^XrbG zRz|q$mdEIem;8)hbLs|u?$O6UYfXk6j*T=_X7+3O&r4w#8n%hfrZDx|t_6Hgbw(X< z9t*7)htZ$pFceW)p%^DKpPXG7KGl?6X(2WBg(9t`OP9E*-vR&`6bd3=UIBlS| z7Dj9hIWS(G7aw7lQ-S_vz^xYmjS+w&^AnhYq(5Syb}Ai-T!zSt)G9GDDE4PIgy&hv zbws_g@QVr17zUb)2o#m%SA!_o$;gFRt{jyiwO9VYJgdBhH+dT2HXb{-(T(L1x7pbl z{PM=zap%(wJm-|>VfVddj6Rlf1s%I292AFI5(Fdh0s@({ECcfZ zv@VP|&o#7W(w?oul>mZh5`ISEvtfwcjFq4#fCVGq~lp+i>hL$M=li@iMNN z4(1j~mZW+DUcDM$``Yd0JP_Dnzh*?8<2w+!;5;(V^o|IAgUF>dvKryaiAh38 zQ=&9gXf#u(gn(oa)LO#G22r_ED7uX%p7(lj*RF44Gr&o}b2Dg}#L`qh(#L{|*tj9C zY|D$foxF8JgE>HZ9Er02L64~qsK(x_*{aV6h$RxywPDUoy@6fu_Or3SFq^2?a&2Jq z)+ub72KHI80#84^33KgY+FCQ~VsLN}`J$ci*b{foV~{1CtRgxPw-2^DDf|zO!r_2f zf9_Z*&?zTl$)P&ppPa5Gjh0IT^(JBGdG7r!^O~{Oj=Zm)Lsn`e=~2@WHUFL>xxT*C z@EkoRXNRvJ0z9GrbMxS-W{pB9$}72vV5lzK<{q$6)4JKyu_()tut}9Gzb-T7Z6Vk> z1i0Qi@VScEoPct}qPGHvD_1p(QfV(@Og4_leL|LnB=X#Yzfr3k-|y|yqbLqp0FDM# zcNv(97n;osSq2OaHZYQ=&0n}F!bbNn3cF!AsExpOa#b*9Z6TeoJ-TKGL>S^BxnZY zUTZDH+pw$Hym`{_CUpzWhmd9sR^@fp?X-!K42rwxYQ?R-K6KjC+|^atafCOiaah$+ zcJ+=eLUl3KglAnJVX4AuyA_uLm^feLf}JmbG#L>Givi5vuVd^O)%Eg#jHMK1M`ETP z`wo@SmyTVjZM3wLf2nE%TyqwgLZAbnzpsfM7Nr<$P4mduAWfy38vu_eh0U9`U~RnO@O$*Sw0(kK=sp8;ktW@e`G^wUq5vnqS?3_^0pm028t7{^BI1(bQca+KR@ z7B|iqYEnwcxvuO|v`TdL*E$rx7mK_s`Jee0NYCdOdwSJ1<`h(jIPGX}QFF4Bj$E!z#4R%jN z*R)p{y?A-ktQDkM)Z+aLQ)r^W21JS!_NW3h?64iNcf`*FiGtLt60{=c#BEt|PoPNl zGY?$bW7k#K`~FAx*4uuHm%Z^NK$l46OtW3^eYf7tPu=)^T7Jaq82-Lj1aIHlT*ra~ zkrGVSRtsYqhKQ6ZN_}QtCaP-EirSMabs$HY8jc~xt;jL_@*pHx16e{$l!EhFn(Z(p z#OUVQ)1{cysHll6xTQeVOQ=UWvQ30+nEq_5<|WoVSV2Cjfvmd@KfdB@Z0Po*zi$bi z`@A<{^F3E1+xbNFbsod-9{3%O*y#{Z&;k*gJXUwP`BPkbU#Sa=vNcqhNaL$*6vVLz zPh>hW0K4b5!l_U>r&m+uBb12G|2>{h(*q-X^;W&Q`Zk+IyA`s9BbbF8ALKuWdej|@ zWrAiea2475l(%)a#oAT0S_6FSVF%EfD}I76f9y**{D`BGCJo$u$8B`q)t6$Q&P_b| z_%7Hqx+50t`bI`Kb3&WHU4 zHez;e8q4=M3_E5Uu|6NfPAivUY@`pHpIV2xv>(eC51~6ZhqQkHGwYv1dte1tF3Rxa zqmN^z3o8+hwe^RO*HvP|IVOMXs6&5+K?H>`V_>w2TQ2!JmK=9J-hb4AxcBCZamCNR zhkXv%7c*DK&Z<180?*`q3smsu+2c5b`bU5d-) z<>8*Bl9KXEyc}h61O7wK_9?H=9hU8YGhTT*?tSoK+0nNhnex>8Xy6BV(c;~b42F=Gi0tCvwNbS{YZnt2C5z2qYN>|VwmyH8{0 zm*aTni%0MMc&MMf-xb!&Dj-;pbvuxtPiJaP|X@nN*fk{|Pi zt-JFLKe>Qbzvx1YB$G7L*7MDO_3*shvf}pp1TZ;t3^5~)Mp=2kCc?URr{HZs^f#&! z5y~C7Ty9BIGIb@nXwy18vf?%&yZ2ko!%d>jNGYD_k=xMdR*Lz7pe{?48kS%ys1W&k z(tAV-MQ%edYUy1HB9l@Ii^j%q$N>Xbz3a}%(iAF5@Gy6<{P?qQ+0|EK$DAlcq zuy8W<9Ypp27-6)ngLM8VT$sV#p0e=5$mH z7b2Al8~TL!EVe@h^AqRh0;f{wn$=f;h6(}6!_g}#eu}G+RAQ4$Xw0wV)TuCeXsgm zjs0P^kYx>8x@3vfIP9_KKD=VZ2k69?p24lrWwJ`=cD8nS?Q6fF z@lP$q>iv(yemjk$v-`f-z5h|Z?niehJ(h5HY6Z`5N(};ZKzNE75A!;MIDWDo@K;w} z$*W&`1{%zyIYdHk3tvc6aE!FHnFL1*6!lToh{oi68Lp48^KdKG?POJDQe9UT^-?YI zLIPcFd8AaZ#1?9CO^t>)a-7Anc2rkW|A{%x?;s-=WQ*;*4}ikIU87sSDo=DeDIu$`E94|it&kA zqO7Sp>mR_?Ke>}v?7a-#sbVh0belo>49#_0G`MUKM;v${?Xc?#%5>K)YjG3O<*ruJ zTC3Ou_3-C)j>0@Ib`0uDqEX&M{EUdunc9q@gWiNcJuJiDeD3X7zv%gR`3sIgYh)J; zXEVrle;J;)QyUMioknW=SsbxW#Gr+A9MzL}H9w04)p-lX0lQh56Gfn~Aj1StiY6RB zygGmr*m>y_l}lt5tlpan(JaHCy=79Sl2R_8XHq-+Zirp0E&F+lO#7lUj=k;in0Mas zw#sC-UEj%-6Ho*&-#!A~I`utxv3pdJ(qfBzv9!5T1+SJ$WqDR0ji?TSy$#-uoRv}E zGg3f-5)2Ft^H6_ATQ-eDWqlYN8ph7gJBd~%ZQQ61=b@pym<>Njk4ntEm689lTY)1xa}!wh%-7*V2fqoNw=pp>j$QXX63`ut zuUm&hUi1;@na!B#bZsw#AyYkJR1lqIl=F}Rd3;U4%SXmGc=D{!h=#fJy->zLHA0_*!=0Qc6%MQSm&2O5O9Re7yKwA}a4w0{b}1t%FF)a(&tP3*~*L zV)lqajor$iNDGr8R5PK}gUTM!6qm*Rzl_4$qMe{5!+u8`0o|TPyUk#9uyX$+kaQ=} zS^ix7)kQDH#wQ-d)W9>aZ=;LZ4q*{;%uG%4@ajY96$hleWz!~}>#$U;a!ftitFK0m zJdBX25<%5*AY!tc-iU zcvjo|Z`CCxzfgtZz8sZAN`aFmNM($^rG(}Pu{E3&poF1PFeOAu#!Lx_Qeu^YRK~0l zMJfYRVXTEgriBrj?@J?PO3QBC1WXB_lHzqq72g-jQ_Iqi5{nex01*Kk=pPv?c&yL>Je z_lp5W`|Y=ck2qq5D8{&Jl$p_PcPQ5yX`;|es?i5ax zow?cU%czkhK>teck^_OpU=jI}3`{A3QXol*RK_Tc))*+82udcBCg389l8KzG5+X_n zq_~Kn1rZ@y?F}tieAFY)cK6Gce`Y2#0)W|{;KiI1xuHF7J_vUK-3Ib$Z>9+8F1Q>$ zK)MU&E=U)Xzld{`Q^1IIm&hAGkQdYDIS1!mqC?+>fBnH6o_=ba%XTm-331yPDbA%= ztC5!peEmQB*FSqA?^r;Pjg^IVl91O(6*`?c{QR10@T32@4x~~Xe&9a%UoSiv{r!Ur zQVWJxzt;;xq-=T9OeQmdg(4(rY=M+C6srjBVVK*BVtnqxwFQ>OAfhh|=vG>x)?wtO z*pe&+Q`CDb$Fk{LIT*;kh#-A*OxzUx6%5SS6q&QIsUAT#`+Y-zO;*_Z1;Y z2r5xz?<*il3c;;Xg^yGOR;mQGV#m1Klgw1~h3NlF+n2}7aaCu2=T`Odx?jIVyCvC{ zY)Q5x@0Rxk+reOiAz-rw2m_McRi z^o5yfpjqr3mpOFdF{WfkHW-kdUD)BeD58vK0a_#`X>E&Z$k7~^9bfy)`{J)R0-7&0?c)M)_}AP53Popwww8CEFZ4$pNuLNJQFX(#65 zG8hq|*__3#cRh#)UaI2NZ+r{hepVgOKxNTVTz|txeD%9O#b5mKhd>k@)`p%XQN^m2 zcFeHWDxD}{7;?Q{M-T+A5vB%BiJ?kkWshN6#;BC?g$v}$H5VDD%i-a?FUbYuh<8{l3RY8I5?jedLxxr^ILuv` zxEC1A7glxak?E#-SKzf|zlZfWna8?kfu3BD5Xp9bHW&q)+f^iWQ=|_ixCPGesTP?p z>(uWsoHf)1f|YKJF3Ux?S_~CnL5g1QRcw{UYo|HM`Byuyp$pzL-m4o|&H8BH0 zc?dJle;1$m*0(USXf>|-FQ3Q4=4RY}>jOCD%6DV%(DT@G&$lqM{B3yc+C`X{>);jE zEaLEG{1Em}F|9iF80_9XPSZ1OCL#<}JE#whP^Wb?J-6d&oO9NBZWEzO!oZYnOi{vg zN=X@4ARdi#>c;#$JvGHIy}XNpAaMCHq~WsLgCUL7tzZ-btGbI}7v)b1-p4{Ps;JSA zJxEj+lVXWX$tnzN(Jb#`=G5I2e^{qu&hR6V-J&GB*eiEOpso{GqCvUPIP(Twgskir zRpG;7_u8e4lLKz7QH)~qm7ML+DWiR7XB}cssU3pw-3o~u?qD{Us)XFh-b7eaXZ#WV z-Yt*gy?^j;ieJ7B*M06I{I=hD4|YHMEH$Z#7w`Ha4vf4BSFAsZ4oy#_Jh_}t0k{=5 zza)xgfWm+(13;ys&={)3$7)68fil_yRaO)@C}~5^Kt_K8pE zE@9H)B!v5gHx(@c4nZ7jJ)xotP{ARL9?Utt4PDx}i`11@W-FU1s1Mz4Tw85X^q-|X zsLC>SGP7S=B^E3=n0=Lj@fJrPeEURWo@}BaTo-7GZM9fseu4nE*<=D&V$l)QL z!ufp0>IZ1^GkY)?&hTS*d#ad4t3c}xz^|8oeD z`aSlSN2<#BKSOB?jy=k<Kkm%a>A{VGwHhl8=`i)0yu;o&lF{^DQZ^2=U_E3do~U-{WnsMYE*Q(Dsh zVIt9>hS_KCz}4S=1ohDYXnQ9t6esrezc`>bvW>>*yeN^^QJxA-n&?%6+KGi*oHs3cWR<{y5Snh$)9#~%3(rpEW% z^HqdwNyj*KUqDy_o4A{=UzpdDRT1a-)PP7foHnp* z{8?_@^*#N0US}%prs2@qPLpFY&Wl`=g>dYQon?lWEDW;IkxY|QvfD_8V1a{R+nBS> zKYPtk_;I!)rv_)SgPKM&Qo@MSU00M$$gqQT>4jl3tDI-LcvGIK2{VgQ6We-BsrHI6 zdUKpv=8&oL*+vkb+sZeji*S5G1u;+9qCZGqXRF66r70jpSa9Syn1ASQT>IV6;-@!V z4ZZYo9KW!FW@iK|)|`fQC!T|;r?17$o1R9aUh$xbi>XwLzE-VTg+Kk!Z(^C=jeq^Z z7jexs*I?k#He9uS2#doGCMR}c)AgU};T3a^P{;~4l~S6SRr;)P{lp-)3M(K5u~#m0 zFAU6g9xre!%Wp7gCa%^rZ`<-P^u&uaRvn-%*WZB3`b+tkjbGz$-EtD?JAOg6;}+u9 z@85}czqf{gN~l;{$>FrGM0q?Sor*T6ZodGRb>#z*`JaB0sLpQZS)s{B5s=aZE!=+= zJnY0WHcv~xrUx!%>o8}v{A>&GYV(1JwziC1fH>nRO~WO@2SV&TZwmIxQT`c&%iNDN z1L-hfC-2s2*;P^qk~ctNPtB#jN(qT|6@7X0)P)<_?(>V=LMtO{aQd0+@Y4q$!Mx#l zbn1ndp%L!I3Fn+kYGNGKBTmEl=QPnQfjWHh7jEDsmwX5p{$`hl6rUB+Dhy{XO5BaB%uGp$LtVS|(WS7|su6S4wHkM4A;Ul}Wzi`s?uw5nb|*58;jHt>SO|{qOVVe)0sp^(;cz zXmF)e#?Z(hf|#gLnVqme@LN=oatmHQ^0KQ=9P>{46yS@yktI1twkui&lY&2t-mPYp zeuQLIvNFW2VR;wE$^^R$9UiI$Mvwh~(Tz2Syz{jedVyWYisP`k*onfNx1S@PQW`?` zS8T}H2+aDcDVJat`6N$0n_R%8Q?|9HIBP~nx3J*&tMK1WeHTTVF*m)B=Q{In`bDq7 z?7=bUpoZ0_TnV%%Fg@3X(EJ8GG$f*MSHv}J=5x7JGOtHbgw@9%&maD~uk!TdB+9ix zCsAv+a;TV8$b7(|1mR@J!xV#`LD?O=g;hE6abI)^6LQLQBAjunGP0pffeDH_JTtq5 z{_t=A8Yj=Spajm>2VSwe*AiGy)hFGrZ29%BFq0;0S` zg-iM&Aq39qn#Vzr*qC{sT4hwLG}stsq28Xg_$L`KRme!jvZkDQ*sNJ`7I5eEXdTRh zg6LfB!Uxi|;!?zkYFM5Lh&pY|%*35F3PW{ecnTnlqT6dH#R&%RHrP6d*SojqNw6iXRAXe{oMtR7@kh6 zSmSkQspk?#hI>P>|3aimByNZxLFuAGN62_(;@f6nVM$oSUR5dbgmcMB$bq!`<)v7&OmeVjB3H z4H3q6Pe29K^B#P$WG}rJhm1vn(yaan2T11++=an#Ci%>6XcSW)$DVQu5&} zKa%o{CVeW&mX^2~5On=1jTtdyhX^U7FH1HGO*$W-JZX3?iOSiIMIe=k%(^j*UGT^X zJPBwonXt)zp6zk0iG)0H7GaqNJSQ2btysgxt}qGlKk+Fspfy3aX=0*f* zL8AA@+Jzh|$e`>5v#&Xc5_l)P-{8mrkQJ)ecSD*M`0g=ijKN_kgziLUm*%L0+1W_+ zqO@^fZrbd`<1I$qO`ZuTyTVeQyolscu(%Rr_$C_v+{L4ai!%PZtTZGQk35t+>AFm9 zI4)btJUof~YrLoFw6dW&>!1P0But#Ok0&bb&>c1nY|$Lhnut4fSsEE6hf-SCHS!qGvbg7{}r3QEOXA*2%efRxiCCifww zVzM9enxceDB;^4CR6t}1fPy$RD2RMmWj`bPnNV7S%U{cAx0fLdgZNew<4-$u<8N5M zOWor1_l(g`lt>kUbM%B+m}VtrK}J_OCd^ic3$e(d!-*)T<)xWZm{pcUH8Dy`|DJUh zr6R@bh_cFyq{gD8v3XkHC08mt=iy$7fz)Lr#Qdnqv?NirFUSP{*&~8pR5&}e8O60kpl>`dq5O0ta7fSWn?XC6mLnfr$IJMB&N87p|(>AL5>1Z zKpZM#K$al@gs@H=4gmG#z@iNaABai`cw&Q#IY2lz&`>gD#e5;s$b!@Wm2G&4e@|Jx zpu%L4Pwq1qheHwnx!(~rSgrFO&bs@QA`-r>2#3rfgtU+j{lFfVv_&UV`2utb_i_ZB{9bI@+`_)SQ^+7`axY84KLRP2c+^5kGv|4TKrLQeNGU?CR_1lb_P`xslz&a6BDy-k*eCEl|`5k zP}|5jCDe6yb8!qA*?OBCD9O~rsIo1;1gI?lp1&R_4cX^`8N?(9BVp{!Qo}Ow@I;5d zEa$M(mM6lgtkjXx4_Nf-Br2A14y1+ggDvdaH_J+qQ%0p6U1hpwNuH409F-|*O6PT| z*y&1uDv{PA5xxLnn9n%O&d%ccn{UN8uD=Jhh3gOm0p`XZ#M$dM;Y06zCkASD54goe z(dKg?GFXAt2qcmx_4*)IuB;asos~o_Feo@4i@uyoZITkE2^gW&f^P7 z9AY38Ww6C@K8c51MM-PTwR)Xs`*q2{OSd|M1E=sCGP|cS46*eviKJw@4JQT;}> zHIXJ~b%zkv2}hg*Ozr^hdk9o&q!E-WG|d8XZ%ufTFqZ6CLug|AzOJfW!fMW)IE;vz zK+tj$%#;-f72@7GV*Bq|jW^FQ<|`}MfxoTm%UlRWL%Q&hLZz%wtpwcY8}xnx8H@Y-1s!! z@?ZZK-gizN(;eVPn-Aez-}*6izVsFP$nXCy=PRGNs-?xM7(&v&rL_)bYYZ4nv$L}_ zHg*t7QBR|Ea|T7_OLqaum%A(+2zhc6ZrD?V{&f3Yq#$@cK|$n7Oc?Bnt7qc?$>e=o zGzYToZa_zKV@V!@JzJ2NfH|>hk}xzOzO8IY#cT`4wNO3sv&ZOIk_&PhWi z3vR}1VT0W={4aT+)}$@EOxwzmR2xhf0|F4Ds@iyY=W|fyVLD>z(L6V~AI+I2RJn>k z1!&LgqltC}3kIubYdb~ZVu*K(>I+SqqLZFbkHFiFy; zuxddQo9=xG>n?i}%6lHc!%uF(=<3U{I8bQm$fIRchyuucjg3!Y&!Gq_*003=eFxEL zwm}30VH>6DAb4~op4t8!PCI2ozKm;q4)$Xz`S=<6uCKo!<^u`C(0m6$U|vgq4uXJE z-jMWX`K^>9rD8_#X zMCV~uQ{p%h?iAfX>5JqKFneoJGb49gPj`Y)d$dtH2UdP_ib{i zjYP~q7@|^*$+<^HN~kwNR4O5A^%^PzgJ`$gT{mM&#!S8*!a@B$MA6fm)W9Oa=w1X?5FEU^^Fn{kM(O*KIQI)(+Xj`1JN8ms{o#GEl59Z#en zP!{KYFEStxW(0@x)%|#1!&jbWFVh(%7oBLmEk&Vm_boR^Y-$TRJK1;(XXV8C)-6-+ zJ+MyKn~BT@0FfKc_`N3Y$Vt3Bxv*=|<|tJkj2Q&y7@*G>_|nUo+q^kQW5X}H)(k8vH2 z5&5bp-H#!R%qM*JlmCvFN_7kklo5m_)G8r@Y6JC(LQtxp(HKTm0j0(~G%5iqwE-v< zU|_HckV2zYM~8u0rHWFuj83zOQl*YkV7t!UDmvZ%UQ`)6ti?rQ;61qpvf>SfpG%ZM zPQQ%RYi@p)1i^VWI?3N-H`3b@vXrA05q?G2gm@|WJ^to2{8pqBn5BlnN0C+u`If*%aokImY3!Q6sX({d z(;O_G&vSA6;i7c8w~Zh8hY6Zi2A*I&zfgJm4f?c%l$44F_jLLqrwkpVVe%a$y{ z>LUiRYx_M|c4UAJYpXbGZ57Lxh1kDq8}>c&6U@`&Bq~XQkH*%HmQ&BE!f;-0tRU&x zi;uKlTEA}RU?@~7!1IqjgVUo4eE*;R1^4Wk#-;E416;i7Nqqc&T!Z$J$KcIZo{k&8 z^h4~NJ&5zJd_U@2AH@k*y$V11Jx)||$o1|j-my>0%fy0v@?^7h;rx)1W@b=~5t z7#%CmYFY+}bCp-C=xc!JY@QDY>2AFA*bvqn z(Ezl;%lGPZ5xbx^s~1L|lU##A-eCNBx(wVafXrEEn{YD3grZ!?>7wn7)6b$~!}9h) zuyqwu8Ufd61MZWESGGH6!G%oUPBLE{WtjhHy-2#(~r@C+J*RyqegJec)-J>Ls)#_d$8%c zPvG{YpX76n8lt&YB&y%Cl_H;t%GGz1cb>R@9lx&>;F|ATPfucmsRJj=7~ z-PrlUBfN9!TXex&KI{rhWp%VnOW6R)INRU|3{6Bzixzz%do$>1MD9ach3W$My7M>E z3{+}04Am7E`ND6)IsGv;6eK2XNY_UWW@-OyR*FZK4y-IS)suO|<#ZHnXbG zym|9b8>pcV3i~J9bmAE&(`6T}#r?Pb4A*__7E&MmYn(X(%xMe5VwIv@2KgfR zdR%MQB(NT`A1IeoV&o0R-eGNnL0SRK6q>k?6dt=9b6T(vj z-o!N2!v5#>{t==_giczh#&<%?g&=B?BC?IV5- zi%H7dfir<#c;qXX z^Gl_hVYX;A$VQ`B=^hW3DE0E}v=7Mysf3&hc~z2dgls2J7?^)7PADxP3ahA zSaRf1#O)@uDr02P8VqVpopvPM0Css${df@Xo?^It8^iO#%$S^cU*zx zG!o?^_LjPf=TWox^sXD z;oS-&0LLKEz!hEx#f@btUX=lGA@NYp*9Gli{%$rgX5XFk!znYzx@a#fS=cLArX{zNBNT zQ=)UOcmtL^zY9kkc@#jvtAG768lPm$8>ypH8NwBBtzs@5#De)lH2Ug=Sh+~kqho_S zfAw*6+3+zK9H@h5T6F9w=V8H`IT{)&lWMHSxx>p)st!`nju53~I%i-#9+k_={!522 zhix!LLz=5Vk_>%|HlqwFWff>C@l4XfWf7ADqidEyRzu+=N-Ym5rWSBmr;^rv?*8oV zHPQvbevL&kPqLzAQ65P>8j-ussH+8(jZ!5)1~fVyjdokJtzIa_rP$}TaVGlSNrkdw zp>xmPAr%O%gt+GeNo~K?GI6=;=J<&Q(HxI0vz?M>%|wdwq{_lYNf}#22$QuBaGoQ? zw}4O)4#ZtB65fIwrD2jmMXM8F<;tVc>9i3=KzU#uFRjP0;b?9Km63(0vc}xZ42QKk zjz0NSSlBLMc24ui&=53hux3Omq>P+sT816384aIL+D8AiW_#wco)x@0*Mq!hPDLT7vF;-QGFw1ATE+AnZz9s zEhb6<3m4X3F)pc)4+L3LpIksPzm-(n>1l;98HF4XD8Gv4E-w2&WK$gHSJqfN7nv5W zyQgEelWBr#-9kqgK-6lQPrVh*XjK~IMmeHpvqd%!WQ3@bnNpP9zjDg3IcSAU_`0-( zqW>jFs_d!6*fA_Xh-N@KWIzjz7m-3TImpB#V8nbNM1pH;utrcNpfU_oP#3{SN-YQM1#;-Mw0?H$C zXK+{p?E6OUI=R0SWcLq~b3Ky1L)rbYMA2I4SRq75j${u52uE?!$r`h(hho~WEMl=v zBf4-c(je1aOC~!l7KZ$>Spmad>(Y-k^`VJ?`al^)yOCxl)-h9uQWp7Deg`92nI?97 z{B2HD%@&S5W9-T_u7zu!<3yG1{K=HgxlQ6V^8N1QM6763Xz`LKj7nY(Q7=`j7kw+P zE5}*1GP@$$MX$TsyG1KJ$&BsFUr!p~oFT9#D=h90vxXH_eh4dBMHhUh1osVZl*!k`SHB4_%oGWC**Go@%OaUMmfP!uVGDpe5%1RQ%M=f?vU z^dVVvv*2oF)Av(&e)qLit5yN`d^Dlw(*+Z? zK-`GgnuH{A0_-bSvWprQQDO%u*U&lnBY5!s3Lbv&In?Uq?3oJCN$&h6TQb|GRi=D_ zSb`H-$2rr{;gGR#FJae4LU{zagUw_$l+W(YWlK=9CI3mD2vz1s$Vw!WC{4s8Q28+Osfy2<+38E3Q!pZ%0oq~l@!7z zYt^Jo9^L|ZSmk4Kb&lgBQwj?U9G5Eyh*Gpp)-V+lKF5UJB(WAAMNX1>#LP^jh}|kx zmP^S%hDqc_1=~P|B}&M$1%ZCQ*q3LdFzN9+X4Q@WrBO8k`_m z@TH2KXjE|)-?Vj^A#`CguP|G5(>ahp{4EfZ3c_TAR$%UMqzR=^QK#Ku3PM%{ilR29 z`ns+#bK2M8RQUvR3Hz!rJ-T7D@?%En>kO-dv-5xCz9pDl-^vr3NQcdLUM23M7oNzY z1Xxry@3D=(xbp@4V)J$^JLOGSxN;SK@z^Xn5uvg87#w~28?gD=pW~t(+i}#<$2xYJ zvq0oYm6K;qqhY0prT6TzvUfA0E`&mGk*6qjtZk$>m3XLLrpbvZlxuYkxr3Rx7Fp;} zW{x!R;7E;T56zM)5jw3X(Rz-#MVv*euaZ`;glo5aPJa-w!}}_}cQ@BXx$M2e5Y`iG zl5NNYR~e0zg6_;>YGxW53WJS#P~61iL>sk61KgRzp{Yq!>+?_wxUX@bo?|0JI}aUz zOHbDIikyZ)A_VinI{lNBix6zgHhrX6DA)-%^K+3Ma7&&@nWRT#yUi9_%N>F}`^K?z ztc{iDo`C0`JBY{UVnU%xc@{(S7C`HDxPQ}TYXK=3HS65UU1jsRK+k~n29b6D@Oo4# z+>YF!y&t#T@enXDh}~Pa;NfTYKm{R2=FP|GPy2EmWRZ$JS8RK9&49;78X)4a`6dJEh{{6&zEt{*Z()J{_-E-o~I9@p`OH7zHl{4OXg$u zwwrLv9pA@fR6dU z`3k9B6}5Y@3$X=VJeHzkB4%g`5tbB)fZ=+8dQ~9|fJ&u`(!dbr=9;|{0dSfypq!!4 z{oBpJx-A~BWHHGn95p&zMRn>Sy#F`<9CM>J-0_t!;43#gidw0O2Yzuo?tf$}Ivip9 z6OZ7|JARCh|IsIK@78DW!j6}*^M&oW@%vxH&mMjrwSgM;?bwX3e))$Oix|q8xra+V z@SpKTU6&TAaZd#)8?v1HUMm&lGX6zCB6~w|H_1}9g1wL5iWfWU@CSeLBmCW8ej1N_ z=X2OsYGAlt$JCzt@x(JP;flBZ1&*jTG1t*uy#l|+kxzh^dW@bZVY@7eUT?)VTX#jH zLIdXfc(SRv+kJs#>AJCCFE^N-0(iY(IZqVC$Y}?$c|dIT0DeG$zgP;9001BWNkl2ZAP+V7*f^a#G{br;Y#ul^4V zE+}K14`Ii)y;w7-@a?bO1jc?mapTii`}cp0&A+%24?NmJaOBar?3AMr>25R3&g*zk zwGy%F)3HGT!L#7#wI~36s61Dhj;+6O#@*p48;D%FbUNkFMH;3glABJEF_D8P=??Fl z7{kco<1u~cMeLn-8ZJELd2D^5jMl_M{EwghJ}!CRMp_g-hXb8}(;h3|SfsSEhS7jc zBfb~voJxWV`VxD*Qp^WQ`8F3u?>gfCe49*`P~N*>o34?q1F1M^g5sT^Kq6SGOK=Y= zw>)nO1E3?1Sb}2~J;N_Odmk=-<5`$%1{7$Z6aWuDw2yZ`_A^?!?xH+1tjkCy2G7dq zaJIrpb(oB4JR{k4*pKo?)J=a@9P2uT?BXyC(ld&%VC5oycJofI4V4g4gac#Xw|ww- z`1B(e@Kg6c$dmPx@elv_4|L(0^RVIcQGRLL3;gmP@c;VUS9r~y=XlHh9sI<-FJt|N z#d!4ICxIX!hGdV*_7ll2<(pkfDcx&v?6*4Pot?SqAS5u|*~m=LPP3YOoJ$6jrxME` z)L;*mh6KA;dOKwd)`mcuISkvF9510dK$vch;n&{$XL#b*u-0#nbwgsB(z(B?ZHppD=90<|Cg4p*k0fS#R9GyPshGPkKx z$s$|AKtl=^bz1U2*mljRNcWceF(4{Rw)jR*x6r99S-gaUlLs+9(*YA<-pEqS&g?^}31VVQ?S6^xyZEiO^CkoXsS}ptB|_b4(JN8u@~(WSN~WCWTJ22n5am zhHMh!FnYA9++s=$#H@)0=BlX!TEB7yJ%0NSX>VJrLyvud?%IDAPF*~KpmH{CIO8=q zW%U5AzvU;W)@x)TL1liDGUYW1J>`P&03~8r2EfUJ>^dDAHqnl$@MIl5$gY>3*RG?ClZ4wzJi-gu(*T{hzLMMyUIlV@9ANIY8`!kXo-Czf=gUCZnE{<4 z@luf-%W`fJcYhv}gAeRR;$UjG)hA?RD%U{!P{Po_V7wnmahWoC}|eS zm!JzOM^-6WR-oKx7iDGkamX@rH~?a;v+ggk#LYqA)aJnmHhb@Nds8aJT4?Ex`RO}U&8Im8Eu+f*yT5~!b@_%KDlaf zdJ3|=Rd$oKV&f}Us<`m{b8ylLYp~^!#}I}gj$OGP)9VKD-Mx3?=NlhJZQp#XKmV%k zDFz>qOyXWrS~l{mIsKM254R-g0(;US2&e@;xEgPG^D?YiJA~%g1jbAAalxg3fh~Xa zDQsMME?$5B2{?M9j`0J7c-sfg#>0o|IP?5tarFKsqL~O6y!%a9TrC49ACIqJw;6BQ zaAu5tElzlvuss`&fra0K!u_uLPa=$Eb%dyS15Mj0)2tfHuc#_}_9#T9G7s)FI6 z2y^YDaM9&QqBAyzfzj2t;Nl~}#OQRQ9Hzj>-Dy{0y03K9tG3$DnDkd&KD=bOM}9b8 zspUQ|#2%*ng6s77?B#qN8JUlZE_@XLpxy3Za;A+F-|~NO=S|;5WoTU<2SUZsR_Io< z{BhN<=BpnhszM98z6x)6Q-JBI2*Jt#CEdb-S%ts*r>`SwPT}C>9Ll8#;|IpE?(+9z z1I=P`x{Wo*D;zp7g$-9+g1G}@p!JvFlNY`L`(E0GxlXYc;Pae(Se92(#%4!Oz`KZa zy{-*wCYLsyO@k?Cz(-2(Fc9thmcD~rs3`N2r0}#M9e;~BsKy)hp{olpMEp0hJ-}e@%(m*Tapz|Gnm4FrVi}JbYf_;vw$ioKD2L4 zDW#aE4)TtPaZ<{3sdBD5k`G1L30bWBmCut){`waoo1E85MY#BHVk=G+NEn+lbI^MFvD~QMY@&5ITGpz_>`%Ume?u zD+t{B8@1L5O6_IoK0Te#+PbXk<-yfneKQV%AO{0V2=6%*&#H>11CFg(^o0pMnN-goN%7kTN`M52B$CFrEE^ z>X5xFcPf{jiQ{F2^p5BtrAol@VxDbk%58rrSaGCoG+EUrksyu-ojgfYVLWMP5^Jpl zRT3xClO&RaCXwhP)hSA%!X{BJzugeU=;xp2TN3a-No!`}AcU%p zVAbjhh8h7%C6%ZcS|rYjgqu%rMpbZA6WN;HWRtQWBi)ja7{a0jWnfSNCwwsGD6#oK z%=l#73HI;g$Z8o?8b_dnb}Qw}rD3S!-UR5T;He-_Co)NW9rCcJ zT7;)0r!1UTiEOn|-!(u0RY`hyl2OmoB`*87x@hA{I=A?Jp&TtOBS*_c1l8+ zMLrXGeztRi><`|MP6as!>L-ohR$Th<0m)N+DSCFh{MAjrku|XV60x5;5N*4e zj9{}BlKIK1=&%unVfH{4Sk_vYGPgk?49i%%d_UGM+7D2WZJaJt+=0-83o?`JflIg? z86@7%0BXy?x(?E9|FuNOklW^+V~O)MEV-q!b3X(-m63p-d?eK=hMv^&1~zRS#Kc57 z>rl-AeHQ5>OYz>Uq?tU46i#PRSTpSh9)Uh~o!5loB3@2ct_XSE+T3R5+brEdrXos1 z%BQXqT^LDXoe7*}gF)b_sY%|oYc~Z!;409&w0@R%=n+@4yo7=U#LGzLx>_EurJv-d zp#ey_Ukh*=u9xAX(s#Wt`E2aaJIb62ty;aB@W5Zi#>!sl$Fz@DB;QyFG*LSB$Wo}K z6bixAB{7>O=9qK`T&fdJ{1AB8M&QNUfO10;uga<_7r~#%3NehtqR7@}MaPUBHEy9# zb0|3aGEi+X@YolD@^CKam#no!xpsbV4yq;ZOKNs;Q9_CsQaRAVZ+PsD8CZHEwm#X! z?w1cG9JuJIW91>F0=m$H=GpMOH$fWNhB^UjN4z2S)7!S<{>_hrl*0PeD{;!nryO3* z&X)tBd`UZ>YU-le-EV2rrT#1GF71{-DEfQ9@AJ_Q_ET=|c1_z?)x6Votw5} zrc*)~C_K4iGj{IYk4r8%8@1YCms*hDJrAvP5y?ak6Dg%3dN(Ax(yhXnELmny+ylxE z#~bjKLxnCPY3a?R(g^@8u8O?7rkFWWNHr}Ah#%7Xay=QRV$}259nYj|FAPJ&_~Yz# z!K{)T5wz(-hlo-r+iA@XE$N6-f*h+)Bt^+5)cc0gPm{rQvek*RbuxMm=zaIHGPTDNI#b`ne_l*%EZW)qqe!cv6-Zu4Bb10`}2K7gWIGIT44 z0AurGPw>}nco0L&Po{TVaV7#VzIXc;{@PC;Vx^c~cj=|<`+Viz=Q7}{Uj??KUtC15 zW0@HgmQgJSG4RXl`7kIbqZBBAi7yCIEte34C4`2DnEJ+V6t(sDI<}wpP#?*pd><}5 zNf#TmL*6K`OFtL;iWcrW{TnIukp%0OH0!76Su`F++DXM@LS4q`@XD#wXJxVI37IKI z=0(#OJMc0N9@-C0r5H~$Jq=9?ih$O2Klgf>4u{#d4=|k%uK7yG z!#5^WFg~tELQ&ekIK$BAJ@$ScrAj#P^bhdGFZ~g|`Q1-r?_3?FXfHP2_+!l0hk@DM zc;wz|@ZgSd3|2z?vTPGC?cRf(<87=z^?W?GbrOGj-2wdF5BFo!lM`6J;us7pJ_&c; zb8pX2lbJ1ix^jm<=`>YfBGz#YnVA(Qi;al&m2YFvT4(RE6GfR0K-y#^`ej7&F%71O zf)X|NZl^8V#;M%dtv>xXpTs>+zJyABMD2d;M)jBf=WqD&{gJNB?Zz!XyjFeY-@ij) zV|>*I=p=DhM=c(t(@aw@RN= zYpv2}>i5~x_Z4lR$#`ZcMz*>hZ4Cw%It&aYasVm@2NK8f29&&(yoUu1X_71^B5mHw z={dwE630m~d52EUm9grnP2C6ec`lI`qsIGpj|#XzWedRJ731{{@H)1x4-sc zy8fR(f_)rf-wQivHkzO(HvT&u8oq=sS$~u|G}|KCB`wdFG&x$oJ7cE+pw-rBMu93- zLj~QUMMH|`HxCq$K8Boir*jhiq+3=LKI&j0uU7Oy;>?%(nl^z}~8mZ7ve|{g8${{LYpu)-k(b#tW$-}#G z){(pMx7TjgOXh{dI)0wS_)R`TYi$-dvAFd0>>{5cbON&Hr>y&uY@C$k`7vh-&RJE1 znMB=;llxbkrd0?!jnlzdH!m|2YgRB-AqFVbLr52$w1ZTqa1%D?h~r;v%EjsVt>TP1 zuQ}GbFIdUX^fgHW*mXSOXHE!%DJ!Rn*e-==k=Ve@n22X2r1zh8^je*Hq)o9XX<;|# zBa2iu?SxI{0T6dCyW-cB(PDsDQ$_FGb{7_%{x%xnS+34MTVHf~fXz?u!ccjJANl#G zc}M+CeB}ij^z`&0j)9Qb{IkPlcl;sqE#^K;r4U1nkOynv(fJLYe`K9Tm)6w6g@ZIS zT;@tC(!)c;vf3!GMI0~CR%Mp~Rw4n#Lgg{h_Ep;OWjLkFWN~0$V$@AE79>#(Y+NQU zv-4z~%bgCe;)KQe2VeaLuUN4HsGrB5`1EV|??3v#@a+CsP<0`{<*iroJKuRR?RnvL zJaPLL{?Uy$^2Td#;+;CwL<|)$Pft$p)*F9{uiSbswtoF5*i#$fkSzE*iv`2W_SEmQ z_mM)q7^67Uwrl-=`a8OL$r{z zf>Iz5MRQEYU-nk~%V+){{`+6N1C{ZKcm~?~Hs;y#J4ye~?ps)_=ZE3INX<8MM_H_% z5>B1C&ul?L(iDZ{zR1p*ysqRqT~+(+UR>Ublotaw8%%cIWCw@CdEsOvtU_QO?2_?X z$nl`uc%;(U#?MZ!opGh0%a|~%u}+t57_uO80CR#P1ztXoOiIIONLzDRgfJGQh`59K z3y#H}jW<(e`C1w+Px1rzAHa$gOQ5P};Vp0f7|veS#P@EvnTHoFrcNgk+$fUR$9R}F z^xVlx0H9^dmgAiDD{1@PH`8MqpTLIsz-dE-om+R(t>64QjoZ8KRmIR`KFJ*Wi@XUIRUE0hTN{A1j9M!P&3>P3(;J zp;oHn$DjQGUjOHh;Df*YRvdfUF#h!N%kb5^o`vEFole}?wQ${942|E9*Ij%SwoH{# z<~Dq=vtG~9?b*8#GWSlvxyfsW&Bw=u2|c?GL7t>u_XHntKZ!wd(xCaKk6bpAxl4AE zdho&)64!ODq7W602^EY9;BT(;5iS=c(2H>zB!(i6Vl?I*bs^RaK90ZszwgACzy2u< zpZ;DPH=;1pEMdXYRakT4g=jtd4gB=Mr_iWZoO4OC>)yAQ&c%~YSc|JJIs>g|AHff< zz7{|F=67)5@q4kl`8x&jc=dZe0#X4@HjA(AdK2)Mf4e@r6d4yEBo!_$ zBtJ8;tEAgM*}uCLST->`F?E%N;-t-2cd=hKlJW`HRZM8;Vk0@bHp%-nxtjF%)PDdn zFN(>Z?svm^vf$jD(xwU6jdwXQ*DjzPB`35_qbg>j`Ry4PAN@zyxh?h2j1);_0iAHp z>!F|BK?BtR9DV$$C}li%-IZ7q&4w5Kt%TizcG`C(cX*12w$roHHyKRg;8kz<{FUJICNA2Yc^#d2_r*dzqdr=32OHRk7E6zov8O_;ow4w&qoN@-5 z6NjLKDpsz$9NeD7OtYPoJBp#TQberiy37nx0Zv@M9w)BP{`T_XMVOkK!j^~bMfK=& zdm~`D0Ewy+K9H2%T1b0YNz|l0K8MEifZ__1s19C&3ql0bh7@$83#L?y#GF36JE2N+9RluSZWBV({-iz_Be zf+ik_W&@EH3Up3lkwH4`{!KYjC`;&?W*h)2rN^>K9-P@h87E>QuZ$cCjU`V+@%mx3 zWs}9r&=Wd1jx@qfduhl@sOGvwZ5cXF6TonlB-yasr}q@!rpj&QL^>G*xs_;(#fU`% zvB(7`ZNW)`lF?~R(xKLrK}ai#FgrEL2o%5(W@pA31O!2{WGV@L=bXb!nUCj-$y@<= z0)Qy$;D{xQ`Hk=T9e(4xe#aMUvJ~V@H!p~0I`a{;_~Df5{m+w5MD3MB5q z#o-d!QK-N(5E(%!(>vXjdVq4x_yj;lgm8|a+dyjyJhvaDo7n+LQ<-m}_wP`GbVfQo z>^mlnaboBZqB%gffw^%HeWS+(uq6*XGe^WgUd*kOtF|OIoSiJW5D9|P7`%>FOQYHB zB)u@U;kuA>vZ`O)b)yjzHZK>ID{`C{AhOwBY!s%}x%UxVjYN){>8J!$=K%{(0hQ}OQ1)LVyAIj+%Cbp4 zTRNCcS8(ijXhH^INjhM4g2@0dxC|%{GnSr12x|oU`3>7V8O;|a(f3Yp#{#mc*fWNr zI+EM8)9Qvz6Ogs{bEH5ahK3l;xoXmLm1*b5^)KsmO4|3?IM=zZ^?ZIlt?1Y*sa$mA z!j-o3OF|*v3M{!mq>4gHH7WQ&#I(^wQ2r#URFp}@wbQAf!PIOv>CmAG!|nwS7+B^= zT-V9oy~$z_E9L_cEH#B-W9t|%=9>JxdE_~VcjxXR6mGZ!3!WYBGpFGa0hk&*6{N^y z)pJ}nZn+}+kh+Argl=v~_PAsLyvt#LXmkXf;S=3jsH~Py_vEitTgfFcz^;>$(sRYH z1qsz;XZ?Q%b&KP3{rue-g{|&Z=Hhb;OIoFTO85M{@d)7?L5Ed+$kLl?dOioQAP|7!3$O43sXSGKG!70hx z^2HtTSEDhAFf8G~fdf#1>i_)CIzrw>-kLXEZ{8m(<$sw!e?BHBC(v%Us7DG_a`^Z* z8nOxp#T#j__|aUfTCGyOUibbz2m%B_;Bx}lrP^>MgEebXVneq1K*-7}SvHWuX`guV z8IV#j9RdM<&L5%e;iZ?CJ1!OP7~ae`feLuOib-O{&PcM#k+JcTv*O6#eSDIJEKgLO z$blZDi)A(zjCrFYTq?!eL%ZEVn#AqKCE=6K6d$yY{HRyC+$iyBtq}wPX|2(2w=g?1 zlTI$zb99vmivS}ej+KBqFS(R-$19aG0AO-*!kXZ29x63958JrU;<=YY=G;?JE-m+* zqoX63o}R|+>})sEDS2*dY&_LEUk-)xIXRn+%+626b9!WCgzNRXO$*Avrh6a7_kaF% z>^yKc)f)%EQ4Li(fzLnXO1}K!D^MK`sEE=qCKV;y7z({Bf_kF?oF?-uh#xLYC- zK`CWAiRJF(BYx_Orr?#3D`jPFa}PfHhN5Seue)REhA`+69?9d1h_B@930Lr8fd~81 z7s`cRh6pSF{_NSE^)v}q59}GoXa4mc@$k$KaQqq1MI zHxBGS&@V!_kO#J0E*IuxI_-8&p51p`5pRiwP) z`toP#!Pzh3(l_kK+I7I-PzAHi0F`zL(SnE$8ED!>001BWNkl_c^$)%#*sqdAdkDapL>$wxH z(~iJ>j%3m99|Qp=Cnq!R5h;bq8l_Shst09bx2jo@hg0+whM`HU=bpFIL8sH{`*ZI# zkGhSs`*WpILAhKm^q{7uruz0me2K_@D|@~4S8BCd;T(&ih-PPJyLvah2&|ejEnIi= zk8%4;pU3Bp2HUEsE1w%PC z!Nhx~f*goTd|526+Qo%FEaU8!!{}$y_zbO^>)Y)^?X^H1?)@LG&r`%TE5FL+GJbLA zofsV*MZ4WXimVI*h4Jx&IAg_oyDiSX@aV~{ zTM;NqG>)=bfsQmPl?oOwUW_OKMIKJrnEwC7)6e0jo4B7ebzF!oFNWBANTCs~ z#QLGv;!x`uY@fOrXa*RrRB_B%AvWD`C;sC**WrU7dY_}Un-{wcMSUtcKogPD!tEnU z<@G49^6B{y*^%jyHElRrFjkVOXy=yiaR5!qNir4zp2%)_F2wC{m&r=*y?E}|O?(y+ zd=>t!9~#JkfdO3bs*CZ`%exS&01U>+@DO%9w;i2M$B1e5!nqty!=ukDo1C1)@@31g z?5LyBoNFNwWJkGNLZE=HPd;h5JbTed_7TGLG+IICgjTbOqmNpFaQVd`!?J#iZ64a zK&`$Sag1D$xXAl(Zi$_H;ev!1J5>Yt)w+zz5jBlgr}a~&dpYblu}e1sG!x_ z&vSE4u2!o=G0C*mvm;||G3G_3Lylz%xSQA)hzR9U$j@wlff_>%bUGU4Qh=J)h&nAU zl}m&;$>=r|vgh919;1GY)?2A!W~x*w&`b;}fdWFHh%4n1mCIEg92}J3KQHZqJGXu9 z8p#+?QRU0sMC2xmgk)rNbd*=EKAsNjAB!vNF}0)+#+ zr*Yumqd4W<7WU1S@yy-<5JgZZL-Rmv^I)`i5Upqmr9fkTrHMy_GO%brp1k*QtUY^u z-ZK@@LdyeD28Gt!191n(=>y4mATBYF?{B?0Qe8uHJq}3>rPdR0c;zNeyjEXvLBy{-~u;WN+fFwlWYrNqRHsfj~rbg{r|31OOq`d8l+8&qdSJaLSYg@5_lxdBPwcB$1u^JBqLaLKw?CK|DALZwS*RXolmqf4(<8e$pXCNpTDT0t0=xl&T7*DF*hmBCR9hYpRq6&yGm!d*f? zpj6VRRU_Kh0$S4{P8|IWde7=lAmTK41}v?eME~vh8z`VMo}J!^e|Y>ohss$?zOv=? zKe57H3Ihz)YjL%qRE{B{qFy`jc z`ph-3XNR{G3mFU*C~njTxIR$EK()$27!pXaE8r}EZt`5FBirrPw!L$LJ%&Jt00E~g#iutOLSVW3)}=3EnD7$OQaD&;bTNdrU*UUT1< zKBGe==?fjnhqZ7+nE1VlDwQyS#K$}=3WR}51*|nOI5q^o&YdsBvN%=x8E+pBf|EtI zQVywHE+Hs|2!jvxRe#nR2g9WIQa*K8&L}lTY_dXbm zO8Ng&_vZ1oTvfT~H|DHbYwf+y*{9Dr3F!#w2nkK1p>L&C8sVy7OJh*E4;!vt_1!DV z72Bu0s~4||Pi)>31O@eq0#BasK$;MGA()sDAbodo`n^|EbBy;#%~@;KtTAh?ea;Ej zw|~Fn>}IX1TGf2>8{Zh?8><-Ey%?VW-1Y(=x%Z>ELxhG_u}9LIJUWpHEhGa_1)^}jtvv$?fmf5vZ!@oOw8tb7)Csy9vT}+X?`;K zt+$;YdYQDwWTfZD>kVPzlIsjOZ3R5_kW2I|%(5X204c1c`|i6BRW*}iM~~5=BZmn9 zR##W$&O7gvbI(1u)zhGqW=nL=B?EktOPR+&V~oKAhYsPq^>rLNbO^R6U~PfIS~_y{ zD5ldX=H4e;d+?G{^`%}Pf6ZnUR#q&{CKH@sM&%gRTC9vl6lY*Gz|kVPx0eEFJz-&4dYb~q@74>m~Y9`YPVFG(u6vD7$?AbTOzU`OL-Crzm_9YH?-nxOi zCZ9zCLwmPf001~v9j6c9|52Q%j?thfv01I){zH~7+Sq}MFTXTF4hc2v-8vA72amT# zi_bSv7b=yfEnmLH*O4ZCE)gy*6^bMbgcg8EFL=hHA(93m1u%0AMALlCWIDwoF1t)_ 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 Z25A#Bg8X}0{Q?3$`r5`?bs7(`{|9y~Ufloy literal 0 HcmV?d00001 diff --git a/htdocs/opensurvey/public/index.php b/htdocs/opensurvey/public/index.php new file mode 100755 index 00000000000..1d31bf260b3 --- /dev/null +++ b/htdocs/opensurvey/public/index.php @@ -0,0 +1,61 @@ + + * + * 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('NOREQUIREUSER')) define('NOREQUIREUSER','1'); +//if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); +//if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','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'); +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + +$origin=GETPOST('origin','alpha'); + + +/* + * View + */ + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeaderSurvey($langs->trans("OpenSurvey"), "", 0, 0, $arrayofjs, $arrayofcss); + +print '
+
+ +
+

'.$langs->trans("OpenSurveyDesc").' '.$langs->trans("OpenSurveyNoRegistration").'

+

'; +print $langs->trans("OrganizeYourMeetingEasily").' +
+
+
+
+
'; + +llxFooterSurvey(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/public/studs.php b/htdocs/opensurvey/public/studs.php new file mode 100755 index 00000000000..9a20b14031b --- /dev/null +++ b/htdocs/opensurvey/public/studs.php @@ -0,0 +1,713 @@ + + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/opensurvey/public/studs.php + * \ingroup opensurvey + * \brief Page to list surveys + */ + +define("NOLOGIN",1); // This means this output page does not require to be logged. +define("NOCSRFCHECK",1); // We accept to go on this page from external web site. +require_once('../../main.inc.php'); +require_once(DOL_DOCUMENT_ROOT."/core/lib/admin.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/class/opensurveysondage.class.php"); +require_once(DOL_DOCUMENT_ROOT."/opensurvey/fonctions.php"); + + +// Init vars +$action=GETPOST('action'); +$numsondage = $numsondageadmin = ''; +if (GETPOST('sondage')) +{ + if (strlen(GETPOST('sondage')) == 24) // recuperation du numero de sondage admin (24 car.) dans l'URL + { + $numsondageadmin=GETPOST("sondage",'alpha'); + $numsondage=substr($numsondageadmin, 0, 16); + } + else + { + $numsondageadmin=''; + $numsondage=GETPOST("sondage",'alpha'); + } +} + +$object=new Opensurveysondage($db); +$result=$object->fetch(0,$numsondage); +if ($result <= 0) dol_print_error('','Failed to get survey id '.$numsondage); + + +$nbcolonnes = substr_count($object->sujet, ',') + 1; + + + +/* + * Actions + */ + +$listofvoters=explode(',',$_SESSION["savevoter"]); + +// Add comment +if (GETPOST('ajoutcomment')) +{ + $error=0; + + if (! GETPOST('comment')) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Comment")),'errors'); + } + if (! GETPOST('commentuser')) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("User")),'errors'); + } + + if (! $error) + { + $comment = GETPOST("comment"); + $comment_user = GETPOST('commentuser'); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."opensurvey_comments (id_sondage, comment, usercomment)"; + $sql.= " VALUES ('".$db->escape($numsondage)."','".$db->escape($comment)."','".$db->escape($comment_user)."')"; + $resql = $db->query($sql); + dol_syslog("sql=".$sql); + if (! $resql) dol_print_error($db); + } +} + +// Add vote +if (isset($_POST["boutonp"]) || isset($_POST["boutonp_x"])) +{ + //Si le nom est bien entré + if (GETPOST('nom')) + { + $nouveauchoix = ''; + for ($i=0;$i<$nbcolonnes;$i++) + { + if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '1') + { + $nouveauchoix.="1"; + } + else if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '2') + { + $nouveauchoix.="2"; + } + else { // sinon c'est 0 + $nouveauchoix.="0"; + } + } + + $nom=substr($_POST["nom"],0,64); + + // Check if vote already exists + $sql = 'SELECT id_users, nom FROM '.MAIN_DB_PREFIX."opensurvey_user_studs WHERE id_sondage='".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."' ORDER BY id_users"; + $resql = $db->query($sql); + $num_rows = $db->num_rows($resql); + if ($num_rows > 0) + { + setEventMessage($langs->trans("VoteNameAlreadyExists"),'errors'); + $error++; + } + else + { + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'opensurvey_user_studs (nom, id_sondage, reponses)'; + $sql.= " VALUES ('".$db->escape($nom)."', '".$db->escape($numsondage)."','".$db->escape($nouveauchoix)."')"; + $resql=$db->query($sql); + + if ($resql) + { + // Add voter to session + $_SESSION["savevoter"]=$nom.','.(empty($_SESSION["savevoter"])?'':$_SESSION["savevoter"]); // Save voter + $listofvoters=explode(',',$_SESSION["savevoter"]); + + if (! empty($object->mailsonde)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $cmailfile=new CMailFile("[".DOL_APPLICATION_TITLE."] ".$langs->trans("Poll").': '.$object->titre, $object->mail_admin, $conf->global->MAIN_MAIL_EMAIL_FROM, $nom." has filled a line.\nou can find your poll at the link:\n".getUrlSondage($numsondage)); + $result=$cmailfile->sendfile(); + if ($result) + { + + } + else + { + + } + } + } + else dol_print_error($db); + } + } + else + { + $err |= NAME_EMPTY; + } +} + + +// Update vote +$sql = 'SELECT * FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_users'; +$sql = $connect->Prepare($sql); +$user_studs = $connect->Execute($sql, array($numsondage)); +$nblignes = $user_studs->RecordCount(); +$testmodifier = false; +$ligneamodifier = -1; +for ($i=0; $i<$nblignes; $i++) +{ + if (isset($_POST['modifierligne'.$i])) { + $ligneamodifier = $i; + } + + //test pour voir si une ligne est a modifier + if (isset($_POST['validermodifier'.$i])) { + $modifier = $i; + $testmodifier = true; + } +} + +if ($testmodifier) +{ + //var_dump($_POST);exit; + $nouveauchoix = ''; + for ($i=0;$i<$nbcolonnes;$i++) + { + //var_dump($_POST["choix$i"]); + if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '1') + { + $nouveauchoix.="1"; + } + else if (isset($_POST["choix$i"]) && $_POST["choix$i"] == '2') + { + $nouveauchoix.="2"; + } + else { // sinon c'est 0 + $nouveauchoix.="0"; + } + } + + $compteur=0; + while ($data = $user_studs->FetchNextObject(false) ) + { + if ($compteur == $modifier) + { + $sql = 'UPDATE '.MAIN_DB_PREFIX."opensurvey_user_studs"; + $sql.= " SET reponses = '".$db->escape($nouveauchoix)."'"; + $sql.= " WHERE nom = '".$db->escape($data->nom)."' AND id_users = '".$db->escape($data->id_users)."'"; + $resql = $db->query($sql); + if ($resql <= 0) + { + dol_print_error($db); + exit; + } + + if ($object->mailsonde=="yes") + { + // TODO Use CMailFile + //$headers="From: ".NOMAPPLICATION." <".ADRESSEMAILADMIN.">\r\nContent-Type: text/plain; charset=\"UTF-8\"\nContent-Transfer-Encoding: 8bit"; + //mail ("$object->mail_admin", "[".NOMAPPLICATION."] " . _("Poll's participation") . " : $object->titre", "\"$data->nom\""."" . _("has filled a line.\nYou can find your poll at the link") . " :\n\n".getUrlSondage($numsondage)." \n\n" . _("Thanks for your confidence.") . "\n".NOMAPPLICATION,$headers); + } + } + + $compteur++; + } +} + +// Delete comment +$idcomment=GETPOST('deletecomment','int'); +if ($idcomment) +{ + $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'opensurvey_comments WHERE id_comment = '.$idcomment; + $resql = $db->query($sql); +} + + + +/* + * View + */ + +$form=new Form($db); +$object=new OpenSurveySondage($db); + +$arrayofjs=array(); +$arrayofcss=array('/opensurvey/css/style.css'); +llxHeaderSurvey($object->titre, "", 0, 0, $arrayofjs, $arrayofcss); + +$res=$object->fetch(0,$numsondage); + +if ($res <= 0) +{ + print $langs->trans("ErrorPollDoesNotExists",$numsondage); + llxFooterSurvey(); + exit; +} + +// Define format of choices +$toutsujet=explode(",",$object->sujet); +$toutsujet=str_replace("°","'",$toutsujet); + +$listofanswers=array(); +foreach ($toutsujet as $value) +{ + $tmp=explode('@',$value); + $listofanswers[]=array('label'=>$tmp[0],'format'=>($tmp[1]?$tmp[1]:'checkbox')); +} + + +print '
'.$langs->trans("YouAreInivitedToVote").'
'; +print $langs->trans("OpenSurveyHowTo").'

'; + +print '
'."\n"; + +//affichage du titre du sondage +$titre=str_replace("\\","",$object->titre); +print ''.$titre.'
'."\n"; + +//affichage du nom de l'auteur du sondage +print $langs->trans("InitiatorOfPoll") .' : '.$object->nom_admin.'
'."\n"; + +//affichage des commentaires du sondage +if ($object->commentaires) { + print '
'.$langs->trans("Description") .' :
'."\n"; + $commentaires=dol_nl2br($object->commentaires); + print $commentaires; + print '
'."\n"; +} + +print '
'."\n"; + +print '
'."\n"; + +print '

'; + +/* +// Define $urlwithroot +$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); +$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file +//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current + +$message=''; +$url=$urlwithouturlroot.dol_buildpath('/opensurvey/public/studs.php',1).'?sondage='.$numsondage; +$urlvcal=''.$url.''; +$message.=img_picto('','object_globe.png').' '.$langs->trans("UrlForSurvey").': '.$urlvcal; + +print '
'.$message.'
'; +*/ + + +print ''."\n"; + +llxFooterSurvey(); + +$db->close(); +?> \ No newline at end of file diff --git a/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql b/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql new file mode 100755 index 00000000000..3f7460f3e8a --- /dev/null +++ b/htdocs/opensurvey/sql/llx_opensurvey_comments.key.sql @@ -0,0 +1,22 @@ +-- ============================================================================ +-- Copyright (C) 2013 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 . +-- ============================================================================ + +ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_comment id_comment; +ALTER TABLE llx_opensurvey_comments ADD INDEX idx_id_sondage id_sondage; + + + diff --git a/htdocs/opensurvey/sql/llx_opensurvey_comments.sql b/htdocs/opensurvey/sql/llx_opensurvey_comments.sql new file mode 100755 index 00000000000..613627c46aa --- /dev/null +++ b/htdocs/opensurvey/sql/llx_opensurvey_comments.sql @@ -0,0 +1,25 @@ +-- ============================================================================ +-- Copyright (C) 2013 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 TABLE llx_opensurvey_comments ( + id_comment INTEGER unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, + id_sondage CHAR(16) NOT NULL, + comment text NOT NULL, + tms timestamp, + usercomment text +) ENGINE=InnoDB; + diff --git a/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql b/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql new file mode 100755 index 00000000000..377f8abc45e --- /dev/null +++ b/htdocs/opensurvey/sql/llx_opensurvey_sondage.key.sql @@ -0,0 +1,19 @@ +-- ============================================================================ +-- Copyright (C) 2013 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 . +-- ============================================================================ + +ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_id_sondage_admin id_sondage_admin; +ALTER TABLE llx_opensurvey_sondage ADD INDEX idx_date_fin date_fin; diff --git a/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql b/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql new file mode 100755 index 00000000000..1704938a6f7 --- /dev/null +++ b/htdocs/opensurvey/sql/llx_opensurvey_sondage.sql @@ -0,0 +1,33 @@ +-- ============================================================================ +-- Copyright (C) 2013 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 TABLE llx_opensurvey_sondage ( + id_sondage VARCHAR(16) PRIMARY KEY, + id_sondage_admin CHAR(24), + commentaires text, + mail_admin VARCHAR(128), + nom_admin VARCHAR(64), + titre text, + date_fin datetime, + format VARCHAR(2), + mailsonde varchar(2) DEFAULT '0', + survey_link_visible integer DEFAULT 1, + canedit integer DEFAULT 0, + origin varchar(64), + tms timestamp, + sujet TEXT +) ENGINE=InnoDB; diff --git a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql b/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql new file mode 100755 index 00000000000..041b2d0593d --- /dev/null +++ b/htdocs/opensurvey/sql/llx_opensurvey_user_studs.key.sql @@ -0,0 +1,20 @@ +-- ============================================================================ +-- Copyright (C) 2013 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 . +-- ============================================================================ + +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_users (id_users); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_nom (nom); +ALTER TABLE llx_opensurvey_user_studs ADD INDEX idx_id_sondage (id_sondage); diff --git a/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql b/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql new file mode 100755 index 00000000000..78d7fa69c4d --- /dev/null +++ b/htdocs/opensurvey/sql/llx_opensurvey_user_studs.sql @@ -0,0 +1,24 @@ +-- ============================================================================ +-- Copyright (C) 2013 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 TABLE llx_opensurvey_user_studs ( + id_users INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, + nom VARCHAR(64) NOT NULL, + id_sondage VARCHAR(16) NOT NULL, + reponses VARCHAR(100) NOT NULL, + tms timestamp +) ENGINE=InnoDB; From cf52cbfab5f1672d2065648c7bccb8e011814561 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 9 Apr 2013 23:46:38 +0200 Subject: [PATCH 07/44] Fix: Better error management --- htdocs/societe/soc.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 772e1b24497..7274c51cf9f 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -528,7 +528,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) if (empty($object->error) && $socid) { $object = new Societe($db); - $object->fetch($socid); + $result=$object->fetch($socid); + if ($result <= 0) dol_print_error('',$object->error); } $objcanvas->assign_values($action, $socid); // Set value for templates $objcanvas->display_canvas($action); // Show template From af6f075b5c25061b68355219ad0fcb6fa7337c6d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 9 Apr 2013 23:56:52 +0200 Subject: [PATCH 08/44] Qual: Better error management. Qual: Uniformize code for canvas --- htdocs/adherents/fiche.php | 17 +++++++++-------- htdocs/contact/fiche.php | 19 ++++++++++--------- .../install/mysql/migration/3.3.0-3.4.0.sql | 2 ++ htdocs/product/fiche.php | 16 +++++++++++----- htdocs/societe/soc.php | 4 ++-- 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/htdocs/adherents/fiche.php b/htdocs/adherents/fiche.php index dda805ec113..65c79d66068 100644 --- a/htdocs/adherents/fiche.php +++ b/htdocs/adherents/fiche.php @@ -49,8 +49,8 @@ $backtopage=GETPOST('backtopage','alpha'); $confirm=GETPOST('confirm','alpha'); $rowid=GETPOST('rowid','int'); $typeid=GETPOST('typeid','int'); -$userid=GETPOST('userid','int'); -$socid=GETPOST('socid','int'); +$userid=GETPOST('userid','int'); +$socid=GETPOST('socid','int'); if (! empty($conf->mailmanspip->enabled)) { @@ -68,7 +68,7 @@ $extrafields = new ExtraFields($db); $extralabels=$extrafields->fetch_name_optionals_label('member'); // Get object canvas (By default, this is not defined, so standard usage of dolibarr) -$object->getCanvas($socid); +$object->getCanvas($rowid); $canvas = $object->canvas?$object->canvas:GETPOST("canvas"); $objcanvas=''; if (! empty($canvas)) @@ -117,7 +117,7 @@ $hookmanager->initHooks(array('membercard')); * Actions */ -$parameters=array('socid'=>$socid, 'objcanvas'=>$objcanvas); +$parameters=array('rowid'=>$rowid, 'objcanvas'=>$objcanvas); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer)) @@ -694,13 +694,14 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // ----------------------------------------- // When used with CANVAS // ----------------------------------------- - if (empty($object->error) && $socid) + if (empty($object->error) && $rowid) { $object = new Adherent($db); - $object->fetch($socid); + $result=$object->fetch($rowid); + if ($result <= 0) dol_print_error('',$object->error); } - $objcanvas->assign_values($action, $socid); // Set value for templates - $objcanvas->display_canvas($action); // Show template + $objcanvas->assign_values($action, $object->id, $object->ref); // Set value for templates + $objcanvas->display_canvas($action); // Show template } else { diff --git a/htdocs/contact/fiche.php b/htdocs/contact/fiche.php index a0ca630a423..9711654fa03 100644 --- a/htdocs/contact/fiche.php +++ b/htdocs/contact/fiche.php @@ -162,7 +162,7 @@ if (empty($reshook)) $object->birthday_alert = $_POST["birthday_alert"]; // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); if (! $_POST["lastname"]) { @@ -254,7 +254,7 @@ if (empty($reshook)) $object->note_private = GETPOST("note_private"); // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels,$object); + $ret = $extrafields->setOptionalsFromPost($extralabels,$object); $result = $object->update($_POST["contactid"], $user); @@ -300,11 +300,12 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) // ----------------------------------------- if (empty($object->error) && $id) { - $object = new Contact($db); - $object->fetch($id); + $object = new Contact($db); + $result=$object->fetch($id); + if ($result <= 0) dol_print_error('',$object->error); } - $objcanvas->assign_values($action, $id); // Set value for templates - $objcanvas->display_canvas($action); // Show template + $objcanvas->assign_values($action, $object->id, $object->ref); // Set value for templates + $objcanvas->display_canvas($action); // Show template } else { @@ -510,7 +511,7 @@ else print $doleditor->Create(1); //print ''; print ''; - + // Note Private print ''.$langs->trans("NotePrivate").''; print ''; @@ -728,7 +729,7 @@ else // print isset($_POST["note"])?$_POST["note"]:$object->note; // print ''; print ''; - + // Note Private print ''.$langs->trans("NotePrivate").''; $doleditor = new DolEditor('note_private', $object->note_private, '', 80, 'dolibarr_notes', 'In', 0, false, true, ROWS_3, 70); @@ -941,7 +942,7 @@ else print ''.$langs->trans("NotePublic").''; print nl2br($object->note_public); print ''; - + // Note Private print ''.$langs->trans("NotePrivate").''; print nl2br($object->note_private); diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index b2be5f7fa14..45d28802558 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -244,6 +244,8 @@ ALTER TABLE llx_actioncomm ADD COLUMN transparency integer after fk_user_action; INSERT INTO llx_c_action_trigger (rowid,code,label,description,elementtype,rang) VALUES (29,'FICHINTER_SENTBYMAIL','Intervention sent by mail','Executed when a intervention is sent by mail','ficheinter',29); +ALTER TABLE llx_adherent ADD COLUMN canvas varchar(32) after fk_user_valid; + ALTER TABLE llx_expedition CHANGE COLUMN note note_private text; ALTER TABLE llx_expedition ADD COLUMN note_public text after note_private; ALTER TABLE llx_livraison CHANGE COLUMN note note_private text; diff --git a/htdocs/product/fiche.php b/htdocs/product/fiche.php index 60c3785751f..e8775f44621 100644 --- a/htdocs/product/fiche.php +++ b/htdocs/product/fiche.php @@ -638,11 +638,17 @@ $formproduct = new FormProduct($db); if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { - // ----------------------------------------- - // When used with CANVAS (more simple) - // ----------------------------------------- - $objcanvas->assign_values($action, $object->id, $object->ref); // Set value for templates - $objcanvas->display_canvas($action); // Show template + // ----------------------------------------- + // When used with CANVAS + // ----------------------------------------- + if (empty($object->error) && $id) + { + $object = new Product($db); + $result=$object->fetch($id); + if ($result <= 0) dol_print_error('',$object->error); + } + $objcanvas->assign_values($action, $object->id, $object->ref); // Set value for templates + $objcanvas->display_canvas($action); // Show template } else { diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index 7274c51cf9f..ceef3ec324e 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -531,8 +531,8 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) $result=$object->fetch($socid); if ($result <= 0) dol_print_error('',$object->error); } - $objcanvas->assign_values($action, $socid); // Set value for templates - $objcanvas->display_canvas($action); // Show template + $objcanvas->assign_values($action, $object->id, $object->ref); // Set value for templates + $objcanvas->display_canvas($action); // Show template } else { From e79d0f50d03833656af8af62cea493dcb4a374ce Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 00:08:55 +0200 Subject: [PATCH 09/44] Fix: Regression --- htdocs/core/class/commonobject.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index e4972596d22..ea60874d2ca 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1420,7 +1420,7 @@ abstract class CommonObject dol_syslog(get_class($this)."::update_note_private sql=".$sql, LOG_DEBUG); if ($this->db->query($sql)) { - $this->note_private = $note; + $this->note_private = $note_private; return 1; } else @@ -1430,7 +1430,7 @@ abstract class CommonObject return -1; } } - + /** * Update private note of element * @@ -1444,11 +1444,11 @@ abstract class CommonObject dol_syslog(get_class($this)."::update_note was called on objet with property table_element not defined", LOG_ERR); return -1; } - + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; $sql.= " SET note = ".(!empty($note)?("'".$this->db->escape($note)."'"):"NULL"); $sql.= " WHERE rowid =". $this->id; - + dol_syslog(get_class($this)."::update_note sql=".$sql, LOG_DEBUG); if ($this->db->query($sql)) { From 7f6fa0bf0f403b6606eade739ebb556c5dd06c68 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 10:40:35 +0200 Subject: [PATCH 10/44] Fix: Enhance detection of html --- htdocs/core/lib/functions.lib.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 04c92c8be0d..38a65fc54ac 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -3544,16 +3544,17 @@ function dol_textishtml($msg,$option=0) { if (preg_match('//i',$msg)) return true; elseif (preg_match('/
/i',$msg)) return true; elseif (preg_match('//i',$msg)) return true; - elseif (preg_match('//i',$msg)) return true; + elseif (preg_match('/
  • Date: Wed, 10 Apr 2013 10:40:59 +0200 Subject: [PATCH 11/44] Fix: syntax error --- htdocs/install/mysql/migration/3.3.0-3.4.0.sql | 6 +++--- htdocs/install/mysql/tables/llx_printer_ipp.sql | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index 45d28802558..42cd9a10f08 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -214,16 +214,16 @@ ALTER TABLE llx_product_price ADD COLUMN import_key varchar(14) AFTER price_by_q DROP TABLE llx_printer_ipp; CREATE TABLE llx_printer_ipp ( - rowid int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, datec datetime, printer_name text NOT NULL, printer_location text NOT NULL, printer_uri varchar(256) NOT NULL, - copy int(11) NOT NULL DEFAULT '1', + copy integer NOT NULL DEFAULT '1', module varchar(16) NOT NULL, login varchar(32) NOT NULL -)ENGINE=innodb; +) ENGINE=innodb; ALTER TABLE llx_socpeople ADD COLUMN ref_ext varchar(128) after entity; diff --git a/htdocs/install/mysql/tables/llx_printer_ipp.sql b/htdocs/install/mysql/tables/llx_printer_ipp.sql index cb898432fe5..19aa1c4d127 100644 --- a/htdocs/install/mysql/tables/llx_printer_ipp.sql +++ b/htdocs/install/mysql/tables/llx_printer_ipp.sql @@ -18,7 +18,7 @@ CREATE TABLE llx_printer_ipp ( - rowid integer NOT NULL AUTO_INCREMENT PRIMARY KEY, + rowid integer AUTO_INCREMENT PRIMARY KEY, tms timestamp, datec datetime, printer_name text NOT NULL, From b496436fe3023fd5137684966787a40bdc31a917 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 10:58:38 +0200 Subject: [PATCH 12/44] Qual: Reduce number of methods. Mutualize update_note code. --- htdocs/adherents/note.php | 2 +- htdocs/adherents/type.php | 2 +- htdocs/categories/class/categorie.class.php | 39 +---------- htdocs/comm/propal.php | 4 +- htdocs/comm/propal/note.php | 4 +- htdocs/commande/fiche.php | 2 +- htdocs/commande/note.php | 4 +- htdocs/compta/deplacement/fiche.php | 4 +- htdocs/compta/facture.php | 4 +- htdocs/compta/facture/note.php | 4 +- htdocs/contrat/fiche.php | 4 +- htdocs/contrat/note.php | 4 +- htdocs/core/class/commonobject.class.php | 78 ++++----------------- htdocs/expedition/note.php | 4 +- htdocs/fichinter/fiche.php | 2 +- htdocs/fichinter/note.php | 4 +- htdocs/fourn/commande/fiche.php | 4 +- htdocs/fourn/commande/note.php | 2 +- htdocs/fourn/facture/fiche.php | 4 +- htdocs/fourn/facture/note.php | 4 +- htdocs/projet/class/project.class.php | 2 +- htdocs/projet/class/task.class.php | 2 +- htdocs/projet/note.php | 2 +- htdocs/projet/tasks/note.php | 2 +- htdocs/societe/note.php | 4 +- test/phpunit/CategorieTest.php | 4 -- 26 files changed, 52 insertions(+), 143 deletions(-) diff --git a/htdocs/adherents/note.php b/htdocs/adherents/note.php index c021ab5a373..d92447434d4 100644 --- a/htdocs/adherents/note.php +++ b/htdocs/adherents/note.php @@ -54,7 +54,7 @@ if ($action == 'update' && $user->rights->adherent->creer && ! $_POST["cancel"]) { $db->begin(); - $res=$object->update_note($_POST["note"],$user); + $res=$object->update_note(dol_html_entity_decode(GETPOST('note'), ENT_QUOTES)); if ($res < 0) { setEventMessage($object->error, 'errors'); diff --git a/htdocs/adherents/type.php b/htdocs/adherents/type.php index deb32ce29d0..2120d2d2a83 100644 --- a/htdocs/adherents/type.php +++ b/htdocs/adherents/type.php @@ -146,7 +146,7 @@ if ($action == 'commentaire' && $user->rights->adherent->configurer) { $don = new Don($db); $don->fetch($rowid); - $don->update_note($_POST["commentaire"]); + $don->update_note(dol_html_entity_decode(GETPOST('commentaire'), ENT_QUOTES)); } diff --git a/htdocs/categories/class/categorie.class.php b/htdocs/categories/class/categorie.class.php index c2c249f5e41..96c111f2dc0 100644 --- a/htdocs/categories/class/categorie.class.php +++ b/htdocs/categories/class/categorie.class.php @@ -477,7 +477,7 @@ class Categorie /** - * Retourne les filles de la categorie + * Return childs of a category * * @return void */ @@ -507,43 +507,6 @@ class Categorie } - /** - * Return category description - * - * @param int $cate Category id - * @return string Description - * @deprecated function not used ? - */ - function get_desc($cate) - { - $sql = "SELECT description FROM ".MAIN_DB_PREFIX."categorie"; - $sql.= " WHERE rowid = ".$cate; - - $res = $this->db->query($sql); - $n = $this->db->fetch_array($res); - - return($n[0]); - } - - /** - * La categorie $fille est-elle une fille de cette categorie ? - * - * @param Category $child Object category - * @return void - * @deprecated function not used ? - */ - function is_fille($child) - { - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."categorie"; - $sql.= " WHERE fk_parent = ".$this->id." AND rowid = ".$child->id; - - $res = $this->db->query($sql); - $n = $this->db->fetch_array($res); - - return ($n[0] > 0); - } - - /** * Load this->motherof that is array(id_son=>id_parent, ...) * diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index b27609b6b28..9c77da67765 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -234,13 +234,13 @@ else if ($action == 'set_ref_client' && $user->rights->propal->creer) else if ($action == 'setnote_public' && $user->rights->propal->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->propal->creer) { - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/comm/propal/note.php b/htdocs/comm/propal/note.php index 663530a92c9..09670340b89 100644 --- a/htdocs/comm/propal/note.php +++ b/htdocs/comm/propal/note.php @@ -51,14 +51,14 @@ $object = new Propal($db); if ($action == 'setnote_public' && $user->rights->propale->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->propale->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php index af01fcd87c0..ce25c5cab31 100644 --- a/htdocs/commande/fiche.php +++ b/htdocs/commande/fiche.php @@ -535,7 +535,7 @@ else if ($action == 'setremiseabsolue' && $user->rights->commande->creer) else if ($action == 'setnote_public' && $user->rights->commande->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/commande/note.php b/htdocs/commande/note.php index 29078518237..c9ca34854b7 100644 --- a/htdocs/commande/note.php +++ b/htdocs/commande/note.php @@ -58,14 +58,14 @@ if (! $object->fetch($id, $ref) > 0) if ($action == 'setnote_public' && $user->rights->commande->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->commande->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/compta/deplacement/fiche.php b/htdocs/compta/deplacement/fiche.php index c7a7c6b7a2e..b09754c2405 100644 --- a/htdocs/compta/deplacement/fiche.php +++ b/htdocs/compta/deplacement/fiche.php @@ -235,13 +235,13 @@ else if ($action == 'setkm' && $user->rights->deplacement->creer) else if ($action == 'setnote_public' && $user->rights->deplacement->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db, $object->error); } else if ($action == 'setnote_private' && $user->rights->deplacement->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db, $object->error); } diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index 7248e124b46..4c85064e427 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -353,14 +353,14 @@ else if ($action == 'set_ref_client' && $user->rights->facture->creer) else if ($action == 'setnote_public' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/compta/facture/note.php b/htdocs/compta/facture/note.php index 484dff7020f..6092ba39e85 100644 --- a/htdocs/compta/facture/note.php +++ b/htdocs/compta/facture/note.php @@ -53,14 +53,14 @@ $object->fetch($id); if ($action == 'setnote_public' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/contrat/fiche.php b/htdocs/contrat/fiche.php index 368971e6ea4..d3ef925158b 100644 --- a/htdocs/contrat/fiche.php +++ b/htdocs/contrat/fiche.php @@ -658,13 +658,13 @@ else if ($action == 'confirm_move' && $confirm == 'yes' && $user->rights->contra else if ($action == 'setnote_public' && $user->rights->contrat->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->contrat->creer) { - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/contrat/note.php b/htdocs/contrat/note.php index cf347cf2973..ee66e4583f7 100644 --- a/htdocs/contrat/note.php +++ b/htdocs/contrat/note.php @@ -50,13 +50,13 @@ $object->fetch($id,$ref); if ($action == 'setnote_public' && $user->rights->contrat->creer) { - $result=$object->update_note_public(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_public')), ENT_QUOTES),'_pubic'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->contrat->creer) { - $result=$object->update_note_private(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_private')), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(dol_htmlcleanlastbr(GETPOST('note_private')), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index ea60874d2ca..b5d49b77dea 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1400,44 +1400,13 @@ abstract class CommonObject } /** - * Update private note of element + * Update note of element * - * @param string $note_private New value for note - * @return int <0 if KO, >0 if OK + * @param string $note New value for note + * @param string $suffix '', '_public' or '_private' + * @return int <0 if KO, >0 if OK */ - function update_note_private($note_private) - { - if (! $this->table_element) - { - dol_syslog(get_class($this)."::update_note_private was called on objet with property table_element not defined", LOG_ERR); - return -1; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET note_private = ".(!empty($note_private)?("'".$this->db->escape($note_private)."'"):"NULL"); - $sql.= " WHERE rowid =". $this->id; - - dol_syslog(get_class($this)."::update_note_private sql=".$sql, LOG_DEBUG); - if ($this->db->query($sql)) - { - $this->note_private = $note_private; - return 1; - } - else - { - $this->error=$this->db->error(); - dol_syslog(get_class($this)."::update_note_private error=".$this->error, LOG_ERR); - return -1; - } - } - - /** - * Update private note of element - * - * @param string $note New value for note - * @return int <0 if KO, >0 if OK - */ - function update_note($note) + function update_note($note,$suffix='') { if (! $this->table_element) { @@ -1446,7 +1415,7 @@ abstract class CommonObject } $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET note = ".(!empty($note)?("'".$this->db->escape($note)."'"):"NULL"); + $sql.= " SET note".$suffix." = ".(!empty($note)?("'".$this->db->escape($note)."'"):"NULL"); $sql.= " WHERE rowid =". $this->id; dol_syslog(get_class($this)."::update_note sql=".$sql, LOG_DEBUG); @@ -1464,36 +1433,17 @@ abstract class CommonObject } /** - * Update public note of element - * - * @param string $note_public New value for note - * @return int <0 if KO, >0 if OK + * Update public note (kept for backward compatibility) + * + * @param string $note New value for note + * @return int <0 if KO, >0 if OK + * @deprecated */ - function update_note_public($note_public) + function update_note_public($note) { - if (! $this->table_element) - { - dol_syslog(get_class($this)."::update_note_public was called on objet with property table_element not defined",LOG_ERR); - return -1; - } - - $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET note_public = ".(!empty($note_public)?("'".$this->db->escape($note_public)."'"):"NULL"); - $sql.= " WHERE rowid =". $this->id; - - dol_syslog(get_class($this)."::update_note_public sql=".$sql); - if ($this->db->query($sql)) - { - $this->note_public = $note_public; - return 1; - } - else - { - $this->error=$this->db->error(); - return -1; - } + return $this->update_note($note,'_public'); } - + /** * Update total_ht, total_ttc and total_vat for an object (sum of lines) * diff --git a/htdocs/expedition/note.php b/htdocs/expedition/note.php index 17613c72b58..2fcd18fef13 100644 --- a/htdocs/expedition/note.php +++ b/htdocs/expedition/note.php @@ -61,14 +61,14 @@ $object->fetch($id); if ($action == 'setnote_public' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->facture->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fichinter/fiche.php b/htdocs/fichinter/fiche.php index 3886edb30f9..4e8b9e2b1d8 100644 --- a/htdocs/fichinter/fiche.php +++ b/htdocs/fichinter/fiche.php @@ -380,7 +380,7 @@ else if ($action == 'setdescription' && $user->rights->ficheinter->creer) else if ($action == 'setnote_public' && $user->rights->ficheinter->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->ficheinter->creer) diff --git a/htdocs/fichinter/note.php b/htdocs/fichinter/note.php index a2de821e6c7..3b7e8b5c960 100644 --- a/htdocs/fichinter/note.php +++ b/htdocs/fichinter/note.php @@ -48,13 +48,13 @@ $object->fetch($id,$ref); if ($action == 'setnote_public' && $user->rights->ficheinter->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->ficheinter->creer) { - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fourn/commande/fiche.php b/htdocs/fourn/commande/fiche.php index 7a5128cca45..2be0c23e78b 100644 --- a/htdocs/fourn/commande/fiche.php +++ b/htdocs/fourn/commande/fiche.php @@ -140,13 +140,13 @@ else if ($action == 'setremisepercent' && $user->rights->fournisseur->commande-> else if ($action == 'setnote_public' && $user->rights->fournisseur->commande->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } else if ($action == 'setnote_private' && $user->rights->fournisseur->commande->creer) { - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fourn/commande/note.php b/htdocs/fourn/commande/note.php index 63cd69a89a0..7d4fa0cd496 100644 --- a/htdocs/fourn/commande/note.php +++ b/htdocs/fourn/commande/note.php @@ -51,7 +51,7 @@ $object->fetch($id, $ref); if ($action == 'setnote_public' && $user->rights->fournisseur->commande->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } elseif ($action == 'setnote' && $user->rights->fournisseur->commande->creer) diff --git a/htdocs/fourn/facture/fiche.php b/htdocs/fourn/facture/fiche.php index 4393023f07c..d85bd03e067 100644 --- a/htdocs/fourn/facture/fiche.php +++ b/htdocs/fourn/facture/fiche.php @@ -211,13 +211,13 @@ elseif ($action == 'setdate_lim_reglement' && $user->rights->fournisseur->factur elseif ($action == 'setnote_public' && $user->rights->fournisseur->facture->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } elseif ($action == 'setnote_private' && $user->rights->fournisseur->facture->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/fourn/facture/note.php b/htdocs/fourn/facture/note.php index 834858788e9..116d0ce1c8b 100644 --- a/htdocs/fourn/facture/note.php +++ b/htdocs/fourn/facture/note.php @@ -51,12 +51,12 @@ $object->fetch($id,$ref); if ($action == 'setnote_public' && $user->rights->fournisseur->facture->creer) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } elseif ($action == 'setnote_private' && $user->rights->fournisseur->facture->creer) { - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/projet/class/project.class.php b/htdocs/projet/class/project.class.php index d2864b08c11..b02b29eaa69 100644 --- a/htdocs/projet/class/project.class.php +++ b/htdocs/projet/class/project.class.php @@ -1011,7 +1011,7 @@ class Project extends CommonObject else { $this->db->begin(); - $res=$clone_project->update_note_public(dol_html_entity_decode($clone_project->note_public, ENT_QUOTES)); + $res=$clone_project->update_note(dol_html_entity_decode($clone_project->note_public, ENT_QUOTES),'_public'); if ($res < 0) { $this->error.=$clone_project->error; diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index f28e5d27e6d..d09647347e5 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -1027,7 +1027,7 @@ class Task extends CommonObject else { $this->db->begin(); - $res=$clone_task->update_note_public(dol_html_entity_decode($clone_task->note_public, ENT_QUOTES)); + $res=$clone_task->update_note(dol_html_entity_decode($clone_task->note_public, ENT_QUOTES),'_public'); if ($res < 0) { $this->error.=$clone_task->error; diff --git a/htdocs/projet/note.php b/htdocs/projet/note.php index e785cf778ab..26eafbc16d2 100644 --- a/htdocs/projet/note.php +++ b/htdocs/projet/note.php @@ -56,7 +56,7 @@ $result = restrictedArea($user, 'projet', $id); if ($action == 'setnote_public' && $user->rights->projet->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/projet/tasks/note.php b/htdocs/projet/tasks/note.php index 6d5f9f666e9..9931bde0510 100644 --- a/htdocs/projet/tasks/note.php +++ b/htdocs/projet/tasks/note.php @@ -87,7 +87,7 @@ $permission=($user->rights->projet->creer || $user->rights->projet->all->creer); if ($action == 'setnote_public' && ! empty($permission)) { - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) dol_print_error($db,$object->error); } diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php index 0d09f21da25..e24fa8a8cdc 100644 --- a/htdocs/societe/note.php +++ b/htdocs/societe/note.php @@ -55,14 +55,14 @@ if ($id > 0) $object->fetch($id); if ($action == 'setnote_public' && $user->rights->propale->creer) { $object->fetch($id); - $result=$object->update_note_public(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public'); if ($result < 0) setEventMessage($object->error,'errors'); } else if ($action == 'setnote_private' && $user->rights->propale->creer) { $object->fetch($id); - $result=$object->update_note_private(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES)); + $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private'); if ($result < 0) setEventMessage($object->error,'errors'); } diff --git a/test/phpunit/CategorieTest.php b/test/phpunit/CategorieTest.php index 128a52796df..501781b309d 100755 --- a/test/phpunit/CategorieTest.php +++ b/test/phpunit/CategorieTest.php @@ -276,10 +276,6 @@ class CategorieTest extends PHPUnit_Framework_TestCase print __METHOD__." retarray size=".count($retarray)."\n"; $this->assertTrue(is_array($retarray)); - $retarray=$localobject->is_fille($localobject2); - print __METHOD__." retarry size=".count($retarray)."\n"; - $this->assertFalse($retarray); - return $localobject->id; } From bc1469ff29b7deb70c4d9fc503f84e609d207e16 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 11:03:24 +0200 Subject: [PATCH 13/44] Fix: More complete function --- htdocs/core/class/commonobject.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b5d49b77dea..e1c4be97184 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1421,12 +1421,14 @@ abstract class CommonObject dol_syslog(get_class($this)."::update_note sql=".$sql, LOG_DEBUG); if ($this->db->query($sql)) { - $this->note = $note; // deprecated + if ($suffix == '_public') $this->note_public = $note; + else if ($suffix == '_private') $this->note_private = $note; + else $this->note = $note; return 1; } else { - $this->error=$this->db->error(); + $this->error=$this->db->lasterror(); dol_syslog(get_class($this)."::update_note error=".$this->error, LOG_ERR); return -1; } From 2c51b51a88a8eb50aef84482a6c4c254bfb27fca Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 10 Apr 2013 11:55:15 +0200 Subject: [PATCH 14/44] Fix: security --- htdocs/core/modules/mailings/contacts2.modules.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/mailings/contacts2.modules.php b/htdocs/core/modules/mailings/contacts2.modules.php index 955a126912b..e1c1d3afcfe 100755 --- a/htdocs/core/modules/mailings/contacts2.modules.php +++ b/htdocs/core/modules/mailings/contacts2.modules.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2011 François Cerbelle + * Copyright (C) 2013 Regis Houssin * * 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 @@ -87,7 +88,7 @@ class mailing_contacts2 extends MailingTargets $sql.= " AND sp.no_email = 0"; //$sql.= " AND sp.poste != ''"; $sql.= " AND sp.entity IN (".getEntity('societe', 1).")"; - if ($filtersarray[0]<>'all') $sql.= " AND sp.poste ='".$filtersarray[0]."'"; + if ($filtersarray[0]<>'all') $sql.= " AND sp.poste ='".$this->db->escape($filtersarray[0])."'"; $sql.= " ORDER BY sp.lastname, sp.firstname"; $resql = $this->db->query($sql); if ($resql) From ba93a4bfe286ca814084d5482dd7a9a3c91dbf8d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 12:20:45 +0200 Subject: [PATCH 15/44] Fix: Codesniffer --- dev/phpcheckstyle/README | 21 -- dev/phpcheckstyle/phpstandard.cfg.xml | 316 ------------------ dev/phpcheckstyle/phpstandard.dtd | 13 - htdocs/commande/class/commande.class.php | 1 - .../thirdparties_services_expired.modules.php | 5 +- .../fourn/class/fournisseur.product.class.php | 1 + htdocs/opensurvey/adminstuds_preview.php | 6 +- .../class/opensurveysondage.class.php | 2 +- htdocs/opensurvey/fonctions.php | 17 +- htdocs/opensurvey/public/choix_date.php | 8 +- htdocs/opensurvey/public/create_survey.php | 2 +- htdocs/opensurvey/public/exportcsv.php | 11 +- htdocs/public/paybox/paymentko.php | 6 +- htdocs/public/paybox/paymentok.php | 2 +- htdocs/public/paypal/paymentko.php | 2 +- htdocs/public/paypal/paymentok.php | 2 +- test/phpunit/WebservicesInvoicesTest.php | 4 +- test/phpunit/WebservicesOrdersTest.php | 8 +- test/phpunit/WebservicesOtherTest.php | 4 +- test/phpunit/WebservicesThirdpartyTest.php | 4 +- test/phpunit/WebservicesUserTest.php | 4 +- 21 files changed, 45 insertions(+), 394 deletions(-) delete mode 100644 dev/phpcheckstyle/README delete mode 100644 dev/phpcheckstyle/phpstandard.cfg.xml delete mode 100644 dev/phpcheckstyle/phpstandard.dtd diff --git a/dev/phpcheckstyle/README b/dev/phpcheckstyle/README deleted file mode 100644 index 84c6b1bbdc8..00000000000 --- a/dev/phpcheckstyle/README +++ /dev/null @@ -1,21 +0,0 @@ -README (English) --------------------------------- - -This directory contains example of PHPCheckStyle configuration -to use for quality assurance on PHP developpement. - -To run PHPCheckstyle in eclipse, you must: -- install plugin PHP Tools integration http://www.phpsrc.org/eclipse/pti/ -- Unzip PHPCheckStyle archive into a directory. -- Go in Eclipse - Window - Preferences - Dynamic Languages - Validator -Choose External PHP Script, -Set path ro run.php file for localhost -Choose a PHP version, -Set parameter string with - --src %f --config "phpstandard.cfg.xml" --format console -Choose php as Filename extension -Check Print PHP output to console -Then add patern - * %f INFO Line:%n - %m Warning - * %f WARNING Line:%n - %m Warning - * %f ERROR Line:%n - %m Error \ No newline at end of file diff --git a/dev/phpcheckstyle/phpstandard.cfg.xml b/dev/phpcheckstyle/phpstandard.cfg.xml deleted file mode 100644 index 3dd3b314660..00000000000 --- a/dev/phpcheckstyle/phpstandard.cfg.xml +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/dev/phpcheckstyle/phpstandard.dtd b/dev/phpcheckstyle/phpstandard.dtd deleted file mode 100644 index bde6e6b2b52..00000000000 --- a/dev/phpcheckstyle/phpstandard.dtd +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 0270b0327dd..b6e11a64065 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -2783,7 +2783,6 @@ class Commande extends CommonOrder * Update value of extrafields on the proposal * * @param User $user Object user that modify - * @param double $remise Amount discount * @return int <0 if ko, >0 if ok */ function update_extrafields($user) diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php index 4b621b705a2..b9d8feccd5c 100755 --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php @@ -175,11 +175,10 @@ class mailing_thirdparties_services_expired extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param int $filter Filter - * @param string $option Option + * @param string $sql Request * @return int Number of recipients */ - function getNbOfRecipients($sql,$filter=1,$option='') + function getNbOfRecipients($sql='') { $now=dol_now(); diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 09843191692..9a86f0e9ee3 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -146,6 +146,7 @@ class ProductFournisseur extends Product * @param string $charges costs affering to product * @param float $remise_percent Discount regarding qty (percent) * @param float $remise Discount regarding qty (amount) + * @param int $newnpr Set NPR or not * @return int <0 if KO, >=0 if OK */ function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0) diff --git a/htdocs/opensurvey/adminstuds_preview.php b/htdocs/opensurvey/adminstuds_preview.php index 7e7bb6a6967..54a44d40abb 100755 --- a/htdocs/opensurvey/adminstuds_preview.php +++ b/htdocs/opensurvey/adminstuds_preview.php @@ -202,7 +202,7 @@ if (isset($_POST["ajoutercolonne"]) && ($object->format == "D" || $object->forma //on rajoute la valeur dans les valeurs $datesbase = explode(",",$object->sujet); - $taillebase = sizeof($datesbase); + $taillebase = count($datesbase); //recherche de l'endroit de l'insertion de la nouvelle date dans les dates deja entrées dans le tableau if ($nouvelledate < $datesbase[0]) { @@ -210,7 +210,9 @@ if (isset($_POST["ajoutercolonne"]) && ($object->format == "D" || $object->forma } elseif ($nouvelledate > $datesbase[$taillebase-1]) { $cleinsertion = count($datesbase); } else { - for ($i = 0; $i < count($datesbase); $i++) { + $nbdatesbase=count($datesbase); + for ($i = 0; $i < $nbdatesbase; $i++) + { $j = $i + 1; if ($nouvelledate > $datesbase[$i] && $nouvelledate < $datesbase[$j]) { $cleinsertion = $j; diff --git a/htdocs/opensurvey/class/opensurveysondage.class.php b/htdocs/opensurvey/class/opensurveysondage.class.php index 7cdfd1e4c7e..0a3f2c571df 100644 --- a/htdocs/opensurvey/class/opensurveysondage.class.php +++ b/htdocs/opensurvey/class/opensurveysondage.class.php @@ -340,7 +340,7 @@ class Opensurveysondage extends CommonObject * @param string $numsondageadmin Num sondage to delete * @return int <0 if KO, >0 if OK */ - function delete($user, $notrigger=0, $numsondageadmin) + function delete($user, $notrigger, $numsondageadmin) { global $conf, $langs; $error=0; diff --git a/htdocs/opensurvey/fonctions.php b/htdocs/opensurvey/fonctions.php index 6068ca965f1..fc30da7498b 100755 --- a/htdocs/opensurvey/fonctions.php +++ b/htdocs/opensurvey/fonctions.php @@ -120,8 +120,8 @@ function get_server_name() /** * is_error * - * @param unknown_type $cerr - * @return boolean + * @param string $cerr Error value + * @return boolean Error key found or not */ function is_error($cerr) { @@ -147,7 +147,7 @@ function validateEmail($email) { $pattern = '/^(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){255,})(?!(?:(?:\\x22?\\x5C[\\x00-\\x7E]\\x22?)|(?:\\x22?[^\\x5C\\x22]\\x22?)){65,}@)(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22))(?:\\.(?:(?:[\\x21\\x23-\\x27\\x2A\\x2B\\x2D\\x2F-\\x39\\x3D\\x3F\\x5E-\\x7E]+)|(?:\\x22(?:[\\x01-\\x08\\x0B\\x0C\\x0E-\\x1F\\x21\\x23-\\x5B\\x5D-\\x7F]|(?:\\x5C[\\x00-\\x7F]))*\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-[a-z0-9]+)*)|(?:\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\]))$/iD'; - return (bool)preg_match($pattern, $email); + return (bool) preg_match($pattern, $email); } @@ -188,15 +188,16 @@ function getUrlSondage($id, $admin = false) /** - * Generate a random id - * - * @return void + * Generate a random id + * + * @param string $car Char to generate key + * @return void */ function dol_survey_random($car) { $string = ""; $chaine = "abcdefghijklmnopqrstuvwxyz123456789"; - srand((double)microtime()*1000000); + srand((double) microtime()*1000000); for($i=0; $i<$car; $i++) { $string .= $chaine[rand()%strlen($chaine)]; } @@ -229,7 +230,7 @@ function ajouter_sondage($origin) if ($_SESSION["formatsondage"]=="D"||$_SESSION["formatsondage"]=="D+") { //Calcul de la date de fin du sondage - $taille_tableau=sizeof($_SESSION["totalchoixjour"])-1; + $taille_tableau=count($_SESSION["totalchoixjour"])-1; $date_fin=$_SESSION["totalchoixjour"][$taille_tableau]+200000; } diff --git a/htdocs/opensurvey/public/choix_date.php b/htdocs/opensurvey/public/choix_date.php index 72a24357436..59536f1f8e6 100755 --- a/htdocs/opensurvey/public/choix_date.php +++ b/htdocs/opensurvey/public/choix_date.php @@ -257,9 +257,9 @@ if (issetAndNoEmpty('choixjourajout')) { // Si le test est passé, alors on insere la valeur dans la variable de session qui contient les dates if ($journeuf && issetAndNoEmpty('choixjourajout') === true) { - array_push ($_SESSION["totalchoixjour"],mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"])); - sort ($_SESSION["totalchoixjour"]); - $cle=array_search (mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"]), $_SESSION["totalchoixjour"]); + array_push($_SESSION["totalchoixjour"], dol_mktime(0, 0, 0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"])); + sort($_SESSION["totalchoixjour"]); + $cle=array_search(dol_mktime(0, 0, 0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"]), $_SESSION["totalchoixjour"]); //On sauvegarde les heures deja entrées for ($i = 0; $i < $cle; $i++) { @@ -540,7 +540,7 @@ if (issetAndNoEmpty('totalchoixjour', $_SESSION) && (!issetAndNoEmpty('choixheur //s'il n'y a pas d'erreur et que le bouton de creation est activé, on demande confirmation if (!$erreur && (GETPOST('choixheures') || GETPOST('choixheures_x'))) { - $taille_tableau=sizeof($_SESSION["totalchoixjour"])-1; + $taille_tableau=count($_SESSION["totalchoixjour"])-1; $jour_arret = $_SESSION["totalchoixjour"][$taille_tableau]+200000; $date_fin=dol_print_date($jour_arret, 'dayhourtext'); diff --git a/htdocs/opensurvey/public/create_survey.php b/htdocs/opensurvey/public/create_survey.php index c5af8db0cab..729255a6ca1 100755 --- a/htdocs/opensurvey/public/create_survey.php +++ b/htdocs/opensurvey/public/create_survey.php @@ -162,7 +162,7 @@ print ''."\n"; print '
    '."\n"; -#affichage du cochage par défaut +// Check or not $cocheplus=''; if ($_SESSION["canedit"]) $cocheplus="checked"; diff --git a/htdocs/opensurvey/public/exportcsv.php b/htdocs/opensurvey/public/exportcsv.php index b2ee0cc1eea..f933b37a317 100755 --- a/htdocs/opensurvey/public/exportcsv.php +++ b/htdocs/opensurvey/public/exportcsv.php @@ -64,7 +64,6 @@ $now=dol_now(); $nbcolonnes=substr_count($object->sujet,',')+1; $toutsujet=explode(",",$object->sujet); -#$toutsujet=str_replace("°","'",$toutsujet); // affichage des sujets du sondage $input.=$langs->trans("Name").";"; @@ -139,15 +138,15 @@ if ($resql) else dol_print_error($db); -$filesize = strlen( $input ); +$filesize = strlen($input); $filename=$numsondage."_".dol_print_date($now,'%Y%m%d%H%M').".csv"; -header( 'Content-Type: text/csv; charset=utf-8' ); -header( 'Content-Length: '.$filesize ); -header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); -header( 'Cache-Control: max-age=10' ); +header('Content-Type: text/csv; charset=utf-8'); +header('Content-Length: '.$filesize); +header('Content-Disposition: attachment; filename="'.$filename.'"'); +header('Cache-Control: max-age=10'); echo $input; exit; diff --git a/htdocs/public/paybox/paymentko.php b/htdocs/public/paybox/paymentko.php index 4db0684005b..19ce36b3b43 100644 --- a/htdocs/public/paybox/paymentko.php +++ b/htdocs/public/paybox/paymentko.php @@ -69,13 +69,13 @@ if (! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL) && preg_match('/MEM=',$fu $sendto=$conf->global->MEMBER_PAYONLINE_SENDEMAIL; $from=$conf->global->MAILING_EMAIL_FROM; require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile( + $mailfile = new CMailFile( 'New subscription payed', $sendto, $from, 'New subscription payed '.$fulltag - ); - + ); + $result=$mailfile->sendfile(); if ($result) { diff --git a/htdocs/public/paybox/paymentok.php b/htdocs/public/paybox/paymentok.php index ebd3c834d09..e206556eea1 100644 --- a/htdocs/public/paybox/paymentok.php +++ b/htdocs/public/paybox/paymentok.php @@ -99,7 +99,7 @@ if (! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL) && preg_match('/MEM=',$fu $sendto=$conf->global->MEMBER_PAYONLINE_SENDEMAIL; $from=$conf->global->MAILING_EMAIL_FROM; require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile( + $mailfile = new CMailFile( 'New subscription payed', $sendto, $from, diff --git a/htdocs/public/paypal/paymentko.php b/htdocs/public/paypal/paymentko.php index c6fe53ac7b0..a291125253f 100755 --- a/htdocs/public/paypal/paymentko.php +++ b/htdocs/public/paypal/paymentko.php @@ -77,7 +77,7 @@ if (! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL) && preg_match('/MEM=',$fu $sendto=$conf->global->MEMBER_PAYONLINE_SENDEMAIL; $from=$conf->global->MAILING_EMAIL_FROM; require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile( + $mailfile = new CMailFile( 'New subscription payed', $sendto, $from, diff --git a/htdocs/public/paypal/paymentok.php b/htdocs/public/paypal/paymentok.php index ca11bcb5422..1241e66b6c8 100755 --- a/htdocs/public/paypal/paymentok.php +++ b/htdocs/public/paypal/paymentok.php @@ -136,7 +136,7 @@ if ($PAYPALTOKEN) $sendto=$conf->global->MEMBER_PAYONLINE_SENDEMAIL; $from=$conf->global->MAILING_EMAIL_FROM; require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; - $mailfile = new CMailFile( + $mailfile = new CMailFile( 'New subscription payed', $sendto, $from, diff --git a/test/phpunit/WebservicesInvoicesTest.php b/test/phpunit/WebservicesInvoicesTest.php index 65983390cfd..6f04f5320e2 100755 --- a/test/phpunit/WebservicesInvoicesTest.php +++ b/test/phpunit/WebservicesInvoicesTest.php @@ -118,11 +118,11 @@ class WebservicesInvoicesTest extends PHPUnit_Framework_TestCase /** - * testWSInvoices_xxx + * testWSInvoicesXxx * * @return int */ - public function testWSInvoices_xxx() + public function testWSInvoicesXxx() { global $conf,$user,$langs,$db; $conf=$this->savconf; diff --git a/test/phpunit/WebservicesOrdersTest.php b/test/phpunit/WebservicesOrdersTest.php index a4571557a48..750c33fa30a 100755 --- a/test/phpunit/WebservicesOrdersTest.php +++ b/test/phpunit/WebservicesOrdersTest.php @@ -118,11 +118,11 @@ class WebservicesOrdersTest extends PHPUnit_Framework_TestCase /** - * testWSOrder_xxx + * testWSOrderXxx * * @return int */ - public function testWSOrder_xxx() + public function testWSOrderXxx() { global $conf,$user,$langs,$db; $conf=$this->savconf; @@ -178,11 +178,11 @@ class WebservicesOrdersTest extends PHPUnit_Framework_TestCase /** - * testWSOther_GetVersions + * testWSOtherGetVersions * * @return int */ - public function testWSOther_GetVersions() + public function testWSOtherGetVersions() { global $conf,$user,$langs,$db; $conf=$this->savconf; diff --git a/test/phpunit/WebservicesOtherTest.php b/test/phpunit/WebservicesOtherTest.php index e06477e7de9..e8a8a6bd19c 100755 --- a/test/phpunit/WebservicesOtherTest.php +++ b/test/phpunit/WebservicesOtherTest.php @@ -118,11 +118,11 @@ class WebservicesOtherTest extends PHPUnit_Framework_TestCase /** - * testWSOther_GetVersions + * testWSOtherGetVersions * * @return int */ - public function testWSOther_GetVersions() + public function testWSOtherGetVersions() { global $conf,$user,$langs,$db; $conf=$this->savconf; diff --git a/test/phpunit/WebservicesThirdpartyTest.php b/test/phpunit/WebservicesThirdpartyTest.php index b28ac8fa2d8..83c7c0ce14d 100755 --- a/test/phpunit/WebservicesThirdpartyTest.php +++ b/test/phpunit/WebservicesThirdpartyTest.php @@ -118,11 +118,11 @@ class WebservicesThirdpartyTest extends PHPUnit_Framework_TestCase /** - * testWSThirdparty_xxx + * testWSThirdpartyXxx * * @return int */ - public function testWSThirdparty_xxx() + public function testWSThirdpartyXxx() { global $conf,$user,$langs,$db; $conf=$this->savconf; diff --git a/test/phpunit/WebservicesUserTest.php b/test/phpunit/WebservicesUserTest.php index 9ef2278015b..832fd1ea4cb 100755 --- a/test/phpunit/WebservicesUserTest.php +++ b/test/phpunit/WebservicesUserTest.php @@ -118,11 +118,11 @@ class WebservicesUserTest extends PHPUnit_Framework_TestCase /** - * testWSUser_xxx + * testWSUserXxx * * @return int */ - public function testWSUser_xxx() + public function testWSUserXxx() { global $conf,$user,$langs,$db; $conf=$this->savconf; From 72aec6aa6084c876d582f4edcd483adc0af0cd44 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 13:30:54 +0200 Subject: [PATCH 16/44] Better translation --- htdocs/langs/en_US/mails.lang | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index f143a7fa167..3cbce8ff4b2 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -82,16 +82,16 @@ ActivateCheckReadKey=Key use to encrypt URL use for "Read Receipt" and "Unsubcri EMailSentToNRecipients=EMail sent to %s recipients. # Libelle des modules de liste de destinataires mailing -MailingModuleDescContactCompanies=Contacts of all third parties (customer, prospect, supplier, ...) +MailingModuleDescContactCompanies=Contacts/addresses of all third parties (customer, prospect, supplier, ...) MailingModuleDescDolibarrUsers=Dolibarr users MailingModuleDescFundationMembers=Foundation members with emails MailingModuleDescEmailsFromFile=EMails from a text file (email;lastname;firstname;other) MailingModuleDescEmailsFromUser=EMails from user input (email;lastname;firstname;other) MailingModuleDescContactsCategories=Third parties (by category) MailingModuleDescDolibarrContractsLinesExpired=Third parties with expired contract's lines -MailingModuleDescContactsByCompanyCategory=Contacts of third parties (by third parties category) +MailingModuleDescContactsByCompanyCategory=Contacts/addresses of third parties (by third parties category) MailingModuleDescMembersCategories=Foundation members (by categories) -MailingModuleDescContactsByFunction=Contacts of third parties (by position/function) +MailingModuleDescContactsByFunction=Contacts/addresses of third parties (by position/function) LineInFile=Line %s in file From b152e587930d7d5d5f6750b04af270b58bc1c1c2 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 10 Apr 2013 15:42:21 +0200 Subject: [PATCH 17/44] Fix: change for experimental encyption --- .../install/mysql/migration/3.3.0-3.4.0.sql | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index 42cd9a10f08..bd1bd8693ce 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -26,18 +26,18 @@ create table llx_adherent_type_extrafields ) ENGINE=innodb; ALTER TABLE llx_adherent_type_extrafields ADD INDEX idx_adherent_type_extrafields (fk_object); -UPDATE llx_const set value='eldy_menu.php' where value='eldy_backoffice.php'; -UPDATE llx_const set value='eldy_menu.php' where value='eldy_frontoffice.php'; -UPDATE llx_const set value='auguria_menu.php' where value='auguria_backoffice.php'; -UPDATE llx_const set value='auguria_menu.php' where value='auguria_frontoffice.php'; -UPDATE llx_const set value='smartphone_menu.php' where value='smartphone_backoffice.php'; -UPDATE llx_const set value='smartphone_menu.php' where value='smartphone_frontoffice.php'; -UPDATE llx_const set name='MAIN_INFO_SOCIETE_ADDRESS' where name='MAIN_INFO_SOCIETE_ADRESSE'; -UPDATE llx_const set name='MAIN_INFO_SOCIETE_TOWN' where name='MAIN_INFO_SOCIETE_VILLE'; -UPDATE llx_const set name='MAIN_INFO_SOCIETE_ZIP' where name='MAIN_INFO_SOCIETE_CP'; -UPDATE llx_const set name='MAIN_INFO_SOCIETE_COUNTRY' where name='MAIN_INFO_SOCIETE_PAYS'; -UPDATE llx_const set name='MAIN_INFO_SOCIETE_STATE' where name='MAIN_INFO_SOCIETE_DEPARTEMENT'; -UPDATE llx_const set name='LIVRAISON_ADDON_NUMBER' where name='LIVRAISON_ADDON'; +UPDATE llx_const set value = __ENCRYPT('eldy_menu.php')__ where __DECRYPT('value')__ = 'eldy_backoffice.php'; +UPDATE llx_const set value = __ENCRYPT('eldy_menu.php')__ where __DECRYPT('value')__ = 'eldy_frontoffice.php'; +UPDATE llx_const set value = __ENCRYPT('auguria_menu.php')__ where __DECRYPT('value')__ = 'auguria_backoffice.php'; +UPDATE llx_const set value = __ENCRYPT('auguria_menu.php')__ where __DECRYPT('value')__ = 'auguria_frontoffice.php'; +UPDATE llx_const set value = __ENCRYPT('smartphone_menu.php')__ where __DECRYPT('value')__ = 'smartphone_backoffice.php'; +UPDATE llx_const set value = __ENCRYPT('smartphone_menu.php')__ where __DECRYPT('value')__ = 'smartphone_frontoffice.php'; +UPDATE llx_const set name = __ENCRYPT('MAIN_INFO_SOCIETE_ADDRESS')__ where __DECRYPT('name')__ = 'MAIN_INFO_SOCIETE_ADRESSE'; +UPDATE llx_const set name = __ENCRYPT('MAIN_INFO_SOCIETE_TOWN')__ where __DECRYPT('name')__ = 'MAIN_INFO_SOCIETE_VILLE'; +UPDATE llx_const set name = __ENCRYPT('MAIN_INFO_SOCIETE_ZIP')__ where __DECRYPT('name')__ = 'MAIN_INFO_SOCIETE_CP'; +UPDATE llx_const set name = __ENCRYPT('MAIN_INFO_SOCIETE_COUNTRY')__ where __DECRYPT('name')__ = 'MAIN_INFO_SOCIETE_PAYS'; +UPDATE llx_const set name = __ENCRYPT('MAIN_INFO_SOCIETE_STATE')__ where __DECRYPT('name')__ = 'MAIN_INFO_SOCIETE_DEPARTEMENT'; +UPDATE llx_const set name = __ENCRYPT('LIVRAISON_ADDON_NUMBER')__ where __DECRYPT('name')__ = 'LIVRAISON_ADDON'; ALTER TABLE llx_user add COLUMN fk_user integer; From 6739ac4d94f8ef4fe607721c76bd9912fc004147 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 15:53:40 +0200 Subject: [PATCH 18/44] Fix: Restore backward compatibility --- htdocs/contact/class/contact.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 65c0407cb97..a41aaf6b366 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -541,6 +541,7 @@ class Contact extends CommonObject $this->mail = $obj->email; $this->birthday = $this->db->jdate($obj->birthday); + $this->note = $obj->note_private; // deprecated $this->note_private = $obj->note_private; $this->note_public = $obj->note_public; $this->default_lang = $obj->default_lang; From 740bc2a656ab544d28abac7f2da61f183e9726a4 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Wed, 10 Apr 2013 15:59:54 +0200 Subject: [PATCH 19/44] Fix: filter on all contacts, not just those related to a company --- .../modules/mailings/contacts2.modules.php | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/htdocs/core/modules/mailings/contacts2.modules.php b/htdocs/core/modules/mailings/contacts2.modules.php index e1c1d3afcfe..4b7b95ecb88 100755 --- a/htdocs/core/modules/mailings/contacts2.modules.php +++ b/htdocs/core/modules/mailings/contacts2.modules.php @@ -81,13 +81,12 @@ class mailing_contacts2 extends MailingTargets $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact,"; $sql.= " sp.lastname, sp.firstname as firstname, sp.civilite,"; $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE s.rowid = sp.fk_soc"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; + $sql.= " WHERE sp.entity IN (".getEntity('societe', 1).")"; $sql.= " AND sp.email != ''"; // Note that null != '' is false $sql.= " AND sp.no_email = 0"; //$sql.= " AND sp.poste != ''"; - $sql.= " AND sp.entity IN (".getEntity('societe', 1).")"; if ($filtersarray[0]<>'all') $sql.= " AND sp.poste ='".$this->db->escape($filtersarray[0])."'"; $sql.= " ORDER BY sp.lastname, sp.firstname"; $resql = $this->db->query($sql); @@ -163,10 +162,9 @@ class mailing_contacts2 extends MailingTargets // Number with a filter are show in the combo list for each filter. // If we want a filter "a position is defined", we must add it into formFilter $sql = "SELECT count(distinct(sp.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE s.rowid = sp.fk_soc"; - $sql.= " AND sp.entity IN (".getEntity('societe', 1).")"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; + $sql.= " WHERE sp.entity IN (".getEntity('societe', 1).")"; $sql.= " AND sp.email != ''"; // Note that null != '' is false $sql.= " AND sp.no_email = 0"; //$sql.= " AND sp.poste != ''"; @@ -188,10 +186,9 @@ class mailing_contacts2 extends MailingTargets $langs->load("companies"); $sql = "SELECT sp.poste, count(distinct(sp.email)) AS nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE s.rowid = sp.fk_soc"; - $sql.= " AND sp.entity IN (".getEntity('societe', 1).")"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; + $sql.= " WHERE sp.entity IN (".getEntity('societe', 1).")"; $sql.= " AND sp.email != ''"; // Note that null != '' is false $sql.= " AND sp.no_email = 0"; $sql.= " AND (sp.poste IS NOT NULL AND sp.poste != '')"; From 4f645b0a53e68f7585fed7caa80061c9ee96bfa2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 16:08:38 +0200 Subject: [PATCH 20/44] Fix: Bad width --- htdocs/societe/note.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php index e24fa8a8cdc..fba53282d1f 100644 --- a/htdocs/societe/note.php +++ b/htdocs/societe/note.php @@ -121,11 +121,12 @@ if ($id > 0) } print ""; - + print '
    '; - + + $colwidth='20'; include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; - + dol_fiche_end(); } From 3d8c312a30208cc661465d81e8933cae5e226d4f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 16:15:35 +0200 Subject: [PATCH 21/44] Fix: Uniformize column size Fix: Use dol_prind_address for addressees --- htdocs/categories/categorie.php | 4 +++- htdocs/societe/consumption.php | 2 +- htdocs/societe/document.php | 2 +- htdocs/societe/note.php | 4 ++-- htdocs/societe/notify/fiche.php | 4 ++-- htdocs/societe/soc.php | 2 +- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/htdocs/categories/categorie.php b/htdocs/categories/categorie.php index b1532f5d7d7..ddc7079c786 100644 --- a/htdocs/categories/categorie.php +++ b/htdocs/categories/categorie.php @@ -240,7 +240,9 @@ if ($socid) } // Address - print ''.$langs->trans('Address').''.nl2br($soc->address).''; + print ''.$langs->trans('Address').''; + print dol_print_address($soc->address,'gmap','thirdparty',$object->id); + print ''; // Zip / Town print ''.$langs->trans('Zip').''.$soc->zip.""; diff --git a/htdocs/societe/consumption.php b/htdocs/societe/consumption.php index f3538c6e266..7c0a4c0332f 100644 --- a/htdocs/societe/consumption.php +++ b/htdocs/societe/consumption.php @@ -106,7 +106,7 @@ print ''; print ''; print ''; -print ''; +print ''; print ''; diff --git a/htdocs/societe/document.php b/htdocs/societe/document.php index ca5582b4dee..f9703044257 100644 --- a/htdocs/societe/document.php +++ b/htdocs/societe/document.php @@ -133,7 +133,7 @@ if ($object->id) print '
    '.$langs->trans('ThirdPartyName').'
    '.$langs->trans('ThirdPartyName').''; print $form->showrefnav($object,'socid','',($user->societe_id?0:1),'rowid','nom'); print '
    '; // Ref - print ''; + print ''; print ''; diff --git a/htdocs/societe/note.php b/htdocs/societe/note.php index fba53282d1f..8fbd6c6187f 100644 --- a/htdocs/societe/note.php +++ b/htdocs/societe/note.php @@ -92,7 +92,7 @@ if ($id > 0) print '
    '.$langs->trans("ThirdPartyName").'
    '.$langs->trans("ThirdPartyName").''; print $form->showrefnav($object,'socid','',($user->societe_id?0:1),'rowid','nom'); print '
    '; - print ''; + print ''; print ''; @@ -124,7 +124,7 @@ if ($id > 0) print '
    '; - $colwidth='20'; + $colwidth='25'; include DOL_DOCUMENT_ROOT.'/core/tpl/notes.tpl.php'; diff --git a/htdocs/societe/notify/fiche.php b/htdocs/societe/notify/fiche.php index 2499ae30a5b..a0ab078e315 100644 --- a/htdocs/societe/notify/fiche.php +++ b/htdocs/societe/notify/fiche.php @@ -141,7 +141,7 @@ if ($result > 0) print '
    '.$langs->trans('ThirdPartyName').'
    '.$langs->trans('ThirdPartyName').''; print $form->showrefnav($object,'socid','',($user->societe_id?0:1),'rowid','nom'); print '
    '; - print ''; @@ -169,7 +169,7 @@ if ($result > 0) print ''; } - print ''; + print ''; print ''; + print ''; print ''; From d7c0cf3d5033710e33aa3c1e8dcffbd1a3527667 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 16:29:53 +0200 Subject: [PATCH 22/44] Fix: More complete fix for emailing contact selectors. --- .../modules/mailings/contacts1.modules.php | 25 ++++++++----------- .../modules/mailings/contacts2.modules.php | 1 - .../modules/mailings/contacts3.modules.php | 22 +++++++--------- htdocs/langs/en_US/mails.lang | 2 +- htdocs/langs/fr_FR/mails.lang | 2 +- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/htdocs/core/modules/mailings/contacts1.modules.php b/htdocs/core/modules/mailings/contacts1.modules.php index 3c44c5e15ce..f45969ea564 100755 --- a/htdocs/core/modules/mailings/contacts1.modules.php +++ b/htdocs/core/modules/mailings/contacts1.modules.php @@ -71,11 +71,8 @@ class mailing_contacts1 extends MailingTargets $statssql=array(); $statssql[0] = "SELECT '".$langs->trans("NbOfCompaniesContacts")."' as label,"; $statssql[0].= " count(distinct(c.email)) as nb"; - $statssql[0].= " FROM ".MAIN_DB_PREFIX."socpeople as c,"; - $statssql[0].= " ".MAIN_DB_PREFIX."societe as s"; - $statssql[0].= " WHERE s.rowid = c.fk_soc"; - $statssql[0].= " AND c.entity IN (".getEntity('societe', 1).")"; - $statssql[0].= " AND s.client IN (1, 3)"; + $statssql[0].= " FROM ".MAIN_DB_PREFIX."socpeople as c"; + $statssql[0].= " WHERE c.entity IN (".getEntity('societe', 1).")"; $statssql[0].= " AND c.email != ''"; // Note that null != '' is false $statssql[0].= " AND c.no_email = 0"; @@ -96,12 +93,11 @@ class mailing_contacts1 extends MailingTargets global $conf; $sql = "SELECT count(distinct(c.email)) as nb"; - $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c,"; - $sql .= " ".MAIN_DB_PREFIX."societe as s"; - $sql .= " WHERE s.rowid = c.fk_soc"; - $sql .= " AND c.entity IN (".getEntity('societe', 1).")"; - $sql .= " AND c.email != ''"; // Note that null != '' is false - $sql .= " AND c.no_email = 0"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; + $sql.= " WHERE c.entity IN (".getEntity('societe', 1).")"; + $sql.= " AND c.email != ''"; // Note that null != '' is false + $sql.= " AND c.no_email = 0"; // La requete doit retourner un champ "nb" pour etre comprise // par parent::getNbOfRecipients @@ -203,10 +199,9 @@ class mailing_contacts1 extends MailingTargets $sql = "SELECT c.rowid as id, c.email as email, c.rowid as fk_contact,"; $sql.= " c.lastname, c.firstname, c.civilite,"; $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE s.rowid = c.fk_soc"; - $sql.= " AND c.entity IN (".getEntity('societe', 1).")"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; + $sql.= " WHERE c.entity IN (".getEntity('societe', 1).")"; $sql.= " AND c.email != ''"; $sql.= " AND c.no_email = 0"; foreach($filtersarray as $key) diff --git a/htdocs/core/modules/mailings/contacts2.modules.php b/htdocs/core/modules/mailings/contacts2.modules.php index 4b7b95ecb88..5a25a11e590 100755 --- a/htdocs/core/modules/mailings/contacts2.modules.php +++ b/htdocs/core/modules/mailings/contacts2.modules.php @@ -187,7 +187,6 @@ class mailing_contacts2 extends MailingTargets $sql = "SELECT sp.poste, count(distinct(sp.email)) AS nb"; $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; $sql.= " WHERE sp.entity IN (".getEntity('societe', 1).")"; $sql.= " AND sp.email != ''"; // Note that null != '' is false $sql.= " AND sp.no_email = 0"; diff --git a/htdocs/core/modules/mailings/contacts3.modules.php b/htdocs/core/modules/mailings/contacts3.modules.php index b1955aa981e..600a855c975 100755 --- a/htdocs/core/modules/mailings/contacts3.modules.php +++ b/htdocs/core/modules/mailings/contacts3.modules.php @@ -79,12 +79,11 @@ class mailing_contacts3 extends MailingTargets $sql = "SELECT sp.rowid as id, sp.email as email, sp.rowid as fk_contact,"; $sql.= " sp.lastname, sp.firstname, sp.civilite,"; $sql.= " s.nom as companyname"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - if ($filtersarray[0] <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie as c,"; - if ($filtersarray[0] <> 'all') $sql.= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql.= " WHERE s.rowid = sp.fk_soc"; - $sql.= " AND sp.email != ''"; // Note that null != '' is false + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp"; + if ($filtersarray[0] <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie as c"; + if ($filtersarray[0] <> 'all') $sql.= ", ".MAIN_DB_PREFIX."categorie_societe as cs"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = sp.fk_soc"; + $sql.= " WHERE sp.email != ''"; // Note that null != '' is false $sql.= " AND sp.no_email = 0"; $sql.= " AND sp.entity IN (".getEntity('societe', 1).")"; if ($filtersarray[0] <> 'all') $sql.= " AND cs.fk_categorie = c.rowid"; @@ -168,10 +167,9 @@ class mailing_contacts3 extends MailingTargets // Number with a filter are show in the combo list for each filter. // If we want a filter "is inside at least one category", we must add it into formFilter $sql = "SELECT count(distinct(c.email)) as nb"; - $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s"; - $sql.= " WHERE s.rowid = c.fk_soc"; - $sql.= " AND c.entity IN (".getEntity('societe', 1).")"; + $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as c"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = c.fk_soc"; + $sql.= " WHERE c.entity IN (".getEntity('societe', 1).")"; $sql.= " AND c.email != ''"; // Note that null != '' is false $sql.= " AND c.no_email = 0"; /* @@ -205,11 +203,9 @@ class mailing_contacts3 extends MailingTargets $sql = "SELECT c.label, count(distinct(sp.email)) AS nb"; $sql.= " FROM ".MAIN_DB_PREFIX."socpeople as sp,"; - $sql.= " ".MAIN_DB_PREFIX."societe as s,"; $sql.= " ".MAIN_DB_PREFIX."categorie as c,"; $sql.= " ".MAIN_DB_PREFIX."categorie_societe as cs"; - $sql.= " WHERE s.rowid = sp.fk_soc"; - $sql.= " AND sp.email != ''"; // Note that null != '' is false + $sql.= " WHERE sp.email != ''"; // Note that null != '' is false $sql.= " AND sp.no_email = 0"; $sql.= " AND sp.entity IN (".getEntity('societe', 1).")"; $sql.= " AND cs.fk_categorie = c.rowid"; diff --git a/htdocs/langs/en_US/mails.lang b/htdocs/langs/en_US/mails.lang index 3cbce8ff4b2..f52dea49651 100644 --- a/htdocs/langs/en_US/mails.lang +++ b/htdocs/langs/en_US/mails.lang @@ -100,7 +100,7 @@ MailSelectedRecipients=Selected recipients MailingArea=EMailings area LastMailings=Last %s emailings TargetsStatistics=Targets statistics -NbOfCompaniesContacts=Unique contacts of companies +NbOfCompaniesContacts=Unique contacts/addresses MailNoChangePossible=Recipients for validated emailing can't be changed SearchAMailing=Search mailing SendMailing=Send emailing diff --git a/htdocs/langs/fr_FR/mails.lang b/htdocs/langs/fr_FR/mails.lang index be08ccad7e8..a94aa8ff149 100644 --- a/htdocs/langs/fr_FR/mails.lang +++ b/htdocs/langs/fr_FR/mails.lang @@ -99,7 +99,7 @@ MailSelectedRecipients=Destinataires sélectionnés MailingArea=Espace emailings LastMailings=Les %s derniers emailings TargetsStatistics=Statistiques destinataires -NbOfCompaniesContacts=Contacts uniques des sociétés +NbOfCompaniesContacts=Contacts/adresses uniques MailNoChangePossible=Destinataires d'un mailing validé non modifiables SearchAMailing=Rechercher un mailing SendMailing=Envoi emailing From a32a02e4c194b2fc0d7f5e4587d44d9931974dc3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 16:51:13 +0200 Subject: [PATCH 23/44] Fix: Removed warnings --- htdocs/comm/mailing/cibles.php | 2 +- htdocs/core/modules/mailings/pomme.modules.php | 2 +- .../mailings/thirdparties_services_expired.modules.php | 5 ++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 95bb905348f..5530d95cd06 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -307,7 +307,7 @@ if ($object->fetch($id) >= 0) print $modulename; print ""; */ - $nbofrecipient=$obj->getNbOfRecipients(); + $nbofrecipient=$obj->getNbOfRecipients(''); print '
    '.$langs->trans("ThirdPartyName").''; + print '
    '.$langs->trans("ThirdPartyName").''; print $form->showrefnav($object,'socid','',($user->societe_id?0:1),'rowid','nom'); print '
    '.$langs->trans("NbOfActiveNotifications").'
    '.$langs->trans("NbOfActiveNotifications").''; $sql = "SELECT COUNT(n.rowid) as nb"; $sql.= " FROM ".MAIN_DB_PREFIX."notify_def as n"; diff --git a/htdocs/societe/soc.php b/htdocs/societe/soc.php index ceef3ec324e..0ee8d7d0f8c 100644 --- a/htdocs/societe/soc.php +++ b/htdocs/societe/soc.php @@ -1465,7 +1465,7 @@ else */ // Name - print '
    '.$langs->trans('ThirdPartyName').'
    '.$langs->trans('ThirdPartyName').''; print $form->showrefnav($object, 'socid', '', ($user->societe_id?0:1), 'rowid', 'nom'); print ''; if ($nbofrecipient >= 0) { diff --git a/htdocs/core/modules/mailings/pomme.modules.php b/htdocs/core/modules/mailings/pomme.modules.php index 6e645b3581c..30c7c63da60 100644 --- a/htdocs/core/modules/mailings/pomme.modules.php +++ b/htdocs/core/modules/mailings/pomme.modules.php @@ -82,7 +82,7 @@ class mailing_pomme extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param string $sql Requete sql de comptage + * @param string $sql SQL request to use to count * @return int Number of recipients */ function getNbOfRecipients($sql='') diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php index 4b621b705a2..665e5f51f7b 100755 --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php @@ -175,11 +175,10 @@ class mailing_thirdparties_services_expired extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * - * @param int $filter Filter - * @param string $option Option + * @param string $sql SQL request to use to count * @return int Number of recipients */ - function getNbOfRecipients($sql,$filter=1,$option='') + function getNbOfRecipients($sql) { $now=dol_now(); From 5197dedc59dda34e61909a6dc71892337dc27d0e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 18:33:58 +0200 Subject: [PATCH 24/44] Fix: Missing background --- htdocs/theme/amarok/style.css.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/theme/amarok/style.css.php b/htdocs/theme/amarok/style.css.php index 41f96d10d20..e1501152c2d 100755 --- a/htdocs/theme/amarok/style.css.php +++ b/htdocs/theme/amarok/style.css.php @@ -174,6 +174,7 @@ select.flat { border-top:solid 1px rgba(0,0,0,.4); border-bottom:solid 1px rgba(0,0,0,.2); box-shadow:1px 1px 2px rgba(0,0,0,.2) inset; + background: #FDFDFD; } form { From f3adcc311d640e26182c85f7f7e399f8da484283 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 18:34:19 +0200 Subject: [PATCH 25/44] Qual: Removed useless table --- htdocs/comm/mailing/cibles.php | 45 +++++++++++++--------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/htdocs/comm/mailing/cibles.php b/htdocs/comm/mailing/cibles.php index 5530d95cd06..22c7de7c5f2 100644 --- a/htdocs/comm/mailing/cibles.php +++ b/htdocs/comm/mailing/cibles.php @@ -1,6 +1,6 @@ - * Copyright (C) 2005-2010 Laurent Destailleur + * Copyright (C) 2005-2013 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -346,21 +346,8 @@ if ($object->fetch($id) >= 0) print '
    '; print '
    '; - - print '
    '; - print ''; - print_titre($langs->trans("ToClearAllRecipientsClickHere")); - print ''; - print ''; - print ''; - print ''; - print '
    '; - print '
    '; - print '
    '; } - - // List of selected targets print "\n\n"; print '
    '; @@ -383,21 +370,23 @@ if ($object->fetch($id) >= 0) { $num = $db->num_rows($resql); - $parm = "&id=".$object->id; - if ($search_lastname) $parm.= "&search_lastname=".urlencode($search_lastname); - if ($search_firstname) $parm.= "&search_firstname=".urlencode($search_firstname); - if ($search_email) $parm.= "&search_email=".urlencode($search_email); + $param = "&id=".$object->id; + if ($search_lastname) $param.= "&search_lastname=".urlencode($search_lastname); + if ($search_firstname) $param.= "&search_firstname=".urlencode($search_firstname); + if ($search_email) $param.= "&search_email=".urlencode($search_email); - print_barre_liste($langs->trans("MailSelectedRecipients"),$page,$_SERVER["PHP_SELF"],$parm,$sortfield,$sortorder,"",$num,$object->nbemail,''); + $cleartext='
    '.$langs->trans("ToClearAllRecipientsClickHere").': '.''; - if ($page) $parm.= "&page=".$page; + print_barre_liste($langs->trans("MailSelectedRecipients").$cleartext,$page,$_SERVER["PHP_SELF"],$param,$sortfield,$sortorder,"",$num,$object->nbemail,''); + + if ($page) $param.= "&page=".$page; print ''; print ''; - print_liste_field_titre($langs->trans("EMail"),$_SERVER["PHP_SELF"],"mc.email",$parm,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Lastname"),$_SERVER["PHP_SELF"],"mc.lastname",$parm,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Firstname"),$_SERVER["PHP_SELF"],"mc.firstname",$parm,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("OtherInformations"),$_SERVER["PHP_SELF"],"",$parm,"","",$sortfield,$sortorder); - print_liste_field_titre($langs->trans("Source"),$_SERVER["PHP_SELF"],"",$parm,"",'align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("EMail"),$_SERVER["PHP_SELF"],"mc.email",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Lastname"),$_SERVER["PHP_SELF"],"mc.lastname",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Firstname"),$_SERVER["PHP_SELF"],"mc.firstname",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("OtherInformations"),$_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Source"),$_SERVER["PHP_SELF"],"",$param,"",'align="center"',$sortfield,$sortorder); // Date sendinf if ($object->statut < 2) @@ -406,11 +395,11 @@ if ($object->fetch($id) >= 0) } else { - print_liste_field_titre($langs->trans("DateSending"),$_SERVER["PHP_SELF"],"mc.date_envoi",$parm,'','align="center"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("DateSending"),$_SERVER["PHP_SELF"],"mc.date_envoi",$param,'','align="center"',$sortfield,$sortorder); } // Statut - print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"mc.statut",$parm,'','align="right"',$sortfield,$sortorder); + print_liste_field_titre($langs->trans("Status"),$_SERVER["PHP_SELF"],"mc.statut",$param,'','align="right"',$sortfield,$sortorder); print ''; @@ -496,7 +485,7 @@ if ($object->fetch($id) >= 0) print ''; print ''; } From 70b7cb1fa3497697ddfc31c734b442f49ed433d0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 19:50:54 +0200 Subject: [PATCH 26/44] Fix: Restore suffix --- htdocs/core/lib/invoice2.lib.php | 67 +++++++++++++------------- scripts/invoices/rebuild_merge_pdf.php | 3 +- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index a73855accb4..c2c67c090b1 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -29,22 +29,23 @@ require_once(DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'); /** * Function to build a compiled PDF - * - * @param DoliDB $db Database handler - * @param Translate $langs Object langs - * @param Conf $conf Object conf + * + * @param DoliDB $db Database handler + * @param Translate $langs Object langs + * @param Conf $conf Object conf * @param string $diroutputpdf Dir to output file * @param string $newlangid Lang id * @param array $filter Array with filters - * @param date $dateafterdate Invoice after date + * @param date $dateafterdate Invoice after date * @param date $datebeforedate Invoice before date * @param date $paymentdateafter Payment after date * @param date $paymentdatebefore Payment before date * @param int $usestdout Add information onto standard output - * @param int $regenerate ''=Use existing PDF files, 'nameofpdf'=Regenerate all PDF files using the template, - * @return int Error code + * @param int $regenerate ''=Use existing PDF files, 'nameofpdf'=Regenerate all PDF files using the template + * @param string $option Suffix to add into file name of generated PDF + * @return int Error code */ -function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate=0) +function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate=0, $option='') { $sql = "SELECT DISTINCT f.rowid, f.facnumber"; $sql.= " FROM ".MAIN_DB_PREFIX."facture as f"; @@ -104,19 +105,19 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte } if ($sqlwhere) $sql.=$sqlwhere; if ($sqlorder) $sql.=$sqlorder; - + //print $sql; exit; dol_syslog("scripts/invoices/rebuild_merge.php: sql=".$sql); - + if ($usestdout) print '--- start'."\n"; - + // Start of transaction //$db->begin(); - + $error = 0; $result = 0; $files = array() ; // liste les fichiers - + dol_syslog("scripts/invoices/rebuild_merge.php sql=".$sql); if ( $resql=$db->query($sql) ) { @@ -125,16 +126,16 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $oldemail = ''; $message = ''; $total = ''; - + if ($num) { // First loop on each resultset to build PDF // ----------------------------------------- - + while ($cpt < $num) { $obj = $db->fetch_object($resql); - + $fac = new Facture($db); $result=$fac->fetch($obj->rowid); if ($result > 0) @@ -157,35 +158,35 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte else { if ($usestdout) print "PDF for invoice ".$obj->facnumber." already exists\n"; } - + // Add file into files array $files[] = $filename; } - + if ($result <= 0) { $error++; if ($usestdout) print "Error: Failed to build PDF for invoice ".$fac->ref."\n"; else dol_syslog("Failed to build PDF for invoice ".$fac->ref, LOG_ERR); } - + $cpt++; } - - // Define format of output PDF + + // Define format of output PDF $formatarray=pdf_getFormat(); $page_largeur = $formatarray['width']; $page_hauteur = $formatarray['height']; $format = array($page_largeur,$page_hauteur); - + if ($usestdout) print "Using output PDF format ".join('x',$format)."\n"; else dol_syslog("Using output PDF format ".join('x',$format), LOG_ERR); - - + + // Now, build a merged files with all files in $files array //--------------------------------------------------------- - + // Create empty PDF $pdf=pdf_getInstance($format); if (class_exists('TCPDF')) @@ -194,11 +195,11 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $pdf->setPrintFooter(false); } $pdf->SetFont(pdf_getPDFFont($outputlangs)); - + if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false); //$pdf->SetCompression(false); - - + + //$pdf->Open(); //$pdf->AddPage(); //$title=$langs->trans("BillsCustomersUnpaid"); @@ -224,12 +225,12 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte // Create output dir if not exists dol_mkdir($diroutputpdf); - + // Save merged file $filename='mergedpdf'; - + if (! empty($option)) $filename.='_'.$option; - + if ($pagecount) { $file=$diroutputpdf.'/'.$filename.'.pdf'; @@ -237,7 +238,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); } - + if ($usestdout) print "Merged PDF has been built in ".$file."\n"; $result = 1; } @@ -254,7 +255,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte dol_syslog("scripts/invoices/rebuild_merge.php: Error"); $error++; } - + if ($error) return -1; else return $result; } diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index f4984331a51..6360735ab67 100755 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -36,7 +36,6 @@ if (substr($sapi_type, 0, 3) == 'cgi') { // Include Dolibarr environment require_once($path."../../htdocs/master.inc.php"); // After this $db is an opened handler to database. We close it at end of file. -require_once(DOL_DOCUMENT_ROOT."/cron/functions_cron.lib.php"); 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"); @@ -179,7 +178,7 @@ if (in_array('payments',$filter) && in_array('nopayment',$filter)) // 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); +$result=rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option); From 98ddd02a32e56245b732ec26c84f1da6f809bcc4 Mon Sep 17 00:00:00 2001 From: fhenry Date: Wed, 10 Apr 2013 19:55:21 +0200 Subject: [PATCH 27/44] Qual : PHP Code_Sniffer --- htdocs/commande/class/commande.class.php | 1 - .../thirdparties_services_expired.modules.php | 1 + .../pdf/doc_generic_project_odt.modules.php | 76 +++++++++++-------- .../fourn/class/fournisseur.product.class.php | 1 + htdocs/opensurvey/adminstuds_preview.php | 2 +- htdocs/opensurvey/fonctions.php | 2 +- htdocs/opensurvey/public/choix_date.php | 6 +- htdocs/opensurvey/public/create_survey.php | 2 +- htdocs/opensurvey/public/exportcsv.php | 12 +-- htdocs/public/paybox/paymentko.php | 3 +- htdocs/public/paybox/paymentok.php | 3 +- htdocs/public/paypal/paymentko.php | 3 +- htdocs/public/paypal/paymentok.php | 3 +- 13 files changed, 64 insertions(+), 51 deletions(-) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 0270b0327dd..b6e11a64065 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -2783,7 +2783,6 @@ class Commande extends CommonOrder * Update value of extrafields on the proposal * * @param User $user Object user that modify - * @param double $remise Amount discount * @return int <0 if ko, >0 if ok */ function update_extrafields($user) diff --git a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php index 4b621b705a2..3865cfe8f66 100755 --- a/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php +++ b/htdocs/core/modules/mailings/thirdparties_services_expired.modules.php @@ -175,6 +175,7 @@ class mailing_thirdparties_services_expired extends MailingTargets * For example if this selector is used to extract 500 different * emails from a text file, this function must return 500. * + * @param string $sql SQL request to get recipitien * @param int $filter Filter * @param string $option Option * @return int Number of recipients diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php index 34cd23a0a7f..912c9fd25ad 100644 --- a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -209,7 +209,7 @@ class doc_generic_project_odt extends ModelePDFProjects function get_substitutionarray_project_reference($refdetail,$outputlangs) { global $conf; - + return array( 'projref_type'=>$refdetail['type'], 'projref_ref'=>$refdetail['ref'], @@ -220,7 +220,7 @@ class doc_generic_project_odt extends ModelePDFProjects 'projref_status'=>$refdetail['status'] ); } - + /** * Define array with couple substitution key => substitution value * @@ -242,7 +242,7 @@ class doc_generic_project_odt extends ModelePDFProjects 'taskressource_email'=>$taskressource['email'] ); } - + /** * Define array with couple substitution key => substitution value * @@ -254,7 +254,7 @@ class doc_generic_project_odt extends ModelePDFProjects { global $conf; - return array( + return array( 'tasktime_rowid'=>$tasktime['rowid'], 'tasktime_task_date'=>dol_print_date($tasktime['task_date'],'day'), 'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'],'all'), @@ -265,7 +265,7 @@ class doc_generic_project_odt extends ModelePDFProjects 'tasktime_fullcivname'=>$tasktime['fullcivname'] ); } - + /** * Define array with couple substitution key => substitution value * @@ -276,7 +276,7 @@ class doc_generic_project_odt extends ModelePDFProjects function get_substitutionarray_task_file($file,$outputlangs) { global $conf; - + return array( 'tasksfile_name'=>$file['name'], 'tasksfile_date'=>dol_print_date($file['date'],'day'), @@ -384,6 +384,14 @@ class doc_generic_project_odt extends ModelePDFProjects return -1; } + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; if (! is_object($outputlangs)) $outputlangs=$langs; $sav_charset_output=$outputlangs->charset_output; $outputlangs->charset_output='UTF-8'; @@ -534,6 +542,9 @@ class doc_generic_project_odt extends ModelePDFProjects // Replace tags of object + external modules $tmparray=$this->get_substitutionarray_object($object,$outputlangs); complete_substitutions_array($tmparray, $outputlangs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks foreach($tmparray as $key=>$value) { try { @@ -564,7 +575,7 @@ class doc_generic_project_odt extends ModelePDFProjects if (!empty($object->fk_soc)) $socid = $object->fk_soc; $tasksarray=$taskstatic->getTasksArray(0, 0, $object->id, $socid, 0); - + foreach ($tasksarray as $task) @@ -584,10 +595,10 @@ class doc_generic_project_odt extends ModelePDFProjects { } } - + $taskobj=new Task($this->db); $taskobj->fetch($task->id); - + // Replace tags of lines for contacts task $sourcearray=array('internal','external'); $contact_arrray=array(); @@ -601,7 +612,7 @@ class doc_generic_project_odt extends ModelePDFProjects if ((is_array($contact_arrray) && count($contact_arrray) > 0)) { $listlinestaskres = $listlines->__get('tasksressources'); - + foreach ($contact_arrray as $contact) { if ($contact['source']=='internal') { @@ -611,15 +622,15 @@ class doc_generic_project_odt extends ModelePDFProjects } elseif ($contact['source']=='external') { $objectdetail=new Contact($this->db); $objectdetail->fetch($contact['id']); - + $soc=new Societe($this->db); $soc->fetch($contact['socid']); $contact['socname']=$soc->name; } $contact['fullname']=$objectdetail->getFullName($outputlangs,1); - + $tmparray=$this->get_substitutionarray_tasksressource($contact,$outputlangs); - + foreach($tmparray as $key => $val) { try @@ -645,7 +656,7 @@ class doc_generic_project_odt extends ModelePDFProjects $sql .= " WHERE t.fk_task =".$task->id; $sql .= " AND t.fk_user = u.rowid"; $sql .= " ORDER BY t.task_date DESC"; - + $resql = $this->db->query($sql); if ($resql) { @@ -663,9 +674,9 @@ class doc_generic_project_odt extends ModelePDFProjects } else { $row['fullcivname']=''; } - + $tmparray=$this->get_substitutionarray_taskstime($row,$outputlangs); - + foreach($tmparray as $key => $val) { try @@ -684,15 +695,15 @@ class doc_generic_project_odt extends ModelePDFProjects } $this->db->free($resql); } - - + + // Replace tags of project files $listtasksfiles = $listlines->__get('tasksfiles'); - + $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($object->ref).'/'.dol_sanitizeFileName($task->ref); $filearray=dol_dir_list($upload_dir,"files",0,'','\.meta$','name',SORT_ASC,1); - - + + foreach ($filearray as $filedetail) { $tmparray=$this->get_substitutionarray_task_file($filedetail,$outputlangs); @@ -731,7 +742,7 @@ class doc_generic_project_odt extends ModelePDFProjects $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($object->ref); $filearray=dol_dir_list($upload_dir,"files",0,'','\.meta$','name',SORT_ASC,1); - + foreach ($filearray as $filedetail) { //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true)); @@ -891,27 +902,27 @@ class doc_generic_project_odt extends ModelePDFProjects { $ref_array=array(); $ref_array['type']=$langs->trans($classname); - + $element = new $classname($this->db); $element->fetch($elementarray[$i]); $element->fetch_thirdparty(); - + //Ref object $ref_array['ref']=$element->ref; - + //Date object $dateref=$element->date; if (empty($dateref)) $dateref=$element->datep; if (empty($dateref)) $dateref=$element->date_contrat; $ref_array['date']=$dateref; - + //Soc object if (is_object($element->thirdparty)) { $ref_array['socname']=$element->thirdparty->name; } else { $ref_array['socname']=''; } - + //Amount object if (empty($valueref['disableamount'])) { if (!empty($element->total_ht)) { @@ -925,9 +936,9 @@ class doc_generic_project_odt extends ModelePDFProjects $ref_array['amountht']=''; $ref_array['amountttc']=''; } - + $ref_array['status']=html_entity_decode($element->getLibStatut(0)); - + $tmparray=$this->get_substitutionarray_project_reference($ref_array,$outputlangs); foreach($tmparray as $key => $val) @@ -945,7 +956,7 @@ class doc_generic_project_odt extends ModelePDFProjects } $listlines->merge(); } - + } } $odfHandler->mergeSegment($listlines); @@ -958,6 +969,11 @@ class doc_generic_project_odt extends ModelePDFProjects return -1; } + // Call the beforeODTSave hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); + $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + + // Write new file $odfHandler->saveToDisk($file); diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 09843191692..d310943bbed 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -146,6 +146,7 @@ class ProductFournisseur extends Product * @param string $charges costs affering to product * @param float $remise_percent Discount regarding qty (percent) * @param float $remise Discount regarding qty (amount) + * @param float $newnpr new infobit tva npr * @return int <0 if KO, >=0 if OK */ function update_buyprice($qty, $buyprice, $user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges=0, $remise_percent=0, $remise=0, $newnpr=0) diff --git a/htdocs/opensurvey/adminstuds_preview.php b/htdocs/opensurvey/adminstuds_preview.php index 7e7bb6a6967..bbb5f8b09ac 100755 --- a/htdocs/opensurvey/adminstuds_preview.php +++ b/htdocs/opensurvey/adminstuds_preview.php @@ -202,7 +202,7 @@ if (isset($_POST["ajoutercolonne"]) && ($object->format == "D" || $object->forma //on rajoute la valeur dans les valeurs $datesbase = explode(",",$object->sujet); - $taillebase = sizeof($datesbase); + $taillebase = count($datesbase); //recherche de l'endroit de l'insertion de la nouvelle date dans les dates deja entrées dans le tableau if ($nouvelledate < $datesbase[0]) { diff --git a/htdocs/opensurvey/fonctions.php b/htdocs/opensurvey/fonctions.php index 6068ca965f1..a1375e15f0a 100755 --- a/htdocs/opensurvey/fonctions.php +++ b/htdocs/opensurvey/fonctions.php @@ -120,7 +120,7 @@ function get_server_name() /** * is_error * - * @param unknown_type $cerr + * @param unknown_type $cerr error number * @return boolean */ function is_error($cerr) diff --git a/htdocs/opensurvey/public/choix_date.php b/htdocs/opensurvey/public/choix_date.php index 72a24357436..faf67137942 100755 --- a/htdocs/opensurvey/public/choix_date.php +++ b/htdocs/opensurvey/public/choix_date.php @@ -257,9 +257,9 @@ if (issetAndNoEmpty('choixjourajout')) { // Si le test est passé, alors on insere la valeur dans la variable de session qui contient les dates if ($journeuf && issetAndNoEmpty('choixjourajout') === true) { - array_push ($_SESSION["totalchoixjour"],mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"])); - sort ($_SESSION["totalchoixjour"]); - $cle=array_search (mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"]), $_SESSION["totalchoixjour"]); + array_push($_SESSION["totalchoixjour"],mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"])); + sort($_SESSION["totalchoixjour"]); + $cle=array_search(mktime (0,0,0, $_SESSION["mois"], $_POST["choixjourajout"][0], $_SESSION["annee"]), $_SESSION["totalchoixjour"]); //On sauvegarde les heures deja entrées for ($i = 0; $i < $cle; $i++) { diff --git a/htdocs/opensurvey/public/create_survey.php b/htdocs/opensurvey/public/create_survey.php index c5af8db0cab..f94898ac692 100755 --- a/htdocs/opensurvey/public/create_survey.php +++ b/htdocs/opensurvey/public/create_survey.php @@ -162,7 +162,7 @@ print ''."\n"; print '
    '."\n"; -#affichage du cochage par défaut +//affichage du cochage par défaut $cocheplus=''; if ($_SESSION["canedit"]) $cocheplus="checked"; diff --git a/htdocs/opensurvey/public/exportcsv.php b/htdocs/opensurvey/public/exportcsv.php index b2ee0cc1eea..a6d0b0216a4 100755 --- a/htdocs/opensurvey/public/exportcsv.php +++ b/htdocs/opensurvey/public/exportcsv.php @@ -64,7 +64,7 @@ $now=dol_now(); $nbcolonnes=substr_count($object->sujet,',')+1; $toutsujet=explode(",",$object->sujet); -#$toutsujet=str_replace("°","'",$toutsujet); +//$toutsujet=str_replace("°","'",$toutsujet); // affichage des sujets du sondage $input.=$langs->trans("Name").";"; @@ -139,15 +139,15 @@ if ($resql) else dol_print_error($db); -$filesize = strlen( $input ); +$filesize = strlen($input); $filename=$numsondage."_".dol_print_date($now,'%Y%m%d%H%M').".csv"; -header( 'Content-Type: text/csv; charset=utf-8' ); -header( 'Content-Length: '.$filesize ); -header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); -header( 'Cache-Control: max-age=10' ); +header('Content-Type: text/csv; charset=utf-8'); +header('Content-Length: '.$filesize); +header('Content-Disposition: attachment; filename="'.$filename.'"'); +header('Cache-Control: max-age=10'); echo $input; exit; diff --git a/htdocs/public/paybox/paymentko.php b/htdocs/public/paybox/paymentko.php index 4db0684005b..b2c3954c1e9 100644 --- a/htdocs/public/paybox/paymentko.php +++ b/htdocs/public/paybox/paymentko.php @@ -73,8 +73,7 @@ if (! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL) && preg_match('/MEM=',$fu 'New subscription payed', $sendto, $from, - 'New subscription payed '.$fulltag - ); + 'New subscription payed '.$fulltag); $result=$mailfile->sendfile(); if ($result) diff --git a/htdocs/public/paybox/paymentok.php b/htdocs/public/paybox/paymentok.php index ebd3c834d09..0c25e2e3039 100644 --- a/htdocs/public/paybox/paymentok.php +++ b/htdocs/public/paybox/paymentok.php @@ -103,8 +103,7 @@ if (! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL) && preg_match('/MEM=',$fu 'New subscription payed', $sendto, $from, - 'New subscription payed '.$fulltag - ); + 'New subscription payed '.$fulltag); $result=$mailfile->sendfile(); if ($result) diff --git a/htdocs/public/paypal/paymentko.php b/htdocs/public/paypal/paymentko.php index c6fe53ac7b0..ff83d6d831a 100755 --- a/htdocs/public/paypal/paymentko.php +++ b/htdocs/public/paypal/paymentko.php @@ -81,8 +81,7 @@ if (! empty($conf->global->MEMBER_PAYONLINE_SENDEMAIL) && preg_match('/MEM=',$fu 'New subscription payed', $sendto, $from, - 'New subscription payed '.$fulltag - ); + 'New subscription payed '.$fulltag); $result=$mailfile->sendfile(); if ($result) diff --git a/htdocs/public/paypal/paymentok.php b/htdocs/public/paypal/paymentok.php index ca11bcb5422..0b425ea8cea 100755 --- a/htdocs/public/paypal/paymentok.php +++ b/htdocs/public/paypal/paymentok.php @@ -140,8 +140,7 @@ if ($PAYPALTOKEN) 'New subscription payed', $sendto, $from, - 'New subscription payed '.$fulltag - ); + 'New subscription payed '.$fulltag); $result=$mailfile->sendfile(); if ($result) From 15e86875f37d24a6cdcc42698cc858449b43f503 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 20:45:38 +0200 Subject: [PATCH 28/44] Fix: sql syntax error --- htdocs/core/lib/admin.lib.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 978f0896f65..f70d3e846cc 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -252,18 +252,20 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker // Ajout trace sur requete (eventuellement a commenter si beaucoup de requetes) if (! $silent) print '
    \n"; dol_syslog('Admin.lib::run_sql Request '.($i+1).' sql='.$newsql, LOG_DEBUG); + $sqlmodified=0; // Replace for encrypt data - if (preg_match_all('/__ENCRYPT\(\'([A-Za-z0-9_\"\[\]]+)\'\)__/i',$newsql,$reg)) + if (preg_match_all('/__ENCRYPT\(\'([^\']+)\'\)__/i',$newsql,$reg)) { $num=count($reg[0]); - for($i=0;$i<$num;$i++) + for($j=0;$j<$num;$j++) { - $from = $reg[0][$i]; - $to = $db->encrypt($reg[1][$i],1); + $from = $reg[0][$j]; + $to = $db->encrypt($reg[1][$j],1); $newsql = str_replace($from,$to,$newsql); } + $sqlmodified++; } // Replace for decrypt data @@ -271,12 +273,13 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker { $num=count($reg[0]); - for($i=0;$i<$num;$i++) + for($j=0;$j<$num;$j++) { - $from = $reg[0][$i]; - $to = $db->decrypt($reg[1][$i]); + $from = $reg[0][$j]; + $to = $db->decrypt($reg[1][$j]); $newsql = str_replace($from,$to,$newsql); } + $sqlmodified++; } // Replace __x__ with rowid of insert nb x @@ -294,9 +297,11 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker $from='__'.$cursor.'__'; $to=$listofinsertedrowid[$cursor]; $newsql=str_replace($from,$to,$newsql); - dol_syslog('Admin.lib::run_sql New Request '.($i+1).' (replacing '.$from.' to '.$to.') sql='.$newsql, LOG_DEBUG); + $sqlmodified++; } + if ($sqlmodified) dol_syslog('Admin.lib::run_sql New Request '.($i+1).' (replacing '.$from.' to '.$to.') sql='.$newsql, LOG_DEBUG); + $result=$db->query($newsql,$usesavepoint); if ($result) { From 9dd201df10a5be596027923fa981e3c535551af3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 20:47:39 +0200 Subject: [PATCH 29/44] Fix: Log --- htdocs/core/lib/admin.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index f70d3e846cc..0d4bbcf6d7a 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -300,7 +300,7 @@ function run_sql($sqlfile,$silent=1,$entity='',$usesavepoint=1,$handler='',$oker $sqlmodified++; } - if ($sqlmodified) dol_syslog('Admin.lib::run_sql New Request '.($i+1).' (replacing '.$from.' to '.$to.') sql='.$newsql, LOG_DEBUG); + if ($sqlmodified) dol_syslog('Admin.lib::run_sql New Request '.($i+1).' sql='.$newsql, LOG_DEBUG); $result=$db->query($newsql,$usesavepoint); if ($result) From 4d0dd0d56c29e34602989256853ebb0a27839894 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Apr 2013 20:50:05 +0200 Subject: [PATCH 30/44] Fix: Function to generate pdf --- htdocs/core/lib/invoice2.lib.php | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index c2c67c090b1..057dffd7d13 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -1,7 +1,6 @@ -#!/usr/bin/php + * Copyright (C) 2009-2013 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 @@ -166,8 +165,8 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte if ($result <= 0) { $error++; - if ($usestdout) print "Error: Failed to build PDF for invoice ".$fac->ref."\n"; - else dol_syslog("Failed to build PDF for invoice ".$fac->ref, LOG_ERR); + if ($usestdout) print "Error: Failed to build PDF for invoice ".($fac->ref?$fac->ref:' id '.$obj->rowid)."\n"; + else dol_syslog("Failed to build PDF for invoice ".($fac->ref?$fac->ref:' id '.$obj->rowid), LOG_ERR); } $cpt++; @@ -194,7 +193,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); } - $pdf->SetFont(pdf_getPDFFont($outputlangs)); + $pdf->SetFont(pdf_getPDFFont($langs)); if ($conf->global->MAIN_DISABLE_PDF_COMPRESSION) $pdf->SetCompression(false); //$pdf->SetCompression(false); @@ -230,16 +229,21 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $filename='mergedpdf'; if (! empty($option)) $filename.='_'.$option; + $file=$diroutputpdf.'/'.$filename.'.pdf'; - if ($pagecount) + if (! $error && $pagecount) { - $file=$diroutputpdf.'/'.$filename.'.pdf'; $pdf->Output($file,'F'); if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); } - if ($usestdout) print "Merged PDF has been built in ".$file."\n"; + if ($usestdout) + { + if (! $error) print "Merged PDF has been built in ".$file."\n"; + else print "Can't build PDF ".$file."\n"; + } + $result = 1; } else From e0cb09bd651210d22ba10dbca3a0a11246b2986a Mon Sep 17 00:00:00 2001 From: BENKE Charles Date: Wed, 10 Apr 2013 22:38:45 +0300 Subject: [PATCH 31/44] Update admin_extrafields.inc.php $default_value not initialised new type : sellist --- htdocs/core/admin_extrafields.inc.php | 55 +++++++++++++++++---------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/htdocs/core/admin_extrafields.inc.php b/htdocs/core/admin_extrafields.inc.php index 02eab4db893..0b608a1e736 100644 --- a/htdocs/core/admin_extrafields.inc.php +++ b/htdocs/core/admin_extrafields.inc.php @@ -66,6 +66,13 @@ if ($action == 'add') $mesg[]=$langs->trans("ErrorNoValueForSelectType"); $action = 'create'; } + if (GETPOST('type')=='sellist' && !GETPOST('param')) + { + $error++; + $langs->load("errors"); + $mesg[]=$langs->trans("ErrorNoValueForSelectListType"); + $action = 'create'; + } if (GETPOST('type')=='checkbox' && !GETPOST('param')) { $error++; @@ -82,30 +89,30 @@ if ($action == 'add') } if (((GETPOST('type')=='radio') || (GETPOST('type')=='checkbox') || (GETPOST('type')=='radio')) && GETPOST('param')) { - // Construct array for parameter (value of select list) - $parameters = GETPOST('param'); - $parameters_array = explode("\r\n",$parameters); - foreach($parameters_array as $param_ligne) - { - if (!empty($param_ligne)) { - if (preg_match_all('/,/',$param_ligne,$matches)) - { - if (count($matches[0])>1) { - $error++; - $langs->load("errors"); - $mesg[]=$langs->trans("ErrorBadFormatValueList",$param_ligne); - $action = 'create'; - } - } - else - { + // Construct array for parameter (value of select list) + $parameters = GETPOST('param'); + $parameters_array = explode("\r\n",$parameters); + foreach($parameters_array as $param_ligne) + { + if (!empty($param_ligne)) { + if (preg_match_all('/,/',$param_ligne,$matches)) + { + if (count($matches[0])>1) { $error++; $langs->load("errors"); $mesg[]=$langs->trans("ErrorBadFormatValueList",$param_ligne); $action = 'create'; } - } - } + } + else + { + $error++; + $langs->load("errors"); + $mesg[]=$langs->trans("ErrorBadFormatValueList",$param_ligne); + $action = 'create'; + } + } + } } if (! $error) @@ -114,6 +121,7 @@ if ($action == 'add') if (isset($_POST["attrname"]) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$_POST['attrname'])) { // Construct array for parameter (value of select list) + $default_value = GETPOST('default_value'); $parameters = GETPOST('param'); $parameters_array = explode("\r\n",$parameters); foreach($parameters_array as $param_ligne) @@ -186,6 +194,13 @@ if ($action == 'update') $mesg[]=$langs->trans("ErrorNoValueForSelectType"); $action = 'edit'; } + if (GETPOST('type')=='sellist' && !GETPOST('param')) + { + $error++; + $langs->load("errors"); + $mesg[]=$langs->trans("ErrorNoValueForSelectListType"); + $action = 'edit'; + } if (GETPOST('type')=='checkbox' && !GETPOST('param')) { $error++; @@ -291,4 +306,4 @@ if ($action == 'delete') } } -?> \ No newline at end of file +?> From 750b30863fc5e9f44eb3dbc987137a8fd9ab10a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Apr 2013 09:15:41 +0200 Subject: [PATCH 32/44] Qual: Clean code from things that should be inside external module. --- htdocs/comm/action/fiche.php | 86 +----------------------- htdocs/install/mysql/tables/llx_user.sql | 9 +-- htdocs/user/class/user.class.php | 30 ++------- htdocs/webservices/server_user.php | 4 -- 4 files changed, 11 insertions(+), 118 deletions(-) diff --git a/htdocs/comm/action/fiche.php b/htdocs/comm/action/fiche.php index 5ed00c1fd6e..37c5aaba693 100644 --- a/htdocs/comm/action/fiche.php +++ b/htdocs/comm/action/fiche.php @@ -589,8 +589,6 @@ if ($action == 'create') print ''; print ''; - add_row_for_calendar_link(); - // Description print ''; - - if (! $user->webcal_login) - { - print ''; - print ''; - $nbtr++; - } - else - { - if ($conf->global->PHPWEBCALENDAR_SYNCRO == 'always') - { - print ''; - } - else - { - print ''; - print ''; - $nbtr++; - } - } - } - } - - // TODO external module - if (! empty($conf->phenix->enabled)) - { - if ($conf->global->PHPPHENIX_SYNCRO != 'never') - { - $langs->load("other"); - - print ''; - - if (! $user->phenix_login) - { - print ''; - print ''; - $nbtr++; - } - else - { - if ($conf->global->PHPPHENIX_SYNCRO == 'always') - { - print ''; - } - else - { - print ''; - print ''; - $nbtr++; - } - } - } - } - - return $nbtr; -} - - ?> diff --git a/htdocs/install/mysql/tables/llx_user.sql b/htdocs/install/mysql/tables/llx_user.sql index 6f1f44f6b2c..6042b0906ce 100644 --- a/htdocs/install/mysql/tables/llx_user.sql +++ b/htdocs/install/mysql/tables/llx_user.sql @@ -1,6 +1,6 @@ -- ============================================================================ -- Copyright (C) 2001-2003 Rodolphe Quiedeville --- Copyright (C) 2006-2011 Laurent Destailleur +-- Copyright (C) 2006-2013 Laurent Destailleur -- Copyright (C) 2007-2013 Regis Houssin -- -- This program is free software; you can redistribute it and/or modify @@ -47,9 +47,6 @@ create table llx_user email varchar(255), signature text DEFAULT NULL, admin smallint DEFAULT 0, - webcal_login varchar(25), -- TODO move to an extra table (ex: llx_extra_fields) - phenix_login varchar(25), -- TODO move to an extra table (ex: llx_extra_fields) - phenix_pass varchar(128), -- TODO move to an extra table (ex: llx_extra_fields) module_comm smallint DEFAULT 1, module_compta smallint DEFAULT 1, fk_societe integer, @@ -64,6 +61,6 @@ create table llx_user openid varchar(255), statut tinyint DEFAULT 1, photo varchar(255), -- filename or url of photo - lang varchar(6) - + lang varchar(6), + color varchar(6) )ENGINE=innodb; diff --git a/htdocs/user/class/user.class.php b/htdocs/user/class/user.class.php index 70883769602..0d50e08e0fd 100644 --- a/htdocs/user/class/user.class.php +++ b/htdocs/user/class/user.class.php @@ -76,11 +76,6 @@ class User extends CommonObject var $fk_member; var $fk_user; - var $webcal_login; - var $phenix_login; - var $phenix_pass; - var $phenix_pass_crypted; - var $clicktodial_url; var $clicktodial_login; var $clicktodial_password; @@ -144,7 +139,7 @@ class User extends CommonObject // Get user $sql = "SELECT u.rowid, u.lastname, u.firstname, u.email, u.job, u.signature, u.office_phone, u.office_fax, u.user_mobile,"; - $sql.= " u.admin, u.login, u.webcal_login, u.phenix_login, u.phenix_pass, u.note,"; + $sql.= " u.admin, u.login, u.note,"; $sql.= " u.pass, u.pass_crypted, u.pass_temp,"; $sql.= " u.fk_societe, u.fk_socpeople, u.fk_member, u.fk_user, u.ldap_sid,"; $sql.= " u.statut, u.lang, u.entity,"; @@ -220,9 +215,6 @@ class User extends CommonObject $this->datelastlogin = $this->db->jdate($obj->datel); $this->datepreviouslogin = $this->db->jdate($obj->datep); - $this->webcal_login = $obj->webcal_login; - $this->phenix_login = $obj->phenix_login; - $this->phenix_pass_crypted = $obj->phenix_pass; $this->societe_id = $obj->fk_societe; $this->contact_id = $obj->fk_socpeople; $this->fk_member = $obj->fk_member; @@ -1111,12 +1103,6 @@ class User extends CommonObject $this->signature = trim($this->signature); $this->note = trim($this->note); $this->openid = trim(empty($this->openid)?'':$this->openid); // Avoid warning - $this->webcal_login = trim($this->webcal_login); - $this->phenix_login = trim($this->phenix_login); - if ($this->phenix_pass != $this->phenix_pass_crypted) - { - $this->phenix_pass = dol_hash(trim($this->phenix_pass)); - } $this->admin = $this->admin?$this->admin:0; // Check parameters @@ -1146,9 +1132,6 @@ class User extends CommonObject $sql.= ", email = '".$this->db->escape($this->email)."'"; $sql.= ", job = '".$this->db->escape($this->job)."'"; $sql.= ", signature = '".$this->db->escape($this->signature)."'"; - $sql.= ", webcal_login = '".$this->db->escape($this->webcal_login)."'"; - $sql.= ", phenix_login = '".$this->db->escape($this->phenix_login)."'"; - $sql.= ", phenix_pass = '".$this->db->escape($this->phenix_pass)."'"; $sql.= ", note = '".$this->db->escape($this->note)."'"; $sql.= ", photo = ".($this->photo?"'".$this->db->escape($this->photo)."'":"null"); $sql.= ", openid = ".($this->openid?"'".$this->db->escape($this->openid)."'":"null"); @@ -1954,6 +1937,8 @@ class User extends CommonObject { global $user,$langs; + $now=dol_now(); + // Initialise parametres $this->id=0; $this->ref = 'SPECIMEN'; @@ -1971,12 +1956,11 @@ class User extends CommonObject $this->pass='dolibspec'; //$this->pass_indatabase='dolibspec'; Set after a fetch //$this->pass_indatabase_crypted='e80ca5a88c892b0aaaf7e154853bccab'; Set after a fetch - $this->datec=time(); - $this->datem=time(); - $this->webcal_login='dolibspec'; + $this->datec=$now; + $this->datem=$now; - $this->datelastlogin=time(); - $this->datepreviouslogin=time(); + $this->datelastlogin=$now; + $this->datepreviouslogin=$now; $this->statut=1; //$this->societe_id = 1; For external users diff --git a/htdocs/webservices/server_user.php b/htdocs/webservices/server_user.php index 7ff24220b84..5b644b150bf 100644 --- a/htdocs/webservices/server_user.php +++ b/htdocs/webservices/server_user.php @@ -357,10 +357,6 @@ function getUser($authentication,$id,$ref='',$ref_ext='') 'fk_thirdparty' => $user->societe_id, 'fk_contact' => $user->contact_id, 'fk_member' => $user->fk_member, - 'webcal_login' => $user->webcal_login, - 'phenix_login' => $user->phenix_login, - 'phenix_pass' => $user->phenix_pass, - 'phenix_pass_crypted' => $user->phenix_pass_crypted, 'datelastlogin' => dol_print_date($user->datelastlogin,'dayhourrfc'), 'datepreviouslogin' => dol_print_date($user->datepreviouslogin,'dayhourrfc'), 'statut' => $user->statut, From 9a290147160cd5a706c1c176fe45613e39cb2885 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Apr 2013 09:44:09 +0200 Subject: [PATCH 33/44] New: Add color field into user table --- htdocs/install/mysql/migration/3.3.0-3.4.0.sql | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql index bd1bd8693ce..a59b5b7cdf4 100755 --- a/htdocs/install/mysql/migration/3.3.0-3.4.0.sql +++ b/htdocs/install/mysql/migration/3.3.0-3.4.0.sql @@ -204,11 +204,13 @@ CREATE TABLE llx_cronjob ALTER TABLE llx_societe MODIFY COLUMN zip varchar(25); -ALTER TABLE llx_user ADD COLUMN address varchar(255); -ALTER TABLE llx_user ADD COLUMN zip varchar(25); -ALTER TABLE llx_user ADD COLUMN town varchar(50); -ALTER TABLE llx_user ADD COLUMN fk_state integer DEFAULT 0; -ALTER TABLE llx_user ADD COLUMN fk_country integer DEFAULT 0; +ALTER TABLE llx_user ADD COLUMN address varchar(255); +ALTER TABLE llx_user ADD COLUMN zip varchar(25); +ALTER TABLE llx_user ADD COLUMN town varchar(50); +ALTER TABLE llx_user ADD COLUMN fk_state integer DEFAULT 0; +ALTER TABLE llx_user ADD COLUMN fk_country integer DEFAULT 0; +ALTER TABLE llx_user ADD COLUMN color varchar(6); + ALTER TABLE llx_product_price ADD COLUMN import_key varchar(14) AFTER price_by_qty; DROP TABLE llx_printer_ipp; From aeae7231082a55b1eaff287a47421fbe93c98fc7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Apr 2013 10:15:53 +0200 Subject: [PATCH 34/44] New: Event into calendar use different colors for different users. --- ChangeLog | 1 + htdocs/comm/action/index.php | 41 ++++++++++++++++++++++++++----- htdocs/theme/eldy/graph-color.php | 2 +- htdocs/theme/eldy/style.css.php | 2 +- 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index cbca688c6c0..ffff5a7a6e0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,7 @@ English Dolibarr ChangeLog ***** ChangeLog for 3.4 compared to 3.3.2 ***** For users: +- New: Event into calendar use different colors for different users. - New: Support revenue stamp onto invoices. - New: Add a tab "consumption" on thirdparties to list products bought/sells. - New: Some performance enhancements. diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 0b182c7645f..49a84a28d22 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -942,7 +942,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa global $user, $conf, $langs; global $filter, $filtera, $filtert, $filterd, $status; global $theme_datacolor; - global $cachethirdparties, $cachecontacts; + global $cachethirdparties, $cachecontacts, $colorindexused; print '
    '."\n"; $curtime = dol_mktime(0, 0, 0, $month, $day, $year); @@ -972,6 +972,9 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); $ymd=sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); + $nextindextouse=count($colorindexused); + //print $nextindextouse; + foreach ($eventarray as $daykey => $notused) { $annee = date('Y',$daykey); @@ -989,10 +992,12 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $color=-1; $cssclass=''; $colorindex=-1; if ((! empty($event->author->id) && $event->author->id == $user->id) || (! empty($event->usertodo->id) && $event->usertodo->id == $user->id) - || (! empty($event->userdone->id) && $event->userdone->id == $user->id)) { - $nummytasks++; $colorindex=1; $cssclass='family_mytasks'; + || (! empty($event->userdone->id) && $event->userdone->id == $user->id)) + { + $nummytasks++; $cssclass='family_mytasks'; } - else if ($event->type_code == 'ICALEVENT') { + else if ($event->type_code == 'ICALEVENT') + { $numical++; if (! empty($event->icalname)) { if (! isset($numicals[dol_string_nospecial($event->icalname)])) { @@ -1004,8 +1009,25 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $cssclass=(! empty($event->icalname)?'family_'.dol_string_nospecial($event->icalname):'family_other'); } else if ($event->type_code == 'BIRTHDAY') { $numbirthday++; $colorindex=2; $cssclass='family_birthday'; } - else { $numother++; $colorindex=2; $cssclass='family_other'; } - if ($color == -1) $color=sprintf("%02x%02x%02x",$theme_datacolor[$colorindex][0],$theme_datacolor[$colorindex][1],$theme_datacolor[$colorindex][2]); + else { $numother++; $cssclass='family_other'; } + if ($color == -1) // Color was not forced. Set color according to color index. + { + // Define color index if not yet defined + $idusertouse=($event->usertodo->id?$event->usertodo->id:0); + if (isset($colorindexused[$idusertouse])) + { + $colorindex=$colorindexused[$idusertouse]; // Color already assigned to this user + } + else + { + $colorindex=$nextindextouse; + $colorindexused[$idusertouse]=$colorindex; + if (! empty($theme_datacolor[$nextindextouse+1])) $nextindextouse++; // Prepare to use next color + } + //print '|'.($color).'='.($idusertouse?$idusertouse:0).'='.$colorindex.'
    '; + // Define color + $color=sprintf("%02x%02x%02x",$theme_datacolor[$colorindex][0],$theme_datacolor[$colorindex][1],$theme_datacolor[$colorindex][2]); + } $cssclass=$cssclass.' '.$cssclass.'_day_'.$ymd; // Show rect of event @@ -1182,6 +1204,13 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
    '."\n"; } +/** + * Change color with a delta + * + * @param string $color Color + * @param int $minus Delta + * @return string New color + */ function dol_color_minus($color, $minus) { $newcolor=$color; diff --git a/htdocs/theme/eldy/graph-color.php b/htdocs/theme/eldy/graph-color.php index e49f86bce60..ab59c7689a4 100644 --- a/htdocs/theme/eldy/graph-color.php +++ b/htdocs/theme/eldy/graph-color.php @@ -28,7 +28,7 @@ global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet; $theme_bordercolor = array(235,235,224); -$theme_datacolor = array(array(125,135,150), array(200,160,180), array(190,190,220), array(170,140,190), array(190,190,170)); +$theme_datacolor = array(array(190,190,220), array(200,160,180), array(125,135,150), array(170,140,190), array(190,190,170)); $theme_bgcolor = array(hexdec('F4'),hexdec('F4'),hexdec('F4')); $theme_bgcoloronglet = array(hexdec('DE'),hexdec('E7'),hexdec('EC')); diff --git a/htdocs/theme/eldy/style.css.php b/htdocs/theme/eldy/style.css.php index eba9a7cc86d..88da3fd4894 100644 --- a/htdocs/theme/eldy/style.css.php +++ b/htdocs/theme/eldy/style.css.php @@ -2100,7 +2100,7 @@ table.cal_month { border-spacing: 0px; } .cal_other_month { border-top: 0; border-left: solid 1px #C0C0C0; border-right: 0; border-bottom: solid 1px #C0C0C0; } .cal_current_month_right { border-right: solid 1px #E0E0E0; } .cal_other_month_right { border-right: solid 1px #C0C0C0; } -.cal_other_month { opacity: 0.6; background: #DDDDDD; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } +.cal_other_month { opacity: 0.6; background: #EAEAEA; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } .cal_past_month { opacity: 0.6; background: #EEEEEE; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } .cal_current_month { background: #FFFFFF; border-left: solid 1px #E0E0E0; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } .cal_today { background: #FFFFFF; border: solid 2px #6C7C7B; padding-: 2px; padding-: 1px; padding-top: 0px; padding-bottom: 0px; } From b52ca834a034ccf19639a36bfda41b60cf166137 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 11 Apr 2013 10:23:35 +0200 Subject: [PATCH 35/44] Optimize size of area --- htdocs/user/fiche.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/user/fiche.php b/htdocs/user/fiche.php index 779d0cf5423..3e695b63e2a 100644 --- a/htdocs/user/fiche.php +++ b/htdocs/user/fiche.php @@ -875,7 +875,7 @@ if (($action == 'create') || ($action == 'adduserldap')) print '
    '; print ''; @@ -1778,7 +1778,7 @@ else if ($caneditfield) { require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('signature',$object->signature,'',280,'dolibarr_mailings','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,8,72); + $doleditor=new DolEditor('signature',$object->signature,'',138,'dolibarr_mailings','In',false,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,72); print $doleditor->Create(1); } else From b3b0c73f319339c8fc4fc3778ef2207ead58cbca Mon Sep 17 00:00:00 2001 From: fhenry Date: Thu, 11 Apr 2013 10:51:31 +0200 Subject: [PATCH 36/44] Qual : PHP Code Sniffer --- htdocs/opensurvey/fonctions.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/opensurvey/fonctions.php b/htdocs/opensurvey/fonctions.php index 2d817c8a63c..9c3ecba0b2d 100755 --- a/htdocs/opensurvey/fonctions.php +++ b/htdocs/opensurvey/fonctions.php @@ -121,7 +121,6 @@ function get_server_name() * is_error * * @param unknown_type $cerr error number - * @param string $cerr Error value * @return boolean Error key found or not */ function is_error($cerr) From db86735fe63607c3b81e1e386f0ae057edcb7ac8 Mon Sep 17 00:00:00 2001 From: fhenry Date: Thu, 11 Apr 2013 10:52:02 +0200 Subject: [PATCH 37/44] Qual : php code sniffer --- htdocs/opensurvey/public/create_survey.php | 4 ---- htdocs/opensurvey/public/exportcsv.php | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/htdocs/opensurvey/public/create_survey.php b/htdocs/opensurvey/public/create_survey.php index 58684f30c32..729255a6ca1 100755 --- a/htdocs/opensurvey/public/create_survey.php +++ b/htdocs/opensurvey/public/create_survey.php @@ -162,11 +162,7 @@ print ''."\n"; print '
    '."\n"; -<<<<<<< HEAD -//affichage du cochage par défaut -======= // Check or not ->>>>>>> branch 'develop' of https://github.com/Dolibarr/dolibarr.git $cocheplus=''; if ($_SESSION["canedit"]) $cocheplus="checked"; diff --git a/htdocs/opensurvey/public/exportcsv.php b/htdocs/opensurvey/public/exportcsv.php index 3b1f22d2243..f933b37a317 100755 --- a/htdocs/opensurvey/public/exportcsv.php +++ b/htdocs/opensurvey/public/exportcsv.php @@ -64,10 +64,6 @@ $now=dol_now(); $nbcolonnes=substr_count($object->sujet,',')+1; $toutsujet=explode(",",$object->sujet); -<<<<<<< HEAD -//$toutsujet=str_replace("°","'",$toutsujet); -======= ->>>>>>> branch 'develop' of https://github.com/Dolibarr/dolibarr.git // affichage des sujets du sondage $input.=$langs->trans("Name").";"; @@ -154,4 +150,4 @@ header('Cache-Control: max-age=10'); echo $input; exit; -?> +?> \ No newline at end of file From 6335918d72cce20b518c5ae5bcc332d88224a8ce Mon Sep 17 00:00:00 2001 From: fhenry Date: Thu, 11 Apr 2013 17:06:53 +0200 Subject: [PATCH 38/44] Quel : indentation --- .../doc/doc_generic_order_odt.modules.php | 458 +++++++++--------- .../doc/doc_generic_invoice_odt.modules.php | 422 ++++++++-------- .../doc/doc_generic_proposal_odt.modules.php | 324 +++++++------ 3 files changed, 605 insertions(+), 599 deletions(-) diff --git a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php index 5ab40fd1e86..00658b7b9cb 100644 --- a/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php +++ b/htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -1,21 +1,21 @@ * Copyright (C) 2012 Juanjo Menent - * - * 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 http://www.gnu.org/ - */ +* +* 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 http://www.gnu.org/ +*/ /** * \file htdocs/core/modules/commande/doc/doc_generic_order_odt.modules.php @@ -86,84 +86,84 @@ class doc_generic_order_odt extends ModelePDFCommandes } - /** - * Define array with couple substitution key => substitution value - * - * @param Object $object Main object to use as data source - * @param Translate $outputlangs Lang object to use for output - * @return array Array of substitution - */ - function get_substitutionarray_object($object,$outputlangs) - { - global $conf; + /** + * Define array with couple substitution key => substitution value + * + * @param Object $object Main object to use as data source + * @param Translate $outputlangs Lang object to use for output + * @return array Array of substitution + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; - $resarray=array( - 'object_id'=>$object->id, - 'object_ref'=>$object->ref, - 'object_ref_ext'=>$object->ref_ext, - 'object_ref_customer'=>$object->ref_client, - 'object_date'=>dol_print_date($object->date,'day'), - 'object_date_delivery'=>dol_print_date($object->date_livraison,'dayhour'), - 'object_date_creation'=>dol_print_date($object->date_creation,'day'), - 'object_date_modification'=>(! empty($object->date_modification)?dol_print_date($object->date_modification,'day'):''), - 'object_date_validation'=>(! empty($object->date_validation)?dol_print_date($object->date_validation,'dayhour'):''), - 'object_date_delivery_planed'=>(! empty($object->date_livraison)?dol_print_date($object->date_livraison,'day'):''), - 'object_date_close'=>dol_print_date($object->date_cloture,'dayhour'), - 'object_payment_mode_code'=>$object->mode_reglement_code, - 'object_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement), - 'object_payment_term_code'=>$object->cond_reglement_code, - 'object_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code)!='PaymentCondition'.$object->cond_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code):$object->cond_reglement), - 'object_total_ht'=>price($object->total_ht,0,$outputlangs), - 'object_total_vat'=>price($object->total_tva,0,$outputlangs), - 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), - 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), - 'object_vatrate'=>vatrate($object->tva), - 'object_note_private'=>$object->note, - 'object_note'=>$object->note_public, - ); + $resarray=array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_ref_ext'=>$object->ref_ext, + 'object_ref_customer'=>$object->ref_client, + 'object_date'=>dol_print_date($object->date,'day'), + 'object_date_delivery'=>dol_print_date($object->date_livraison,'dayhour'), + 'object_date_creation'=>dol_print_date($object->date_creation,'day'), + 'object_date_modification'=>(! empty($object->date_modification)?dol_print_date($object->date_modification,'day'):''), + 'object_date_validation'=>(! empty($object->date_validation)?dol_print_date($object->date_validation,'dayhour'):''), + 'object_date_delivery_planed'=>(! empty($object->date_livraison)?dol_print_date($object->date_livraison,'day'):''), + 'object_date_close'=>dol_print_date($object->date_cloture,'dayhour'), + 'object_payment_mode_code'=>$object->mode_reglement_code, + 'object_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement), + 'object_payment_term_code'=>$object->cond_reglement_code, + 'object_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code)!='PaymentCondition'.$object->cond_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code):$object->cond_reglement), + 'object_total_ht'=>price($object->total_ht,0,$outputlangs), + 'object_total_vat'=>price($object->total_tva,0,$outputlangs), + 'object_total_ttc'=>price($object->total_ttc,0,$outputlangs), + 'object_total_discount_ht' => price($object->getTotalDiscount(), 0, $outputlangs), + 'object_vatrate'=>vatrate($object->tva), + 'object_note_private'=>$object->note, + 'object_note'=>$object->note_public, + ); - // Add vat by rates - foreach ($object->lines as $line) - { - if (empty($resarray['object_total_vat_'.$line->tva_tx])) $resarray['object_total_vat_'.$line->tva_tx]=0; - $resarray['object_total_vat_'.$line->tva_tx]+=$line->total_tva; - } + // Add vat by rates + foreach ($object->lines as $line) + { + if (empty($resarray['object_total_vat_'.$line->tva_tx])) $resarray['object_total_vat_'.$line->tva_tx]=0; + $resarray['object_total_vat_'.$line->tva_tx]+=$line->total_tva; + } - return $resarray; - } + return $resarray; + } - /** - * Define array with couple substitution key => substitution value - * - * @param array $line Array of lines - * @param Translate $outputlangs Lang object to use for output - * @return array Return a substitution array - */ - function get_substitutionarray_lines($line,$outputlangs) - { - global $conf; + /** + * Define array with couple substitution key => substitution value + * + * @param array $line Array of lines + * @param Translate $outputlangs Lang object to use for output + * @return array Return a substitution array + */ + function get_substitutionarray_lines($line,$outputlangs) + { + global $conf; - return array( - 'line_fulldesc'=>doc_getlinedesc($line,$outputlangs), - 'line_product_ref'=>$line->product_ref, - 'line_product_label'=>$line->product_label, - 'line_desc'=>$line->desc, - 'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits), - 'line_up'=>price($line->subprice, 0, $outputlangs), - 'line_qty'=>$line->qty, - 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''), - 'line_price_ht'=>price($line->total_ht, 0, $outputlangs), - 'line_price_ttc'=>price($line->total_ttc, 0, $outputlangs), - 'line_price_vat'=>price($line->total_tva, 0, $outputlangs), - 'line_date_start'=>$line->date_start, - 'line_date_end'=>$line->date_end - ); - } + return array( + 'line_fulldesc'=>doc_getlinedesc($line,$outputlangs), + 'line_product_ref'=>$line->product_ref, + 'line_product_label'=>$line->product_label, + 'line_desc'=>$line->desc, + 'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits), + 'line_up'=>price($line->subprice, 0, $outputlangs), + 'line_qty'=>$line->qty, + 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''), + 'line_price_ht'=>price($line->total_ht, 0, $outputlangs), + 'line_price_ttc'=>price($line->total_ttc, 0, $outputlangs), + 'line_price_vat'=>price($line->total_tva, 0, $outputlangs), + 'line_date_start'=>$line->date_start, + 'line_date_end'=>$line->date_end + ); + } /** * Return description of a module * - * @param Translate $langs Lang object to use for output + * @param Translate $langs Lang object to use for output * @return string Description */ function info($langs) @@ -191,7 +191,9 @@ class doc_generic_order_odt extends ModelePDFCommandes { $tmpdir=trim($tmpdir); $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); - if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); else { @@ -202,19 +204,19 @@ class doc_generic_order_odt extends ModelePDFCommandes $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); // Add list of substitution keys $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; - $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); $texte.= '
     '.$langs->trans("MailingStatusNotSent"); if ($user->rights->mailing->creer) { - print ''.img_delete($langs->trans("RemoveRecipient")); + print ''.img_delete($langs->trans("RemoveRecipient")); } print '
    '.$langs->trans("Request").' '.($i+1)." sql='".dol_htmlentities($newsql,ENT_NOQUOTES)."'
    '.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; @@ -1061,90 +1059,8 @@ if ($id > 0) print ''; } + llxFooter(); $db->close(); - - -/** - * Ajoute une ligne de tableau a 2 colonnes pour avoir l'option synchro calendrier - * - * @return int Retourne le nombre de lignes ajoutees - */ -function add_row_for_calendar_link() -{ - global $conf,$langs,$user; - $nbtr=0; - - // Lien avec calendrier si module active - // TODO external module - if (! empty($conf->webcalendar->enabled)) - { - if ($conf->global->PHPWEBCALENDAR_SYNCRO != 'never') - { - $langs->load("other"); - - print '
    '.$langs->trans("AddCalendarEntry","Webcalendar").''; - print ' '.$langs->transnoentities("ErrorWebcalLoginNotDefined","id."\">".$user->login.""); - print '
    global->PHPWEBCALENDAR_SYNCRO=='always' || $conf->global->PHPWEBCALENDAR_SYNCRO=='yesbydefault')?' checked':'').'>
    '.$langs->trans("AddCalendarEntry","Phenix").''; - print ' '.$langs->transnoentities("ErrorPhenixLoginNotDefined","id."\">".$user->login.""); - print '
    global->PHPPHENIX_SYNCRO=='always' || $conf->global->PHPPHENIX_SYNCRO=='yesbydefault')?' checked':'').'>
    '.$langs->trans("Signature").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('signature',GETPOST('signature'),'',280,'dolibarr_mailings','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,8,72); + $doleditor=new DolEditor('signature',GETPOST('signature'),'',138,'dolibarr_mailings','In',true,true,empty($conf->global->FCKEDITOR_ENABLE_USERSIGN)?0:1,ROWS_4,90); print $doleditor->Create(1); print '
    '; + $texte.= ''; $texte.= ''; + $texte.= ''; + $texte.= ''; $texte.= ''; - $texte.= '
    '; $texte.= ''; - $texte.= '  '; - $texte.= ''; - $texte.= '
    '; + $texte.= ''; // Scan directories if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; @@ -228,7 +230,7 @@ class doc_generic_order_odt extends ModelePDFCommandes $texte.= ''; /*$texte.= ''; - $texte.= ''; + $texte.= ''; $texte.= ''; $texte.= ''; $texte.= '';*/ @@ -245,9 +247,9 @@ class doc_generic_order_odt extends ModelePDFCommandes * @param Commande $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file - * @param int $hidedetails Do not show line details - * @param int $hidedesc Do not show desc - * @param int $hideref Do not show ref + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref * @return int 1 if OK, <=0 if KO */ function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) @@ -260,14 +262,14 @@ class doc_generic_order_odt extends ModelePDFCommandes return -1; } - // Add odtgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('odtgeneration')); - global $action; + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; if (! is_object($outputlangs)) $outputlangs=$langs; $sav_charset_output=$outputlangs->charset_output; @@ -314,7 +316,7 @@ class doc_generic_order_odt extends ModelePDFCommandes $newfiletmp=preg_replace('/\.odt/i','',$newfile); $newfiletmp=preg_replace('/template_/i','',$newfiletmp); $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); - $newfiletmp=$objectref.'_'.$newfiletmp; + $newfiletmp=$objectref.'_'.$newfiletmp; //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; $file=$dir.'/'.$newfiletmp.'.odt'; //print "newdir=".$dir; @@ -325,64 +327,64 @@ class doc_generic_order_odt extends ModelePDFCommandes dol_mkdir($conf->commande->dir_temp); - // If BILLING contact defined on invoice, we use it - $usecontact=false; - $arrayidcontact=$object->getIdContact('external','BILLING'); - if (count($arrayidcontact) > 0) - { - $usecontact=true; - $result=$object->fetch_contact($arrayidcontact[0]); - } + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } - // Recipient name - if (! empty($usecontact)) - { - // On peut utiliser le nom de la societe du contact - if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; - else $socobject = $object->client; - } - else - { - $socobject=$object->client; - } + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else $socobject = $object->client; + } + else + { + $socobject=$object->client; + } - // Make substitution - $substitutionarray=array( - '__FROM_NAME__' => $this->emetteur->nom, - '__FROM_EMAIL__' => $this->emetteur->email, - '__TOTAL_TTC__' => $object->total_ttc, - '__TOTAL_HT__' => $object->total_ht, - '__TOTAL_VAT__' => $object->total_vat - ); - complete_substitutions_array($substitutionarray, $langs, $object); - // Call the ODTSubstitution hook - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); - $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Line of free text $newfreetext=''; $paramfreetext='COMMANDE_FREE_TEXT'; - if (! empty($conf->global->$paramfreetext)) - { - $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); - } + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } - // Open and load template + // Open and load template require_once ODTPHP_PATH.'odf.php'; $odfHandler = new odf( - $srctemplatepath, - array( - 'PATH_TO_TMP' => $conf->commande->dir_temp, - 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}' + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->commande->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' ) ); // After construction $odfHandler->contentXml contains content and // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by // [!-- BEGIN lines --]*[!-- END lines --] - //print html_entity_decode($odfHandler->__toString()); - //print exit; + //print html_entity_decode($odfHandler->__toString()); + //print exit; // Make substitutions into odt of freetext @@ -393,29 +395,29 @@ class doc_generic_order_odt extends ModelePDFCommandes { } - // Make substitutions into odt of user info + // Make substitutions into odt of user info $tmparray=$this->get_substitutionarray_user($user,$outputlangs); - //var_dump($tmparray); exit; - foreach($tmparray as $key=>$value) - { - try { - if (preg_match('/logo$/',$key)) // Image - { - //var_dump($value);exit; - if (file_exists($value)) $odfHandler->setImage($key, $value); - else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } - catch(OdfException $e) - { - } - } - // Make substitutions into odt of mysoc - $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); //var_dump($tmparray); exit; foreach($tmparray as $key=>$value) { @@ -435,7 +437,7 @@ class doc_generic_order_odt extends ModelePDFCommandes { } } - // Make substitutions into odt of thirdparty + // Make substitutions into odt of thirdparty $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); foreach($tmparray as $key=>$value) { @@ -455,73 +457,73 @@ class doc_generic_order_odt extends ModelePDFCommandes } } // Replace tags of object + external modules - $tmparray=$this->get_substitutionarray_object($object,$outputlangs); - complete_substitutions_array($tmparray, $outputlangs, $object); - // Call the ODTSubstitution hook - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); - $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - foreach($tmparray as $key=>$value) - { - try { - if (preg_match('/logo$/',$key)) // Image - { - if (file_exists($value)) $odfHandler->setImage($key, $value); - else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } - catch(OdfException $e) - { - } - } + $tmparray=$this->get_substitutionarray_object($object,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } // Replace tags of lines - try - { - $listlines = $odfHandler->setSegment('lines'); - foreach ($object->lines as $line) - { - $tmparray=$this->get_substitutionarray_lines($line,$outputlangs); - complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); - // Call the ODTSubstitutionLine hook - $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); - $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - foreach($tmparray as $key => $val) - { - try - { - $listlines->setVars($key, $val, true, 'UTF-8'); - } - catch(OdfException $e) - { - } - catch(SegmentException $e) - { - } - } - $listlines->merge(); - } - $odfHandler->mergeSegment($listlines); - } - catch(OdfException $e) - { - $this->error=$e->getMessage(); - dol_syslog($this->error, LOG_WARNING); - return -1; - } + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_lines($line,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } - // Call the beforeODTSave hook + // Call the beforeODTSave hook $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - // Write new file + // Write new file //$result=$odfHandler->exportAsAttachedFile('toto'); $odfHandler->saveToDisk($file); if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); + @chmod($file, octdec($conf->global->MAIN_UMASK)); $odfHandler=null; // Destroy object diff --git a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php index 77f673f2220..512bf98be8b 100644 --- a/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php +++ b/htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -2,20 +2,20 @@ /* Copyright (C) 2010-2012 Laurent Destailleur * Copyright (C) 2012 Regis Houssin - * 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 http://www.gnu.org/ - */ +* 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 http://www.gnu.org/ +*/ /** * \file htdocs/core/modules/facture/doc/doc_generic_invoice_odt.modules.php @@ -86,55 +86,55 @@ class doc_generic_invoice_odt extends ModelePDFFactures } - /** - * Define array with couple substitution key => substitution value - * - * @param Object $object Main object to use as data source - * @param Translate $outputlangs Lang object to use for output - * @return array Array of substitution - */ - function get_substitutionarray_object($object,$outputlangs) - { - global $conf; + /** + * Define array with couple substitution key => substitution value + * + * @param Object $object Main object to use as data source + * @param Translate $outputlangs Lang object to use for output + * @return array Array of substitution + */ + function get_substitutionarray_object($object,$outputlangs) + { + global $conf; - $invoice_source=new Facture($this->db); + $invoice_source=new Facture($this->db); if ($object->fk_facture_source > 0) { - $invoice_source->fetch($object->fk_facture_source); + $invoice_source->fetch($object->fk_facture_source); } $sumpayed = $object->getSommePaiement(); $alreadypayed=price($sumpayed,0,$outputlangs); - $resarray=array( - 'object_id'=>$object->id, - 'object_ref'=>$object->ref, - 'object_ref_ext'=>$object->ref_ext, - 'object_ref_customer'=>$object->ref_client, - 'object_ref_supplier'=>(! empty($object->ref_fournisseur)?$object->ref_fournisseur:''), - 'object_source_invoice_ref'=>$invoice_source->ref, - 'object_date'=>dol_print_date($object->date,'day'), - 'object_date_limit'=>dol_print_date($object->date_lim_reglement,'day'), - 'object_date_creation'=>dol_print_date($object->date_creation,'day'), - 'object_date_modification'=>(! empty($object->date_modification)?dol_print_date($object->date_modification,'day'):''), - 'object_date_validation'=>(! empty($object->date_validation)?dol_print_date($object->date_validation,'dayhour'):''), - 'object_date_delivery_planed'=>(! empty($object->date_livraison)?dol_print_date($object->date_livraison,'day'):''), - 'object_payment_mode_code'=>$object->mode_reglement_code, - 'object_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement), - 'object_payment_term_code'=>$object->cond_reglement_code, - 'object_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code)!='PaymentCondition'.$object->cond_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code):$object->cond_reglement), - 'object_total_ht'=>price2num($object->total_ht), - 'object_total_vat'=>price2num($object->total_tva), - 'object_total_ttc'=>price2num($object->total_ttc), - 'object_total_discount_ht' => price2num($object->getTotalDiscount(), 0, $outputlangs), - 'object_vatrate'=>(isset($object->tva)?vatrate($object->tva):''), - 'object_note_private'=>$object->note, - 'object_note'=>$object->note_public, - // Payments - 'object_already_payed'=>$alreadypayed, - 'object_remain_to_pay'=>price2num($object->total_ttc - $sumpayed) - ); + $resarray=array( + 'object_id'=>$object->id, + 'object_ref'=>$object->ref, + 'object_ref_ext'=>$object->ref_ext, + 'object_ref_customer'=>$object->ref_client, + 'object_ref_supplier'=>(! empty($object->ref_fournisseur)?$object->ref_fournisseur:''), + 'object_source_invoice_ref'=>$invoice_source->ref, + 'object_date'=>dol_print_date($object->date,'day'), + 'object_date_limit'=>dol_print_date($object->date_lim_reglement,'day'), + 'object_date_creation'=>dol_print_date($object->date_creation,'day'), + 'object_date_modification'=>(! empty($object->date_modification)?dol_print_date($object->date_modification,'day'):''), + 'object_date_validation'=>(! empty($object->date_validation)?dol_print_date($object->date_validation,'dayhour'):''), + 'object_date_delivery_planed'=>(! empty($object->date_livraison)?dol_print_date($object->date_livraison,'day'):''), + 'object_payment_mode_code'=>$object->mode_reglement_code, + 'object_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement), + 'object_payment_term_code'=>$object->cond_reglement_code, + 'object_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code)!='PaymentCondition'.$object->cond_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code):$object->cond_reglement), + 'object_total_ht'=>price2num($object->total_ht), + 'object_total_vat'=>price2num($object->total_tva), + 'object_total_ttc'=>price2num($object->total_ttc), + 'object_total_discount_ht' => price2num($object->getTotalDiscount(), 0, $outputlangs), + 'object_vatrate'=>(isset($object->tva)?vatrate($object->tva):''), + 'object_note_private'=>$object->note, + 'object_note'=>$object->note_public, + // Payments + 'object_already_payed'=>$alreadypayed, + 'object_remain_to_pay'=>price2num($object->total_ttc - $sumpayed) + ); - // Add vat by rates + // Add vat by rates foreach ($object->lines as $line) { if (empty($resarray['object_total_vat_'.$line->tva_tx])) $resarray['object_total_vat_'.$line->tva_tx]=0; @@ -152,41 +152,41 @@ class doc_generic_invoice_odt extends ModelePDFFactures $resarray = $this->fill_substitutionarray_with_extrafields($object,$resarray,$extrafields,$array_key='object',$outputlangs); } - return $resarray; - } + return $resarray; + } - /** - * Define array with couple substitution key => substitution value - * - * @param array $line Array of lines - * @param Translate $outputlangs Lang object to use for output - * @return array Return substitution array - */ - function get_substitutionarray_lines($line,$outputlangs) - { - global $conf; + /** + * Define array with couple substitution key => substitution value + * + * @param array $line Array of lines + * @param Translate $outputlangs Lang object to use for output + * @return array Return substitution array + */ + function get_substitutionarray_lines($line,$outputlangs) + { + global $conf; - return array( - 'line_fulldesc'=>doc_getlinedesc($line,$outputlangs), - 'line_product_ref'=>$line->product_ref, - 'line_product_label'=>$line->product_label, - 'line_desc'=>$line->desc, - 'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits), - 'line_up'=>price($line->subprice, 0, $outputlangs), - 'line_qty'=>$line->qty, - 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''), - 'line_price_ht'=>price2num($line->total_ht), - 'line_price_ttc'=>price2num($line->total_ttc), - 'line_price_vat'=>price2num($line->total_tva), - 'line_date_start'=>dol_print_date($line->date_start, 'day', false, $outputlangs), - 'line_date_end'=>dol_print_date($line->date_end, 'day', false, $outputlangs), - ); - } + return array( + 'line_fulldesc'=>doc_getlinedesc($line,$outputlangs), + 'line_product_ref'=>$line->product_ref, + 'line_product_label'=>$line->product_label, + 'line_desc'=>$line->desc, + 'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits), + 'line_up'=>price($line->subprice, 0, $outputlangs), + 'line_qty'=>$line->qty, + 'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''), + 'line_price_ht'=>price2num($line->total_ht), + 'line_price_ttc'=>price2num($line->total_ttc), + 'line_price_vat'=>price2num($line->total_tva), + 'line_date_start'=>dol_print_date($line->date_start, 'day', false, $outputlangs), + 'line_date_end'=>dol_print_date($line->date_end, 'day', false, $outputlangs), + ); + } /** * Return description of a module * - * @param Translate $langs Lang object to use for output + * @param Translate $langs Lang object to use for output * @return string Description */ function info($langs) @@ -214,7 +214,9 @@ class doc_generic_invoice_odt extends ModelePDFFactures { $tmpdir=trim($tmpdir); $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); - if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); else { @@ -225,19 +227,19 @@ class doc_generic_invoice_odt extends ModelePDFFactures $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); // Add list of substitution keys $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; - $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); $texte.= ''; + $texte.= ''; $texte.= ''; + $texte.= ''; + $texte.= ''; $texte.= ''; - $texte.= '
    '; $texte.= ''; - $texte.= '  '; - $texte.= ''; - $texte.= '
    '; + $texte.= ''; // Scan directories if (count($listofdir)) $texte.=$langs->trans("NumberOfModelFilesFound").': '.count($listoffiles).''; @@ -251,7 +253,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures $texte.= ''; /*$texte.= ''; - $texte.= ''; + $texte.= ''; $texte.= ''; $texte.= ''; $texte.= '';*/ @@ -268,9 +270,9 @@ class doc_generic_invoice_odt extends ModelePDFFactures * @param Facture $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file - * @param int $hidedetails Do not show line details - * @param int $hidedesc Do not show desc - * @param int $hideref Do not show ref + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref * @return int 1 if OK, <=0 if KO */ function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) @@ -283,14 +285,14 @@ class doc_generic_invoice_odt extends ModelePDFFactures return -1; } - // Add odtgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('odtgeneration')); - global $action; + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; if (! is_object($outputlangs)) $outputlangs=$langs; $sav_charset_output=$outputlangs->charset_output; @@ -337,7 +339,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures $newfiletmp=preg_replace('/\.odt/i','',$newfile); $newfiletmp=preg_replace('/template_/i','',$newfiletmp); $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); - $newfiletmp=$objectref.'_'.$newfiletmp; + $newfiletmp=$objectref.'_'.$newfiletmp; //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; $file=$dir.'/'.$newfiletmp.'.odt'; //print "newdir=".$dir; @@ -348,70 +350,70 @@ class doc_generic_invoice_odt extends ModelePDFFactures dol_mkdir($conf->facture->dir_temp); - // If BILLING contact defined on invoice, we use it - $usecontact=false; - $arrayidcontact=$object->getIdContact('external','BILLING'); - if (count($arrayidcontact) > 0) - { - $usecontact=true; - $result=$object->fetch_contact($arrayidcontact[0]); - } + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } - // Recipient name - if (! empty($usecontact)) - { - // On peut utiliser le nom de la societe du contact - if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; - else $socobject = $object->client; - } - else - { - $socobject=$object->client; - } + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else $socobject = $object->client; + } + else + { + $socobject=$object->client; + } - // Fetch info for linked propal - $linked_propal = $object->fetchObjectLinked('','','',''); - //print_r($object->linkedObjects['propal']); exit; + // Fetch info for linked propal + $linked_propal = $object->fetchObjectLinked('','','',''); + //print_r($object->linkedObjects['propal']); exit; - $propal_object = $object->linkedObjects['propal'][0]; + $propal_object = $object->linkedObjects['propal'][0]; - // Make substitution - $substitutionarray=array( - '__FROM_NAME__' => $this->emetteur->nom, - '__FROM_EMAIL__' => $this->emetteur->email, - '__TOTAL_TTC__' => $object->total_ttc, - '__TOTAL_HT__' => $object->total_ht, - '__TOTAL_VAT__' => $object->total_tva - ); - complete_substitutions_array($substitutionarray, $langs, $object); - // Call the ODTSubstitution hook - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); - $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_tva + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Line of free text $newfreetext=''; $paramfreetext='FACTURE_FREE_TEXT'; - if (! empty($conf->global->$paramfreetext)) - { - $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); - } + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } - // Open and load template + // Open and load template require_once ODTPHP_PATH.'odf.php'; $odfHandler = new odf( - $srctemplatepath, - array( - 'PATH_TO_TMP' => $conf->facture->dir_temp, - 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}' + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->facture->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' ) ); // After construction $odfHandler->contentXml contains content and // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by // [!-- BEGIN lines --]*[!-- END lines --] - //print html_entity_decode($odfHandler->__toString()); - //print exit; + //print html_entity_decode($odfHandler->__toString()); + //print exit; // Make substitutions into odt of freetext @@ -422,7 +424,7 @@ class doc_generic_invoice_odt extends ModelePDFFactures { } - // Make substitutions into odt of user info + // Make substitutions into odt of user info $array_user=$this->get_substitutionarray_user($user,$outputlangs); $array_soc=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); $array_thirdparty=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); @@ -432,74 +434,74 @@ class doc_generic_invoice_odt extends ModelePDFFactures $tmparray = array_merge($array_user,$array_soc,$array_thirdparty,$array_objet,$array_propal); complete_substitutions_array($tmparray, $outputlangs, $object); - // Call the ODTSubstitution hook - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); - $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - //var_dump($tmparray); exit; - foreach($tmparray as $key=>$value) - { - try { - if (preg_match('/logo$/',$key)) // Image - { - //var_dump($value);exit; - if (file_exists($value)) $odfHandler->setImage($key, $value); - else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } - catch(OdfException $e) - { - } - } + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } // Replace tags of lines - try - { - $listlines = $odfHandler->setSegment('lines'); - foreach ($object->lines as $line) - { - $tmparray=$this->get_substitutionarray_lines($line,$outputlangs); - complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); - // Call the ODTSubstitutionLine hook - $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); - $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - foreach($tmparray as $key => $val) - { - try - { - $listlines->setVars($key, $val, true, 'UTF-8'); - } - catch(OdfException $e) - { - } - catch(SegmentException $e) - { - } - } - $listlines->merge(); - } - $odfHandler->mergeSegment($listlines); - } - catch(OdfException $e) - { - $this->error=$e->getMessage(); - dol_syslog($this->error, LOG_WARNING); - return -1; - } + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_lines($line,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } - // Call the beforeODTSave hook + // Call the beforeODTSave hook $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - // Write new file + // Write new file //$result=$odfHandler->exportAsAttachedFile('toto'); $odfHandler->saveToDisk($file); if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); + @chmod($file, octdec($conf->global->MAIN_UMASK)); $odfHandler=null; // Destroy object diff --git a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php index df61cbed461..26d67f09a32 100644 --- a/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php +++ b/htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -1,21 +1,21 @@ * Copyright (C) 2012 Juanjo Menent - * - * 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 http://www.gnu.org/ - */ +* +* 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 http://www.gnu.org/ +*/ /** * \file htdocs/core/modules/propale/doc/doc_generic_proposal_odt.modules.php @@ -89,7 +89,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales /** * Return description of a module * - * @param Translate $langs Lang object to use for output + * @param Translate $langs Lang object to use for output * @return string Description */ function info($langs) @@ -123,7 +123,9 @@ class doc_generic_proposal_odt extends ModelePDFPropales { $tmpdir=trim($tmpdir); $tmpdir=preg_replace('/DOL_DATA_ROOT/',DOL_DATA_ROOT,$tmpdir); - if (! $tmpdir) { unset($listofdir[$key]); continue; } + if (! $tmpdir) { + unset($listofdir[$key]); continue; + } if (! is_dir($tmpdir)) $texttitle.=img_warning($langs->trans("ErrorDirNotFound",$tmpdir),0); else { @@ -134,19 +136,19 @@ class doc_generic_proposal_odt extends ModelePDFPropales $texthelp=$langs->trans("ListOfDirectoriesForModelGenODT"); // Add list of substitution keys $texthelp.='
    '.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'
    '; - $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it + $texthelp.=$langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it $texte.= $form->textwithpicto($texttitle,$texthelp,1,'help','',1); $texte.= ''; + $texte.= ''; $texte.= ''; + $texte.= ''; + $texte.= ''; $texte.= ''; - $texte.= '
    '; $texte.= ''; - $texte.= '  '; - $texte.= ''; - $texte.= '
    '; + $texte.= ''; // Scan directories if (count($listofdir)) @@ -190,7 +192,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales $texte.= ''; /*$texte.= ''; - $texte.= ''; + $texte.= ''; $texte.= ''; $texte.= ''; $texte.= '';*/ @@ -207,9 +209,9 @@ class doc_generic_proposal_odt extends ModelePDFPropales * @param Propale $object Object source to build document * @param Translate $outputlangs Lang output object * @param string $srctemplatepath Full path of source filename for generator using a template file - * @param int $hidedetails Do not show line details - * @param int $hidedesc Do not show desc - * @param int $hideref Do not show ref + * @param int $hidedetails Do not show line details + * @param int $hidedesc Do not show desc + * @param int $hideref Do not show ref * @return int 1 if OK, <=0 if KO */ function write_file($object,$outputlangs,$srctemplatepath,$hidedetails=0,$hidedesc=0,$hideref=0) @@ -222,14 +224,14 @@ class doc_generic_proposal_odt extends ModelePDFPropales return -1; } - // Add odtgeneration hook - if (! is_object($hookmanager)) - { - include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; - $hookmanager=new HookManager($this->db); - } - $hookmanager->initHooks(array('odtgeneration')); - global $action; + // Add odtgeneration hook + if (! is_object($hookmanager)) + { + include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; + $hookmanager=new HookManager($this->db); + } + $hookmanager->initHooks(array('odtgeneration')); + global $action; if (! is_object($outputlangs)) $outputlangs=$langs; $sav_charset_output=$outputlangs->charset_output; @@ -276,7 +278,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales $newfiletmp=preg_replace('/\.odt/i','',$newfile); $newfiletmp=preg_replace('/template_/i','',$newfiletmp); $newfiletmp=preg_replace('/modele_/i','',$newfiletmp); - $newfiletmp=$objectref.'_'.$newfiletmp; + $newfiletmp=$objectref.'_'.$newfiletmp; //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt'; $file=$dir.'/'.$newfiletmp.'.odt'; //print "newdir=".$dir; @@ -287,64 +289,64 @@ class doc_generic_proposal_odt extends ModelePDFPropales dol_mkdir($conf->propal->dir_temp); - // If BILLING contact defined on invoice, we use it - $usecontact=false; - $arrayidcontact=$object->getIdContact('external','BILLING'); - if (count($arrayidcontact) > 0) - { - $usecontact=true; - $result=$object->fetch_contact($arrayidcontact[0]); - } + // If BILLING contact defined on invoice, we use it + $usecontact=false; + $arrayidcontact=$object->getIdContact('external','BILLING'); + if (count($arrayidcontact) > 0) + { + $usecontact=true; + $result=$object->fetch_contact($arrayidcontact[0]); + } - // Recipient name - if (! empty($usecontact)) - { - // On peut utiliser le nom de la societe du contact - if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; - else $socobject = $object->client; - } - else - { - $socobject=$object->client; - } + // Recipient name + if (! empty($usecontact)) + { + // On peut utiliser le nom de la societe du contact + if (! empty($conf->global->MAIN_USE_COMPANY_NAME_OF_CONTACT)) $socobject = $object->contact; + else $socobject = $object->client; + } + else + { + $socobject=$object->client; + } - // Make substitution - $substitutionarray=array( - '__FROM_NAME__' => $this->emetteur->nom, - '__FROM_EMAIL__' => $this->emetteur->email, - '__TOTAL_TTC__' => $object->total_ttc, - '__TOTAL_HT__' => $object->total_ht, - '__TOTAL_VAT__' => $object->total_vat - ); - complete_substitutions_array($substitutionarray, $langs, $object); - // Call the ODTSubstitution hook - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); - $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + // Make substitution + $substitutionarray=array( + '__FROM_NAME__' => $this->emetteur->nom, + '__FROM_EMAIL__' => $this->emetteur->email, + '__TOTAL_TTC__' => $object->total_ttc, + '__TOTAL_HT__' => $object->total_ht, + '__TOTAL_VAT__' => $object->total_vat + ); + complete_substitutions_array($substitutionarray, $langs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$substitutionarray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks // Line of free text $newfreetext=''; $paramfreetext='PROPALE_FREE_TEXT'; - if (! empty($conf->global->$paramfreetext)) - { - $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); - } + if (! empty($conf->global->$paramfreetext)) + { + $newfreetext=make_substitutions($conf->global->$paramfreetext,$substitutionarray); + } - // Open and load template + // Open and load template require_once ODTPHP_PATH.'odf.php'; $odfHandler = new odf( - $srctemplatepath, - array( - 'PATH_TO_TMP' => $conf->propal->dir_temp, - 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. - 'DELIMITER_LEFT' => '{', - 'DELIMITER_RIGHT' => '}' + $srctemplatepath, + array( + 'PATH_TO_TMP' => $conf->propal->dir_temp, + 'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy. + 'DELIMITER_LEFT' => '{', + 'DELIMITER_RIGHT' => '}' ) ); // After construction $odfHandler->contentXml contains content and // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by // [!-- BEGIN lines --]*[!-- END lines --] - //print html_entity_decode($odfHandler->__toString()); - //print exit; + //print html_entity_decode($odfHandler->__toString()); + //print exit; // Make substitutions into odt of freetext @@ -355,29 +357,29 @@ class doc_generic_proposal_odt extends ModelePDFPropales { } - // Make substitutions into odt of user info + // Make substitutions into odt of user info $tmparray=$this->get_substitutionarray_user($user,$outputlangs); - //var_dump($tmparray); exit; - foreach($tmparray as $key=>$value) - { - try { - if (preg_match('/logo$/',$key)) // Image - { - //var_dump($value);exit; - if (file_exists($value)) $odfHandler->setImage($key, $value); - else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } - catch(OdfException $e) - { - } - } - // Make substitutions into odt of mysoc - $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); + //var_dump($tmparray); exit; + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + //var_dump($value);exit; + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } + // Make substitutions into odt of mysoc + $tmparray=$this->get_substitutionarray_mysoc($mysoc,$outputlangs); //var_dump($tmparray); exit; foreach($tmparray as $key=>$value) { @@ -397,7 +399,7 @@ class doc_generic_proposal_odt extends ModelePDFPropales { } } - // Make substitutions into odt of thirdparty + // Make substitutions into odt of thirdparty $tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs); foreach($tmparray as $key=>$value) { @@ -417,74 +419,74 @@ class doc_generic_proposal_odt extends ModelePDFPropales } } // Replace tags of object + external modules - $tmparray=$this->get_substitutionarray_propal($object,$outputlangs); - //print_r($tmparray); exit; - complete_substitutions_array($tmparray, $outputlangs, $object); - // Call the ODTSubstitution hook - $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); - $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - foreach($tmparray as $key=>$value) - { - try { - if (preg_match('/logo$/',$key)) // Image - { - if (file_exists($value)) $odfHandler->setImage($key, $value); - else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); - } - else // Text - { - $odfHandler->setVars($key, $value, true, 'UTF-8'); - } - } - catch(OdfException $e) - { - } - } + $tmparray=$this->get_substitutionarray_propal($object,$outputlangs); + //print_r($tmparray); exit; + complete_substitutions_array($tmparray, $outputlangs, $object); + // Call the ODTSubstitution hook + $parameters=array('file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray); + $reshook=$hookmanager->executeHooks('ODTSubstitution',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key=>$value) + { + try { + if (preg_match('/logo$/',$key)) // Image + { + if (file_exists($value)) $odfHandler->setImage($key, $value); + else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8'); + } + else // Text + { + $odfHandler->setVars($key, $value, true, 'UTF-8'); + } + } + catch(OdfException $e) + { + } + } // Replace tags of lines - try - { - $listlines = $odfHandler->setSegment('lines'); - foreach ($object->lines as $line) - { - $tmparray=$this->get_substitutionarray_propal_lines($line,$outputlangs); - complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); - // Call the ODTSubstitutionLine hook - $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); - $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - foreach($tmparray as $key => $val) - { - try - { - $listlines->setVars($key, $val, true, 'UTF-8'); - } - catch(OdfException $e) - { - } - catch(SegmentException $e) - { - } - } - $listlines->merge(); - } - $odfHandler->mergeSegment($listlines); - } - catch(OdfException $e) - { - $this->error=$e->getMessage(); - dol_syslog($this->error, LOG_WARNING); - return -1; - } + try + { + $listlines = $odfHandler->setSegment('lines'); + foreach ($object->lines as $line) + { + $tmparray=$this->get_substitutionarray_propal_lines($line,$outputlangs); + complete_substitutions_array($tmparray, $outputlangs, $object, $line, "completesubstitutionarray_lines"); + // Call the ODTSubstitutionLine hook + $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs,'substitutionarray'=>&$tmparray,'line'=>$line); + $reshook=$hookmanager->executeHooks('ODTSubstitutionLine',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks + foreach($tmparray as $key => $val) + { + try + { + $listlines->setVars($key, $val, true, 'UTF-8'); + } + catch(OdfException $e) + { + } + catch(SegmentException $e) + { + } + } + $listlines->merge(); + } + $odfHandler->mergeSegment($listlines); + } + catch(OdfException $e) + { + $this->error=$e->getMessage(); + dol_syslog($this->error, LOG_WARNING); + return -1; + } - // Call the beforeODTSave hook + // Call the beforeODTSave hook $parameters=array('odfHandler'=>&$odfHandler,'file'=>$file,'object'=>$object,'outputlangs'=>$outputlangs); $reshook=$hookmanager->executeHooks('beforeODTSave',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - // Write new file + // Write new file //$result=$odfHandler->exportAsAttachedFile('toto'); $odfHandler->saveToDisk($file); if (! empty($conf->global->MAIN_UMASK)) - @chmod($file, octdec($conf->global->MAIN_UMASK)); + @chmod($file, octdec($conf->global->MAIN_UMASK)); $odfHandler=null; // Destroy object From 9b2cbfef054a8e7b7757b7d17cecb78d6de8fb5a Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 11 Apr 2013 17:10:11 +0200 Subject: [PATCH 39/44] Fix: for avoid problem with multicompany thirdparty sharing --- htdocs/core/class/conf.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 764438a273c..06510e28199 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -331,7 +331,8 @@ class Conf // societe if (empty($this->global->SOCIETE_CODECLIENT_ADDON)) $this->global->SOCIETE_CODECLIENT_ADDON="mod_codeclient_leopard"; - if (empty($this->global->SOCIETE_CODEFOURNISSEUR_ADDON)) $this->global->SOCIETE_CODEFOURNISSEUR_ADDON=$this->global->SOCIETE_CODECLIENT_ADDON; + // Unused constant and for avoid problem with multicompany sharing + //if (empty($this->global->SOCIETE_CODEFOURNISSEUR_ADDON)) $this->global->SOCIETE_CODEFOURNISSEUR_ADDON=$this->global->SOCIETE_CODECLIENT_ADDON; if (empty($this->global->SOCIETE_CODECOMPTA_ADDON)) $this->global->SOCIETE_CODECOMPTA_ADDON="mod_codecompta_panicum"; // Security From 030752c4c6fb5451f1c40b0447f14519fd54c62c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 11 Apr 2013 17:24:17 +0200 Subject: [PATCH 40/44] Fix: missing to rename constant --- htdocs/fourn/class/fournisseur.commande.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 90e5afa1726..2c6ad45f30f 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -603,7 +603,7 @@ class CommandeFournisseur extends CommonOrder /** * Renvoie la reference de commande suivante non utilisee en fonction du modele - * de numerotation actif defini dans COMMANDE_SUPPLIER_ADDON + * de numerotation actif defini dans COMMANDE_SUPPLIER_ADDON_NUMBER * * @param Societe $soc objet societe * @return string reference libre pour la facture @@ -615,14 +615,14 @@ class CommandeFournisseur extends CommonOrder $dir = DOL_DOCUMENT_ROOT .'/core/modules/supplier_order/'; - if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON)) + if (! empty($conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER)) { - $file = $conf->global->COMMANDE_SUPPLIER_ADDON.'.php'; + $file = $conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER.'.php'; if (is_readable($dir.'/'.$file)) { // Definition du nom de modele de numerotation de commande fournisseur - $modName=$conf->global->COMMANDE_SUPPLIER_ADDON; + $modName=$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER; require_once $dir.'/'.$file; // Recuperation de la nouvelle reference @@ -643,7 +643,7 @@ class CommandeFournisseur extends CommonOrder } else { - print $langs->trans("Error")." ".$langs->trans("Error_FailedToLoad_COMMANDE_SUPPLIER_ADDON_File",$conf->global->COMMANDE_SUPPLIER_ADDON); + print $langs->trans("Error")." ".$langs->trans("Error_FailedToLoad_COMMANDE_SUPPLIER_ADDON_File",$conf->global->COMMANDE_SUPPLIER_ADDON_NUMBER); return -2; } } From af40d27eb57012a1b04b1560cb17ad7036505145 Mon Sep 17 00:00:00 2001 From: fhenry Date: Thu, 11 Apr 2013 17:26:49 +0200 Subject: [PATCH 41/44] Remove require_once from odf.php because it cause regression. --- htdocs/includes/odtphp/odf.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 2d5c991fb77..4f737d15b71 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -1,6 +1,4 @@ Date: Thu, 11 Apr 2013 17:31:24 +0200 Subject: [PATCH 42/44] Add hook for substitution --- .../project/pdf/doc_generic_project_odt.modules.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php index 912c9fd25ad..218ae0620dd 100644 --- a/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php +++ b/htdocs/core/modules/project/pdf/doc_generic_project_odt.modules.php @@ -125,7 +125,7 @@ class doc_generic_project_odt extends ModelePDFProjects 'object_note_private'=>$object->note_private, 'object_note_public'=>$object->note_public, 'object_public'=>$object->public, - 'object_statut'=>html_entity_decode($object->getLibStatut()) + 'object_statut'=>$object->getLibStatut() ); } @@ -478,7 +478,6 @@ class doc_generic_project_odt extends ModelePDFProjects // Make substitutions into odt of user info $tmparray=$this->get_substitutionarray_user($user,$outputlangs); - //var_dump($tmparray); exit; foreach($tmparray as $key=>$value) { try { @@ -805,7 +804,6 @@ class doc_generic_project_odt extends ModelePDFProjects $contact['fullname']=$objectdetail->getFullName($outputlangs,1); $tmparray=$this->get_substitutionarray_project_contacts($contact,$outputlangs); - complete_substitutions_array($tmparray, $outputlangs, $contact, $contact, "completesubstitutionarray_lines"); foreach($tmparray as $key => $val) { try @@ -937,7 +935,7 @@ class doc_generic_project_odt extends ModelePDFProjects $ref_array['amountttc']=''; } - $ref_array['status']=html_entity_decode($element->getLibStatut(0)); + $ref_array['status']=$element->getLibStatut(0); $tmparray=$this->get_substitutionarray_project_reference($ref_array,$outputlangs); @@ -975,7 +973,8 @@ class doc_generic_project_odt extends ModelePDFProjects // Write new file - $odfHandler->saveToDisk($file); + $odfHandler->saveToDisk($file); + //$odfHandler->exportAsAttachedPDF($file); if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); From e209959c90dc11de2618d0f61dbdee00cacc1984 Mon Sep 17 00:00:00 2001 From: simnandez Date: Thu, 11 Apr 2013 17:58:56 +0200 Subject: [PATCH 43/44] Fix: Remove ChangeLog duplicity --- ChangeLog | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffff5a7a6e0..85ac7de62a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -89,24 +89,6 @@ WARNING: If you used external modules, some of them may need to be upgraded due -***** ChangeLog for 3.3.2 compared to 3.3.1 ***** - --Fix: Ducth (nl_NL) translation --Fix: [ bug #790 ] Spanish localtax RE not being correctly calculated --Generalize fix: file with a specific mask not found, again - - - -***** ChangeLog for 3.3.1 compared to 3.3 ***** - -- Fix: [ bug #733 ] Mass emailing tools do not support
  • '."\n"; +print ''; +// Todo : add CSRF protection +print '
    '."\n"; +print '

    '."\n"; + +// Debut de l'affichage des resultats du sondage +print ''."\n"; + +//recuperation des utilisateurs du sondage +$sql = 'SELECT * FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_users'; +$sql = $connect->Prepare($sql); +$user_studs = $connect->Execute($sql, array($numsondage)); + +//si le sondage est un sondage de date +if ($object->format=="D"||$object->format=="D+") +{ + //affichage des sujets du sondage + print ''."\n"; + print ''."\n"; + + //affichage des années + $colspan=1; + for ($i=0;$i'.date('Y', intval($toutsujet[$i])).''."\n"; + $colspan=1; + } + } + + print ''."\n"; + print ''."\n"; + print ''."\n"; + + //affichage des mois + $colspan=1; + for ($i=0;$i'.dol_print_date($cur, "%B").''."\n"; + $colspan=1; + } + } + + print ''."\n"; + print ''."\n"; + print ''."\n"; + + //affichage des jours + $colspan=1; + for ($i=0;$i'.dol_print_date($cur, "%a %e").''."\n"; + $colspan=1; + } + } + + print ''."\n"; + + //affichage des horaires + if (strpos($object->sujet, '@') !== false) { + print ''."\n"; + print ''."\n"; + + for ($i=0; isset($toutsujet[$i]); $i++) { + $heures=explode('@',$toutsujet[$i]); + if (isset($heures[1])) { + print ''."\n"; + } else { + print ''."\n"; + } + } + + print ''."\n"; + } +} +else +{ + $toutsujet=str_replace("°","'",$toutsujet); + + //affichage des sujets du sondage + print ''."\n"; + print ''."\n"; + + for ($i=0; isset($toutsujet[$i]); $i++) + { + $tmp=explode('@',$toutsujet[$i]); + print ''."\n"; + } + + print ''."\n"; +} + + +// Loop on each answer +$sumfor = array(); +$sumagainst = array(); +$compteur = 0; + +$sql = 'SELECT * FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_users'; +$sql = $connect->Prepare($sql); +$user_studs = $connect->Execute($sql, array($numsondage)); + +while ($data = $user_studs->FetchNextObject(false)) +{ + $ensemblereponses = $data->reponses; + $nombase=str_replace("°","'",$data->nom); + + print ''."\n"; + + // ligne d'un usager pré-authentifié + $mod_ok = ($object->canedit || (! empty($nombase) && in_array($nombase, $listofvoters))); + + // Name + print ''."\n"; + + // pour chaque colonne + for ($i=0; $i < $nbcolonnes; $i++) + { + $car = substr($ensemblereponses, $i, 1); + if ($compteur == $ligneamodifier) + { + print ''."\n"; + } + else + { + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + if (((string) $car) == "1") print ''."\n"; + else print ''."\n"; + // Total + if (isset($sumfor[$i]) === false) $sumfor[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + if (((string) $car) == "1") print ''."\n"; + else if (((string) $car) == "0") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (! isset($sumagainst[$i])) $sumagainst[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + if (((string) $car) == "0") $sumagainst[$i]++; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + if (((string) $car) == "1") print ''."\n"; + else if (((string) $car) == "0") print ''."\n"; + else print ''."\n"; + // Total + if (! isset($sumfor[$i])) $sumfor[$i] = 0; + if (! isset($sumagainst[$i])) $sumagainst[$i] = 0; + if (((string) $car) == "1") $sumfor[$i]++; + if (((string) $car) == "0") $sumagainst[$i]++; + } + } + } + + // Button edit at end of line + if ($compteur != $ligneamodifier && $mod_ok) + { + print ''."\n"; + } + + //demande de confirmation pour modification de ligne + for ($i=0;$i<$nblignes;$i++) { + if (isset($_POST["modifierligne$i"])) { + if ($compteur == $i) { + print ''."\n"; + } + } + } + + $compteur++; + print ''."\n"; +} + +// Add line to add new record +if ($ligneamodifier < 0 && (! isset($_SESSION['nom']))) +{ + print ''."\n"; + print ''."\n"; + + // affichage des cases de formulaire checkbox pour un nouveau choix + for ($i=0;$i<$nbcolonnes;$i++) + { + print ''."\n"; + } + + // Affichage du bouton de formulaire pour inscrire un nouvel utilisateur dans la base + print ''."\n"; + print ''."\n"; +} + +// Select value of best choice (for checkbox columns only) +$nbofcheckbox=0; +for ($i=0; $i < $nbcolonnes; $i++) +{ + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] != 'checkbox') continue; + $nbofcheckbox++; + if (isset($sumfor[$i])) + { + if ($i == 0) + { + $meilleurecolonne = $sumfor[$i]; + } + if (! isset($meilleurecolonne) || $sumfor[$i] > $meilleurecolonne) + { + $meilleurecolonne = $sumfor[$i]; + } + } +} + +// Show line total +print ''."\n"; +print ''."\n"; +for ($i = 0; $i < $nbcolonnes; $i++) +{ + $showsumfor = isset($sumfor[$i])?$sumfor[$i]:''; + $showsumagainst = isset($sumagainst[$i])?$sumagainst[$i]:''; + if (empty($showsumfor)) $showsumfor = 0; + if (empty($showsumagainst)) $showsumagainst = 0; + + print ''."\n"; +} +print ''; +// Show picto winnner +if ($nbofcheckbox >= 2) +{ + print ''."\n"; + print ''."\n"; + for ($i=0; $i < $nbcolonnes; $i++) + { + //print 'xx'.(! empty($listofanswers[$i]['format'])).'-'.$sumfor[$i].'-'.$meilleurecolonne; + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'checkbox' && isset($sumfor[$i]) && isset($meilleurecolonne) && $sumfor[$i] == $meilleurecolonne) + { + print ''."\n"; + } else { + print ''."\n"; + } + } + print ''."\n"; +} +print '
    '.$heures[1].'
    '.$tmp[0].'
    '.$nombase.''; + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + print ''; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("No"),'1'=>$langs->trans("Yes")); + print $form->selectarray("choix".$i, $arraychoice, $car); + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("Against"),'1'=>$langs->trans("For")); + print $form->selectarray("choix".$i, $arraychoice, $car); + } + print 'OKKO'.$langs->trans("Yes").''.$langs->trans("No").' '.$langs->trans("For").''.$langs->trans("Against").' 
    '."\n"; + if (isset($_SESSION['nom'])) + { + print ''.$_SESSION['nom']."\n"; + } else { + print ''."\n"; + } + print ''; + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) + { + print ''; + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("No"),'1'=>$langs->trans("Yes")); + print $form->selectarray("choix".$i, $arraychoice, GETPOST('choix'.$i)); + } + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') + { + $arraychoice=array('2'=>' ','0'=>$langs->trans("Against"),'1'=>$langs->trans("For")); + print $form->selectarray("choix".$i, $arraychoice, GETPOST('choix'.$i)); + } + print '
    '. $langs->trans("Total") .''; + if (empty($listofanswers[$i]['format']) || ! in_array($listofanswers[$i]['format'],array('yesno','foragainst'))) print $showsumfor; + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'yesno') print $langs->trans("Yes").': '.$showsumfor.'
    '.$langs->trans("No").': '.$showsumagainst; + if (! empty($listofanswers[$i]['format']) && $listofanswers[$i]['format'] == 'foragainst') print $langs->trans("For").': '.$showsumfor.'
    '.$langs->trans("Against").': '.$showsumagainst; + print '
    '."\n"; +print '
    '."\n"; + +$toutsujet=explode(",",$object->sujet); +$toutsujet=str_replace("°","'",$toutsujet); + +$compteursujet=0; +$meilleursujet = ''; + +for ($i = 0; $i < $nbcolonnes; $i++) { + if (isset($sumfor[$i]) && isset($meilleurecolonne) && $sumfor[$i] == $meilleurecolonne) { + $meilleursujet.=", "; + if ($object->format=="D"||$object->format=="D+") { + $meilleursujetexport = $toutsujet[$i]; + + if (strpos($toutsujet[$i], '@') !== false) { + $toutsujetdate = explode("@", $toutsujet[$i]); + $meilleursujet .= dol_print_date($toutsujetdate[0],'daytext'). ' ('.dol_print_date($toutsujetdate[0],'%A').')' . _("for") . ' ' . $toutsujetdate[1]; + } else { + $meilleursujet .= dol_print_date($toutsujet[$i],'daytext'). ' ('.dol_print_date($toutsujet[$i],'%A').')'; + } + } else { + $tmps=explode('@',$toutsujet[$i]); + $meilleursujet .= $tmps[0]; + } + + $compteursujet++; + } +} + +$meilleursujet=substr("$meilleursujet", 1); +$meilleursujet = str_replace("°", "'", $meilleursujet); + + +// Show best choice +if ($nbofcheckbox >= 2) +{ + $vote_str = $langs->trans('votes'); + print '

    '."\n"; + + if ($compteursujet == "1" && isset($meilleurecolonne)) { + print 'Meilleur choix ' . $langs->trans('TheBestChoice') . ": $meilleursujet " . $langs->trans('with') . " $meilleurecolonne " . $vote_str . ".\n"; + } elseif (isset($meilleurecolonne)) { + print 'Meilleur choix ' . $langs->trans('TheBestChoices') . ": $meilleursujet " . $langs->trans('with') . " $meilleurecolonne " . $vote_str . ".\n"; + } + + print '


    '; +} + +print '
    '; + + +// Comment list +$sql = 'SELECT id_comment, usercomment, comment'; +$sql.= ' FROM '.MAIN_DB_PREFIX.'opensurvey_comments'; +$sql.= " WHERE id_sondage='".$db->escape($numsondage)."'"; +$sql.= " ORDER BY id_comment"; +$resql = $db->query($sql); +$num_rows=$db->num_rows($resql); +if ($num_rows > 0) +{ + $i = 0; + print "
    " . $langs->trans("CommentsOfVoters") . " :
    \n"; + while ( $i < $num_rows) + { + $obj=$db->fetch_object($resql); + print '
    '; + if (in_array($obj->usercomment, $listofvoters)) print ' '.img_picto('', 'delete.png').' '; + print $obj->usercomment.' : '.dol_nl2br($obj->comment)."
    "; + $i++; + } +} + +// Form to add comment +print '
    ' .$langs->trans("AddACommentForPoll") . "
    \n"; + +print '
    '."\n"; +print $langs->trans("Name") .' : '; +print '   '."\n"; +print '
    '."\n"; +print ''."\n"; +// Focus javascript sur la case de texte du formulaire +print '