adherent.class.php 81 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153
  1. <?php
  2. /* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2002-2003 Jean-Louis Bergamo <jlb@j1b.org>
  4. * Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
  6. * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
  7. * Copyright (C) 2009-2017 Regis Houssin <regis.houssin@capnetworks.com>
  8. * Copyright (C) 2014-2016 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
  9. * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
  10. * Copyright (C) 2015 Frederic France <frederic.france@free.fr>
  11. * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  12. * Copyright (C) 2016 Juanjo Menent <jmenent@2byte.es>
  13. *
  14. * This program is free software; you can redistribute it and/or modify
  15. * it under the terms of the GNU General Public License as published by
  16. * the Free Software Foundation; either version 3 of the License, or
  17. * (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  26. */
  27. /**
  28. * \file htdocs/adherents/class/adherent.class.php
  29. * \ingroup member
  30. * \brief File of class to manage members of a foundation
  31. */
  32. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  33. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  34. require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
  35. /**
  36. * Class to manage members of a foundation
  37. */
  38. class Adherent extends CommonObject
  39. {
  40. public $element='member';
  41. public $table_element='adherent';
  42. protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  43. var $mesgs;
  44. var $login;
  45. //! Clear password in memory
  46. var $pass;
  47. //! Clear password in database (defined if DATABASE_PWD_ENCRYPTED=0)
  48. var $pass_indatabase;
  49. //! Encrypted password in database (always defined)
  50. var $pass_indatabase_crypted;
  51. var $societe;
  52. var $company;
  53. var $address;
  54. var $zip;
  55. var $town;
  56. var $state_id; // Id of department
  57. var $state_code; // Code of department
  58. var $state; // Label of department
  59. var $email;
  60. var $skype;
  61. var $phone;
  62. var $phone_perso;
  63. var $phone_mobile;
  64. var $morphy;
  65. var $public;
  66. var $statut; // -1:brouillon, 0:resilie, >=1:valide,paye
  67. var $photo;
  68. var $datec;
  69. var $datem;
  70. var $datefin;
  71. var $datevalid;
  72. var $birth;
  73. var $note_public;
  74. var $note_private;
  75. var $typeid; // Id type adherent
  76. var $type; // Libelle type adherent
  77. var $need_subscription;
  78. var $user_id;
  79. var $user_login;
  80. var $fk_soc;
  81. // Fields loaded by fetch_subscriptions()
  82. var $first_subscription_date;
  83. var $first_subscription_amount;
  84. var $last_subscription_date;
  85. var $last_subscription_date_start;
  86. var $last_subscription_date_end;
  87. var $last_subscription_amount;
  88. var $subscriptions=array();
  89. var $oldcopy; // To contains a clone of this when we need to save old properties of object
  90. public $entity;
  91. /**
  92. * Constructor
  93. *
  94. * @param DoliDB $db Database handler
  95. */
  96. function __construct($db)
  97. {
  98. $this->db = $db;
  99. $this->statut = -1;
  100. // l'adherent n'est pas public par defaut
  101. $this->public = 0;
  102. // les champs optionnels sont vides
  103. $this->array_options=array();
  104. }
  105. /**
  106. * Function sending an email has the adherent with the text supplied in parameter.
  107. *
  108. * @param string $text Content of message (not html entities encoded)
  109. * @param string $subject Subject of message
  110. * @param array $filename_list Array of attached files
  111. * @param array $mimetype_list Array of mime types of attached files
  112. * @param array $mimefilename_list Array of public names of attached files
  113. * @param string $addr_cc Email cc
  114. * @param string $addr_bcc Email bcc
  115. * @param int $deliveryreceipt Ask a delivery receipt
  116. * @param int $msgishtml 1=String IS already html, 0=String IS NOT html, -1=Unknown need autodetection
  117. * @param string $errors_to erros to
  118. * @return int <0 if KO, >0 if OK
  119. */
  120. function send_an_email($text, $subject, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $addr_cc="", $addr_bcc="", $deliveryreceipt=0, $msgishtml=-1, $errors_to='')
  121. {
  122. global $conf,$langs;
  123. // Detect if message is HTML
  124. if ($msgishtml == -1)
  125. {
  126. $msgishtml = 0;
  127. if (dol_textishtml($text,1)) $msgishtml = 1;
  128. }
  129. $texttosend=$this->makeSubstitution($text);
  130. $subjecttosend=$this->makeSubstitution($subject);
  131. if ($msgishtml) $texttosend=dol_htmlentitiesbr($texttosend);
  132. // Envoi mail confirmation
  133. $from=$conf->email_from;
  134. if (! empty($conf->global->ADHERENT_MAIL_FROM)) $from=$conf->global->ADHERENT_MAIL_FROM;
  135. include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
  136. $mailfile = new CMailFile($subjecttosend, $this->email, $from, $texttosend, $filename_list, $mimetype_list, $mimefilename_list, $addr_cc, $addr_bcc, $deliveryreceipt, $msgishtml);
  137. if ($mailfile->sendfile())
  138. {
  139. return 1;
  140. }
  141. else
  142. {
  143. $this->error=$langs->trans("ErrorFailedToSendMail",$from,$this->email).'. '.$mailfile->error;
  144. return -1;
  145. }
  146. }
  147. /**
  148. * Make substitution of tags into text with value of current object.
  149. *
  150. * @param string $text Text to make substitution to
  151. * @return string Value of input text string with substitutions done
  152. */
  153. function makeSubstitution($text)
  154. {
  155. global $conf,$langs;
  156. $birthday = dol_print_date($this->birth,'day');
  157. $msgishtml = 0;
  158. if (dol_textishtml($text,1)) $msgishtml = 1;
  159. $infos='';
  160. if ($this->civility_id) $infos.= $langs->transnoentities("UserTitle").": ".$this->getCivilityLabel()."\n";
  161. $infos.= $langs->transnoentities("id").": ".$this->id."\n";
  162. $infos.= $langs->transnoentities("Lastname").": ".$this->lastname."\n";
  163. $infos.= $langs->transnoentities("Firstname").": ".$this->firstname."\n";
  164. $infos.= $langs->transnoentities("Company").": ".$this->societe."\n";
  165. $infos.= $langs->transnoentities("Address").": ".$this->address."\n";
  166. $infos.= $langs->transnoentities("Zip").": ".$this->zip."\n";
  167. $infos.= $langs->transnoentities("Town").": ".$this->town."\n";
  168. $infos.= $langs->transnoentities("Country").": ".$this->country."\n";
  169. $infos.= $langs->transnoentities("EMail").": ".$this->email."\n";
  170. if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
  171. {
  172. $infos.= $langs->transnoentities("Login").": ".$this->login."\n";
  173. $infos.= $langs->transnoentities("Password").": ".$this->pass."\n";
  174. }
  175. $infos.= $langs->transnoentities("Birthday").": ".$birthday."\n";
  176. $infos.= $langs->transnoentities("Photo").": ".$this->photo."\n";
  177. $infos.= $langs->transnoentities("Public").": ".yn($this->public);
  178. // Substitutions
  179. $substitutionarray=array(
  180. '__DOL_MAIN_URL_ROOT__'=>DOL_MAIN_URL_ROOT,
  181. '__ID__'=>$msgishtml?dol_htmlentitiesbr($this->id):$this->id,
  182. '__CIVILITY__'=>$this->getCivilityLabel(),
  183. '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname,
  184. '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname,
  185. '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs),
  186. '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe,
  187. '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address,
  188. '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip,
  189. '__TOWN_'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town,
  190. '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country,
  191. '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email,
  192. '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday,
  193. '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo,
  194. '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login,
  195. '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass,
  196. // For backward compatibility
  197. '%DOL_MAIN_URL_ROOT%'=>DOL_MAIN_URL_ROOT,
  198. '%ID%'=>$msgishtml?dol_htmlentitiesbr($this->id):$this->id,
  199. '%CIVILITY%'=>$this->getCivilityLabel(),
  200. '%FIRSTNAME%'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname,
  201. '%LASTNAME%'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname,
  202. '%FULLNAME%'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs),
  203. '%COMPANY%'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe,
  204. '%ADDRESS%'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address,
  205. '%ZIP%'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip,
  206. '%TOWN%'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town,
  207. '%COUNTRY%'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country,
  208. '%EMAIL%'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email,
  209. '%BIRTH%'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday,
  210. '%PHOTO%'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo,
  211. '%LOGIN%'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login,
  212. '%PASSWORD%'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass,
  213. '%INFOS%'=>$msgishtml?dol_htmlentitiesbr($infos):$infos,
  214. '%SOCIETE%'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe,
  215. '%PRENOM%'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname,
  216. '%NOM%'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname,
  217. '%CP%'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip,
  218. '%VILLE%'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town,
  219. '%PAYS%'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country,
  220. );
  221. complete_substitutions_array($substitutionarray, $langs, $this);
  222. return make_substitutions($text, $substitutionarray, $langs);
  223. }
  224. /**
  225. * Return translated label by the nature of a adherent (physical or moral)
  226. *
  227. * @param string $morphy Nature of the adherent (physical or moral)
  228. * @return string Label
  229. */
  230. function getmorphylib($morphy='')
  231. {
  232. global $langs;
  233. if (! $morphy) { $morphy=$this->morphy; }
  234. if ($morphy == 'phy') { return $langs->trans("Physical"); }
  235. if ($morphy == 'mor') { return $langs->trans("Moral"); }
  236. return $morphy;
  237. }
  238. /**
  239. * Create a member into database
  240. *
  241. * @param User $user Objet user qui demande la creation
  242. * @param int $notrigger 1 ne declenche pas les triggers, 0 sinon
  243. * @return int <0 if KO, >0 if OK
  244. */
  245. function create($user,$notrigger=0)
  246. {
  247. global $conf,$langs;
  248. $error=0;
  249. $now=dol_now();
  250. // Clean parameters
  251. $this->import_key = trim($this->import_key);
  252. // Check parameters
  253. if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
  254. {
  255. $langs->load("errors");
  256. $this->error = $langs->trans("ErrorBadEMail",$this->email);
  257. return -1;
  258. }
  259. if (! $this->datec) $this->datec=$now;
  260. if (empty($conf->global->ADHERENT_LOGIN_NOT_REQUIRED))
  261. {
  262. if (empty($this->login))
  263. {
  264. $this->error = $langs->trans("ErrorWrongValueForParameterX","Login");
  265. return -1;
  266. }
  267. }
  268. $this->db->begin();
  269. // Insert member
  270. $sql = "INSERT INTO ".MAIN_DB_PREFIX."adherent";
  271. $sql.= " (datec,login,fk_user_author,fk_user_mod,fk_user_valid,morphy,fk_adherent_type,entity,import_key)";
  272. $sql.= " VALUES (";
  273. $sql.= " '".$this->db->idate($this->datec)."'";
  274. $sql.= ", ".($this->login?"'".$this->db->escape($this->login)."'":"null");
  275. $sql.= ", ".($user->id>0?$user->id:"null"); // Can be null because member can be created by a guest or a script
  276. $sql.= ", null, null, '".$this->morphy."'";
  277. $sql.= ", '".$this->typeid."'";
  278. $sql.= ", ".$conf->entity;
  279. $sql.= ", ".(! empty($this->import_key) ? "'".$this->import_key."'":"null");
  280. $sql.= ")";
  281. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  282. $result = $this->db->query($sql);
  283. if ($result)
  284. {
  285. $id = $this->db->last_insert_id(MAIN_DB_PREFIX."adherent");
  286. if ($id > 0)
  287. {
  288. $this->id=$id;
  289. $this->ref=(string) $id;
  290. // Update minor fields
  291. $result=$this->update($user,1,1,0,0,'add'); // nosync is 1 to avoid update data of user
  292. if ($result < 0)
  293. {
  294. $this->db->rollback();
  295. return -1;
  296. }
  297. // Add link to user
  298. if ($this->user_id)
  299. {
  300. // Add link to user
  301. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET";
  302. $sql.= " fk_member = ".$this->id;
  303. $sql.= " WHERE rowid = ".$this->user_id;
  304. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  305. $resql = $this->db->query($sql);
  306. if (! $resql)
  307. {
  308. $this->error='Failed to update user to make link with member';
  309. $this->db->rollback();
  310. return -4;
  311. }
  312. }
  313. if (! $notrigger)
  314. {
  315. // Call trigger
  316. $result=$this->call_trigger('MEMBER_CREATE',$user);
  317. if ($result < 0) { $error++; }
  318. // End call triggers
  319. }
  320. if (count($this->errors))
  321. {
  322. dol_syslog(get_class($this)."::create ".implode(',',$this->errors), LOG_ERR);
  323. $this->db->rollback();
  324. return -3;
  325. }
  326. else
  327. {
  328. $this->db->commit();
  329. return $this->id;
  330. }
  331. }
  332. else
  333. {
  334. $this->error='Failed to get last insert id';
  335. dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
  336. $this->db->rollback();
  337. return -2;
  338. }
  339. }
  340. else
  341. {
  342. $this->error=$this->db->error();
  343. $this->db->rollback();
  344. return -1;
  345. }
  346. }
  347. /**
  348. * Update a member in database (standard information and password)
  349. *
  350. * @param User $user User making update
  351. * @param int $notrigger 1=disable trigger UPDATE (when called by create)
  352. * @param int $nosyncuser 0=Synchronize linked user (standard info), 1=Do not synchronize linked user
  353. * @param int $nosyncuserpass 0=Synchronize linked user (password), 1=Do not synchronize linked user
  354. * @param int $nosyncthirdparty 0=Synchronize linked thirdparty (standard info), 1=Do not synchronize linked thirdparty
  355. * @param string $action Current action for hookmanager
  356. * @return int <0 if KO, >0 if OK
  357. */
  358. function update($user,$notrigger=0,$nosyncuser=0,$nosyncuserpass=0,$nosyncthirdparty=0,$action='update')
  359. {
  360. global $conf, $langs, $hookmanager;
  361. $nbrowsaffected=0;
  362. $error=0;
  363. dol_syslog(get_class($this)."::update notrigger=".$notrigger.", nosyncuser=".$nosyncuser.", nosyncuserpass=".$nosyncuserpass." nosyncthirdparty=".$nosyncthirdparty.", email=".$this->email);
  364. // Clean parameters
  365. $this->lastname=trim($this->lastname)?trim($this->lastname):trim($this->lastname);
  366. $this->firstname=trim($this->firstname)?trim($this->firstname):trim($this->firstname);
  367. $this->address=($this->address?$this->address:$this->address);
  368. $this->zip=($this->zip?$this->zip:$this->zip);
  369. $this->town=($this->town?$this->town:$this->town);
  370. $this->country_id=($this->country_id > 0?$this->country_id:$this->country_id);
  371. $this->state_id=($this->state_id > 0?$this->state_id:$this->state_id);
  372. if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->lastname=ucwords(trim($this->lastname));
  373. if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->firstname=ucwords(trim($this->firstname));
  374. $this->note_public=($this->note_public?$this->note_public:$this->note_public);
  375. $this->note_private=($this->note_private?$this->note_private:$this->note_private);
  376. // Check parameters
  377. if (! empty($conf->global->ADHERENT_MAIL_REQUIRED) && ! isValidEMail($this->email))
  378. {
  379. $langs->load("errors");
  380. $this->error = $langs->trans("ErrorBadEMail",$this->email);
  381. return -1;
  382. }
  383. $this->db->begin();
  384. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  385. $sql.= " civility = ".(!is_null($this->civility_id)?"'".$this->civility_id."'":"null");
  386. $sql.= ", firstname = ".($this->firstname?"'".$this->db->escape($this->firstname)."'":"null");
  387. $sql.= ", lastname=" .($this->lastname?"'".$this->db->escape($this->lastname)."'":"null");
  388. $sql.= ", login=" .($this->login?"'".$this->db->escape($this->login)."'":"null");
  389. $sql.= ", societe=" .($this->societe?"'".$this->db->escape($this->societe)."'":"null");
  390. $sql.= ", fk_soc=" .($this->fk_soc > 0?"'".$this->fk_soc."'":"null");
  391. $sql.= ", address=" .($this->address?"'".$this->db->escape($this->address)."'":"null");
  392. $sql.= ", zip=" .($this->zip?"'".$this->db->escape($this->zip)."'":"null");
  393. $sql.= ", town=" .($this->town?"'".$this->db->escape($this->town)."'":"null");
  394. $sql.= ", country=".($this->country_id>0?"'".$this->country_id."'":"null");
  395. $sql.= ", state_id=".($this->state_id>0?"'".$this->state_id."'":"null");
  396. $sql.= ", email='".$this->db->escape($this->email)."'";
  397. $sql.= ", skype='".$this->db->escape($this->skype)."'";
  398. $sql.= ", phone=" .($this->phone?"'".$this->db->escape($this->phone)."'":"null");
  399. $sql.= ", phone_perso=" .($this->phone_perso?"'".$this->db->escape($this->phone_perso)."'":"null");
  400. $sql.= ", phone_mobile=" .($this->phone_mobile?"'".$this->db->escape($this->phone_mobile)."'":"null");
  401. $sql.= ", note_private=" .($this->note_private?"'".$this->db->escape($this->note_private)."'":"null");
  402. $sql.= ", note_public=" .($this->note_public?"'".$this->db->escape($this->note_public)."'":"null");
  403. $sql.= ", photo=" .($this->photo?"'".$this->photo."'":"null");
  404. $sql.= ", public='".$this->db->escape($this->public)."'";
  405. $sql.= ", statut=" .$this->statut;
  406. $sql.= ", fk_adherent_type=".$this->typeid;
  407. $sql.= ", morphy='".$this->db->escape($this->morphy)."'";
  408. $sql.= ", birth=" .($this->birth?"'".$this->db->idate($this->birth)."'":"null");
  409. if ($this->datefin) $sql.= ", datefin='".$this->db->idate($this->datefin)."'"; // Must be modified only when deleting a subscription
  410. if ($this->datevalid) $sql.= ", datevalid='".$this->db->idate($this->datevalid)."'"; // Must be modified only when validating a member
  411. $sql.= ", fk_user_mod=".($user->id>0?$user->id:'null'); // Can be null because member can be create by a guest
  412. $sql.= " WHERE rowid = ".$this->id;
  413. dol_syslog(get_class($this)."::update update member", LOG_DEBUG);
  414. $resql = $this->db->query($sql);
  415. if ($resql)
  416. {
  417. unset($this->country_code);
  418. unset($this->country);
  419. unset($this->state_code);
  420. unset($this->state);
  421. $nbrowsaffected+=$this->db->affected_rows($resql);
  422. $action='update';
  423. // Actions on extra fields (by external module)
  424. // TODO le hook fait double emploi avec le trigger !!
  425. $hookmanager->initHooks(array('memberdao'));
  426. $parameters=array('id'=>$this->id);
  427. $action='';
  428. $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
  429. if (empty($reshook))
  430. {
  431. if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
  432. {
  433. $result=$this->insertExtraFields();
  434. if ($result < 0)
  435. {
  436. $error++;
  437. }
  438. }
  439. }
  440. else if ($reshook < 0) $error++;
  441. // Update password
  442. if (! $error && $this->pass)
  443. {
  444. dol_syslog(get_class($this)."::update update password");
  445. if ($this->pass != $this->pass_indatabase && $this->pass != $this->pass_indatabase_crypted)
  446. {
  447. $isencrypted = empty($conf->global->DATABASE_PWD_ENCRYPTED)?0:1;
  448. // If password to set differs from the one found into database
  449. $result=$this->setPassword($user,$this->pass,$isencrypted,$notrigger,$nosyncuserpass);
  450. if (! $nbrowsaffected) $nbrowsaffected++;
  451. }
  452. }
  453. // Remove links to user and replace with new one
  454. if (! $error)
  455. {
  456. dol_syslog(get_class($this)."::update update link to user");
  457. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
  458. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  459. $resql = $this->db->query($sql);
  460. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
  461. // If there is a user linked to this member
  462. if ($this->user_id > 0)
  463. {
  464. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id." WHERE rowid = ".$this->user_id;
  465. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  466. $resql = $this->db->query($sql);
  467. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -5; }
  468. }
  469. }
  470. if (! $error && $nbrowsaffected) // If something has change in main data
  471. {
  472. // Update information on linked user if it is an update
  473. if (! $error && $this->user_id > 0 && ! $nosyncuser)
  474. {
  475. require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
  476. dol_syslog(get_class($this)."::update update linked user");
  477. $luser=new User($this->db);
  478. $result=$luser->fetch($this->user_id);
  479. if ($result >= 0)
  480. {
  481. //var_dump($this->user_login);exit;
  482. //var_dump($this->login);exit;
  483. $luser->login=$this->login;
  484. $luser->civility_id=$this->civility_id;
  485. $luser->firstname=$this->firstname;
  486. $luser->lastname=$this->lastname;
  487. $luser->pass=$this->pass;
  488. $luser->societe_id=$this->societe;
  489. $luser->email=$this->email;
  490. $luser->skype=$this->skype;
  491. $luser->office_phone=$this->phone;
  492. $luser->user_mobile=$this->phone_mobile;
  493. $luser->fk_member=$this->id;
  494. $result=$luser->update($user,0,1,1); // Use nosync to 1 to avoid cyclic updates
  495. if ($result < 0)
  496. {
  497. $this->error=$luser->error;
  498. dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
  499. $error++;
  500. }
  501. }
  502. else
  503. {
  504. $this->error=$luser->error;
  505. $error++;
  506. }
  507. }
  508. // Update information on linked thirdparty if it is an update
  509. if (! $error && $this->fk_soc > 0 && ! $nosyncthirdparty)
  510. {
  511. require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
  512. dol_syslog(get_class($this)."::update update linked thirdparty");
  513. // This member is linked with a thirdparty, so we also update thirdparty informations
  514. // if this is an update.
  515. $lthirdparty=new Societe($this->db);
  516. $result=$lthirdparty->fetch($this->fk_soc);
  517. if ($result >= 0)
  518. {
  519. $lthirdparty->address=$this->address;
  520. $lthirdparty->zip=$this->zip;
  521. $lthirdparty->town=$this->town;
  522. $lthirdparty->email=$this->email;
  523. $lthirdparty->skype=$this->skype;
  524. $lthirdparty->phone=$this->phone;
  525. $lthirdparty->state_id=$this->state_id;
  526. $lthirdparty->country_id=$this->country_id;
  527. $lthirdparty->country_id=$this->country_id;
  528. //$lthirdparty->phone_mobile=$this->phone_mobile;
  529. $result=$lthirdparty->update($this->fk_soc,$user,0,1,1,'update'); // Use sync to 0 to avoid cyclic updates
  530. if ($result < 0)
  531. {
  532. $this->error=$lthirdparty->error;
  533. dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
  534. $error++;
  535. }
  536. }
  537. else
  538. {
  539. $this->error=$lthirdparty->error;
  540. $error++;
  541. }
  542. }
  543. if (! $error && ! $notrigger)
  544. {
  545. // Call trigger
  546. $result=$this->call_trigger('MEMBER_MODIFY',$user);
  547. if ($result < 0) { $error++; }
  548. // End call triggers
  549. }
  550. }
  551. if (! $error)
  552. {
  553. $this->db->commit();
  554. return $nbrowsaffected;
  555. }
  556. else
  557. {
  558. $this->db->rollback();
  559. return -1;
  560. }
  561. }
  562. else
  563. {
  564. $this->db->rollback();
  565. $this->error=$this->db->lasterror();
  566. return -2;
  567. }
  568. }
  569. /**
  570. * Update denormalized last subscription date.
  571. * This function is called when we delete a subscription for example.
  572. *
  573. * @param User $user User making change
  574. * @return int <0 if KO, >0 if OK
  575. */
  576. function update_end_date($user)
  577. {
  578. $this->db->begin();
  579. // Search for last subscription id and end date
  580. $sql = "SELECT rowid, datec as dateop, dateadh as datedeb, datef as datefin";
  581. $sql.= " FROM ".MAIN_DB_PREFIX."subscription";
  582. $sql.= " WHERE fk_adherent=".$this->id;
  583. $sql.= " ORDER by dateadh DESC"; // Sort by start subscription date
  584. dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
  585. $resql=$this->db->query($sql);
  586. if ($resql)
  587. {
  588. $obj=$this->db->fetch_object($resql);
  589. $dateop=$this->db->jdate($obj->dateop);
  590. $datedeb=$this->db->jdate($obj->datedeb);
  591. $datefin=$this->db->jdate($obj->datefin);
  592. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  593. $sql.= " datefin=".($datefin != '' ? "'".$this->db->idate($datefin)."'" : "null");
  594. $sql.= " WHERE rowid = ".$this->id;
  595. dol_syslog(get_class($this)."::update_end_date", LOG_DEBUG);
  596. $resql=$this->db->query($sql);
  597. if ($resql)
  598. {
  599. $this->last_subscription_date=$dateop;
  600. $this->last_subscription_date_start=$datedeb;
  601. $this->last_subscription_date_end=$datefin;
  602. $this->datefin=$datefin;
  603. $this->db->commit();
  604. return 1;
  605. }
  606. else
  607. {
  608. $this->db->rollback();
  609. return -1;
  610. }
  611. }
  612. else
  613. {
  614. $this->error=$this->db->lasterror();
  615. $this->db->rollback();
  616. return -1;
  617. }
  618. }
  619. /**
  620. * Fonction qui supprime l'adherent et les donnees associees
  621. *
  622. * @param int $rowid Id of member to delete
  623. * @return int <0 if KO, 0=nothing to do, >0 if OK
  624. */
  625. function delete($rowid)
  626. {
  627. global $conf, $langs, $user;
  628. $result = 0;
  629. $error=0;
  630. $errorflag=0;
  631. // Check parameters
  632. if (empty($rowid)) $rowid=$this->id;
  633. $this->db->begin();
  634. // Remove category
  635. $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_member WHERE fk_member = ".$rowid;
  636. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  637. $resql=$this->db->query($sql);
  638. if (! $resql)
  639. {
  640. $error++;
  641. $this->error .= $this->db->lasterror();
  642. $errorflag=-1;
  643. }
  644. // Remove subscription
  645. if (! $error)
  646. {
  647. $sql = "DELETE FROM ".MAIN_DB_PREFIX."subscription WHERE fk_adherent = ".$rowid;
  648. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  649. $resql=$this->db->query($sql);
  650. if (! $resql)
  651. {
  652. $error++;
  653. $this->error .= $this->db->lasterror();
  654. $errorflag=-2;
  655. }
  656. }
  657. // Remove linked user
  658. if (! $error)
  659. {
  660. $ret=$this->setUserId(0);
  661. if ($ret < 0)
  662. {
  663. $error++;
  664. $this->error .= $this->db->lasterror();
  665. $errorflag=-3;
  666. }
  667. }
  668. // Removed extrafields
  669. if (! $error)
  670. {
  671. if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
  672. {
  673. $result=$this->deleteExtraFields();
  674. if ($result < 0)
  675. {
  676. $error++;
  677. $errorflag=-4;
  678. dol_syslog(get_class($this)."::delete erreur ".$errorflag." ".$this->error, LOG_ERR);
  679. }
  680. }
  681. }
  682. // Remove adherent
  683. if (! $error)
  684. {
  685. $sql = "DELETE FROM ".MAIN_DB_PREFIX."adherent WHERE rowid = ".$rowid;
  686. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  687. $resql=$this->db->query($sql);
  688. if (! $resql)
  689. {
  690. $error++;
  691. $this->error .= $this->db->lasterror();
  692. $errorflag=-5;
  693. }
  694. }
  695. if (! $error)
  696. {
  697. // Call trigger
  698. $result=$this->call_trigger('MEMBER_DELETE',$user);
  699. if ($result < 0) { $error++; }
  700. // End call triggers
  701. }
  702. if (! $error)
  703. {
  704. $this->db->commit();
  705. return 1;
  706. }
  707. else
  708. {
  709. $this->db->rollback();
  710. return $errorflag;
  711. }
  712. }
  713. /**
  714. * Change password of a user
  715. *
  716. * @param User $user Object user de l'utilisateur qui fait la modification
  717. * @param string $password New password (to generate if empty)
  718. * @param int $isencrypted 0 ou 1 si il faut crypter le mot de passe en base (0 par defaut)
  719. * @param int $notrigger 1=Ne declenche pas les triggers
  720. * @param int $nosyncuser Do not synchronize linked user
  721. * @return string If OK return clear password, 0 if no change, < 0 if error
  722. */
  723. function setPassword($user, $password='', $isencrypted=0, $notrigger=0, $nosyncuser=0)
  724. {
  725. global $conf, $langs;
  726. $error=0;
  727. dol_syslog(get_class($this)."::setPassword user=".$user->id." password=".preg_replace('/./i','*',$password)." isencrypted=".$isencrypted);
  728. // If new password not provided, we generate one
  729. if (! $password)
  730. {
  731. require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
  732. $password=getRandomPassword(false);
  733. }
  734. // Crypt password
  735. $password_crypted = dol_hash($password);
  736. $password_indatabase = '';
  737. if (! $isencrypted)
  738. {
  739. $password_indatabase = $password;
  740. }
  741. $this->db->begin();
  742. // Mise a jour
  743. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
  744. $sql.= " SET pass_crypted = '".$this->db->escape($password_crypted)."'";
  745. //if (! empty($conf->global->DATABASE_PWD_ENCRYPTED))
  746. if ($isencrypted)
  747. {
  748. $sql.= ", pass = null";
  749. }
  750. else
  751. {
  752. $sql.= ", pass = '".$this->db->escape($password_indatabase)."'";
  753. }
  754. $sql.= " WHERE rowid = ".$this->id;
  755. //dol_syslog("Adherent::Password sql=hidden");
  756. dol_syslog(get_class($this)."::setPassword", LOG_DEBUG);
  757. $result = $this->db->query($sql);
  758. if ($result)
  759. {
  760. $nbaffectedrows=$this->db->affected_rows($result);
  761. if ($nbaffectedrows)
  762. {
  763. $this->pass=$password;
  764. $this->pass_indatabase=$password_indatabase;
  765. $this->pass_indatabase_crypted=$password_crypted;
  766. if ($this->user_id && ! $nosyncuser)
  767. {
  768. require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
  769. // This member is linked with a user, so we also update users informations
  770. // if this is an update.
  771. $luser=new User($this->db);
  772. $result=$luser->fetch($this->user_id);
  773. if ($result >= 0)
  774. {
  775. $result=$luser->setPassword($user,$this->pass,0,0,1);
  776. if ($result < 0)
  777. {
  778. $this->error=$luser->error;
  779. dol_syslog(get_class($this)."::setPassword ".$this->error,LOG_ERR);
  780. $error++;
  781. }
  782. }
  783. else
  784. {
  785. $this->error=$luser->error;
  786. $error++;
  787. }
  788. }
  789. if (! $error && ! $notrigger)
  790. {
  791. // Call trigger
  792. $result=$this->call_trigger('MEMBER_NEW_PASSWORD',$user);
  793. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  794. // End call triggers
  795. }
  796. $this->db->commit();
  797. return $this->pass;
  798. }
  799. else
  800. {
  801. $this->db->rollback();
  802. return 0;
  803. }
  804. }
  805. else
  806. {
  807. $this->db->rollback();
  808. dol_print_error($this->db);
  809. return -1;
  810. }
  811. }
  812. /**
  813. * Set link to a user
  814. *
  815. * @param int $userid Id of user to link to
  816. * @return int 1=OK, -1=KO
  817. */
  818. function setUserId($userid)
  819. {
  820. global $conf, $langs;
  821. $this->db->begin();
  822. // If user is linked to this member, remove old link to this member
  823. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = NULL WHERE fk_member = ".$this->id;
  824. dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
  825. $resql = $this->db->query($sql);
  826. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -1; }
  827. // Set link to user
  828. if ($userid > 0)
  829. {
  830. $sql = "UPDATE ".MAIN_DB_PREFIX."user SET fk_member = ".$this->id;
  831. $sql.= " WHERE rowid = ".$userid;
  832. dol_syslog(get_class($this)."::setUserId", LOG_DEBUG);
  833. $resql = $this->db->query($sql);
  834. if (! $resql) { $this->error=$this->db->error(); $this->db->rollback(); return -2; }
  835. }
  836. $this->db->commit();
  837. return 1;
  838. }
  839. /**
  840. * Set link to a third party
  841. *
  842. * @param int $thirdpartyid Id of user to link to
  843. * @return int 1=OK, -1=KO
  844. */
  845. function setThirdPartyId($thirdpartyid)
  846. {
  847. global $conf, $langs;
  848. $this->db->begin();
  849. // Remove link to third party onto any other members
  850. if ($thirdpartyid > 0)
  851. {
  852. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = null";
  853. $sql.= " WHERE fk_soc = '".$thirdpartyid."'";
  854. $sql.= " AND entity = ".$conf->entity;
  855. dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
  856. $resql = $this->db->query($sql);
  857. }
  858. // Add link to third party for current member
  859. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET fk_soc = ".($thirdpartyid>0 ? $thirdpartyid : 'null');
  860. $sql.= " WHERE rowid = ".$this->id;
  861. dol_syslog(get_class($this)."::setThirdPartyId", LOG_DEBUG);
  862. $resql = $this->db->query($sql);
  863. if ($resql)
  864. {
  865. $this->db->commit();
  866. return 1;
  867. }
  868. else
  869. {
  870. $this->error=$this->db->error();
  871. $this->db->rollback();
  872. return -1;
  873. }
  874. }
  875. /**
  876. * Method to load member from its login
  877. *
  878. * @param string $login login of member
  879. * @return void
  880. */
  881. function fetch_login($login)
  882. {
  883. global $conf;
  884. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
  885. $sql.= " WHERE login='".$this->db->escape($login)."'";
  886. $sql.= " AND entity = ".$conf->entity;
  887. $resql=$this->db->query($sql);
  888. if ($resql)
  889. {
  890. if ($this->db->num_rows($resql))
  891. {
  892. $obj = $this->db->fetch_object($resql);
  893. $this->fetch($obj->rowid);
  894. }
  895. }
  896. else
  897. {
  898. dol_print_error($this->db);
  899. }
  900. }
  901. /**
  902. * Method to load member from its name
  903. *
  904. * @param string $firstname Firstname
  905. * @param string $lastname Lastname
  906. * @return void
  907. */
  908. function fetch_name($firstname,$lastname)
  909. {
  910. global $conf;
  911. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent";
  912. $sql.= " WHERE firstname='".$this->db->escape($firstname)."'";
  913. $sql.= " AND lastname='".$this->db->escape($lastname)."'";
  914. $sql.= " AND entity = ".$conf->entity;
  915. $resql=$this->db->query($sql);
  916. if ($resql)
  917. {
  918. if ($this->db->num_rows($resql))
  919. {
  920. $obj = $this->db->fetch_object($resql);
  921. $this->fetch($obj->rowid);
  922. }
  923. }
  924. else
  925. {
  926. dol_print_error($this->db);
  927. }
  928. }
  929. /**
  930. * Load member from database
  931. *
  932. * @param int $rowid Id of object to load
  933. * @param string $ref To load member from its ref
  934. * @param int $fk_soc To load member from its link to third party
  935. * @param string $ref_ext External reference
  936. * @return int >0 if OK, 0 if not found, <0 if KO
  937. */
  938. function fetch($rowid,$ref='',$fk_soc='',$ref_ext='')
  939. {
  940. global $langs;
  941. $sql = "SELECT d.rowid, d.ref_ext, d.civility as civility_id, d.firstname, d.lastname, d.societe as company, d.fk_soc, d.statut, d.public, d.address, d.zip, d.town, d.note_private,";
  942. $sql.= " d.note_public,";
  943. $sql.= " d.email, d.skype, d.phone, d.phone_perso, d.phone_mobile, d.login, d.pass, d.pass_crypted,";
  944. $sql.= " d.photo, d.fk_adherent_type, d.morphy, d.entity,";
  945. $sql.= " d.datec as datec,";
  946. $sql.= " d.tms as datem,";
  947. $sql.= " d.datefin as datefin,";
  948. $sql.= " d.birth as birthday,";
  949. $sql.= " d.datevalid as datev,";
  950. $sql.= " d.country,";
  951. $sql.= " d.state_id,";
  952. $sql.= " d.model_pdf,";
  953. $sql.= " c.rowid as country_id, c.code as country_code, c.label as country,";
  954. $sql.= " dep.nom as state, dep.code_departement as state_code,";
  955. $sql.= " t.libelle as type, t.subscription as subscription,";
  956. $sql.= " u.rowid as user_id, u.login as user_login";
  957. $sql.= " FROM ".MAIN_DB_PREFIX."adherent_type as t, ".MAIN_DB_PREFIX."adherent as d";
  958. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.country = c.rowid";
  959. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_departements as dep ON d.state_id = dep.rowid";
  960. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u ON d.rowid = u.fk_member";
  961. $sql.= " WHERE d.fk_adherent_type = t.rowid";
  962. if ($rowid) $sql.= " AND d.rowid=".$rowid;
  963. elseif ($ref || $fk_soc) {
  964. $sql.= " AND d.entity IN (".getEntity().")";
  965. if ($ref) $sql.= " AND d.rowid='".$this->db->escape($ref)."'";
  966. elseif ($fk_soc > 0) $sql.= " AND d.fk_soc=".$fk_soc;
  967. }
  968. elseif ($ref_ext)
  969. {
  970. $sql.= " AND d.ref_ext='".$this->db->escape($ref_ext)."'";
  971. }
  972. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  973. $resql=$this->db->query($sql);
  974. if ($resql)
  975. {
  976. if ($this->db->num_rows($resql))
  977. {
  978. $obj = $this->db->fetch_object($resql);
  979. $this->entity = $obj->entity;
  980. $this->ref = $obj->rowid;
  981. $this->id = $obj->rowid;
  982. $this->ref_ext = $obj->ref_ext;
  983. $this->civility_id = $obj->civility_id;
  984. $this->firstname = $obj->firstname;
  985. $this->lastname = $obj->lastname;
  986. $this->login = $obj->login;
  987. $this->societe = $obj->company;
  988. $this->company = $obj->company;
  989. $this->fk_soc = $obj->fk_soc;
  990. $this->address = $obj->address;
  991. $this->zip = $obj->zip;
  992. $this->town = $obj->town;
  993. $this->pass = $obj->pass;
  994. $this->pass_indatabase = $obj->pass;
  995. $this->pass_indatabase_crypted = $obj->pass_crypted;
  996. $this->state_id = $obj->state_id;
  997. $this->state_code = $obj->state_id?$obj->state_code:'';
  998. $this->state = $obj->state_id?$obj->state:'';
  999. $this->country_id = $obj->country_id;
  1000. $this->country_code = $obj->country_code;
  1001. if ($langs->trans("Country".$obj->country_code) != "Country".$obj->country_code)
  1002. $this->country = $langs->transnoentitiesnoconv("Country".$obj->country_code);
  1003. else
  1004. $this->country=$obj->country;
  1005. $this->phone = $obj->phone;
  1006. $this->phone_perso = $obj->phone_perso;
  1007. $this->phone_mobile = $obj->phone_mobile;
  1008. $this->email = $obj->email;
  1009. $this->skype = $obj->skype;
  1010. $this->photo = $obj->photo;
  1011. $this->statut = $obj->statut;
  1012. $this->public = $obj->public;
  1013. $this->datec = $this->db->jdate($obj->datec);
  1014. $this->datem = $this->db->jdate($obj->datem);
  1015. $this->datefin = $this->db->jdate($obj->datefin);
  1016. $this->datevalid = $this->db->jdate($obj->datev);
  1017. $this->birth = $this->db->jdate($obj->birthday);
  1018. $this->note_private = $obj->note_private;
  1019. $this->note_public = $obj->note_public;
  1020. $this->morphy = $obj->morphy;
  1021. $this->typeid = $obj->fk_adherent_type;
  1022. $this->type = $obj->type;
  1023. $this->need_subscription = $obj->subscription;
  1024. $this->user_id = $obj->user_id;
  1025. $this->user_login = $obj->user_login;
  1026. $this->model_pdf = $obj->model_pdf;
  1027. // Retreive all extrafield for thirdparty
  1028. // fetch optionals attributes and labels
  1029. require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
  1030. $extrafields=new ExtraFields($this->db);
  1031. $extralabels=$extrafields->fetch_name_optionals_label($this->table_element,true);
  1032. $this->fetch_optionals($this->id,$extralabels);
  1033. // Load other properties
  1034. $result=$this->fetch_subscriptions();
  1035. return $result;
  1036. }
  1037. else
  1038. {
  1039. return 0;
  1040. }
  1041. }
  1042. else
  1043. {
  1044. $this->error=$this->db->lasterror();
  1045. return -1;
  1046. }
  1047. }
  1048. /**
  1049. * Fonction qui recupere pour un adherent les parametres
  1050. * first_subscription_date
  1051. * first_subscription_amount
  1052. * last_subscription_date
  1053. * last_subscription_amount
  1054. *
  1055. * @return int <0 si KO, >0 si OK
  1056. */
  1057. function fetch_subscriptions()
  1058. {
  1059. global $langs;
  1060. require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
  1061. $sql = "SELECT c.rowid, c.fk_adherent, c.subscription, c.note, c.fk_bank,";
  1062. $sql.= " c.tms as datem,";
  1063. $sql.= " c.datec as datec,";
  1064. $sql.= " c.dateadh as dateh,";
  1065. $sql.= " c.datef as datef";
  1066. $sql.= " FROM ".MAIN_DB_PREFIX."subscription as c";
  1067. $sql.= " WHERE c.fk_adherent = ".$this->id;
  1068. $sql.= " ORDER BY c.dateadh";
  1069. dol_syslog(get_class($this)."::fetch_subscriptions", LOG_DEBUG);
  1070. $resql=$this->db->query($sql);
  1071. if ($resql)
  1072. {
  1073. $this->subscriptions=array();
  1074. $i=0;
  1075. while ($obj = $this->db->fetch_object($resql))
  1076. {
  1077. if ($i==0)
  1078. {
  1079. $this->first_subscription_date=$obj->dateh;
  1080. $this->first_subscription_amount=$obj->subscription;
  1081. }
  1082. $this->last_subscription_date=$obj->dateh;
  1083. $this->last_subscription_amount=$obj->subscription;
  1084. $subscription=new Subscription($this->db);
  1085. $subscription->id=$obj->rowid;
  1086. $subscription->fk_adherent=$obj->fk_adherent;
  1087. $subscription->amount=$obj->subscription;
  1088. $subscription->note=$obj->note;
  1089. $subscription->fk_bank=$obj->fk_bank;
  1090. $subscription->datem=$this->db->jdate($obj->datem);
  1091. $subscription->datec=$this->db->jdate($obj->datec);
  1092. $subscription->dateh=$this->db->jdate($obj->dateh);
  1093. $subscription->datef=$this->db->jdate($obj->datef);
  1094. $this->subscriptions[]=$subscription;
  1095. $i++;
  1096. }
  1097. return 1;
  1098. }
  1099. else
  1100. {
  1101. $this->error=$this->db->error().' sql='.$sql;
  1102. return -1;
  1103. }
  1104. }
  1105. /**
  1106. * Insert subscription into database and eventually add links to banks, mailman, etc...
  1107. *
  1108. * @param int $date Date of effect of subscription
  1109. * @param double $montant Amount of subscription (0 accepted for some members)
  1110. * @param int $accountid Id bank account
  1111. * @param string $operation Type operation (if Id bank account provided)
  1112. * @param string $label Label operation (if Id bank account provided)
  1113. * @param string $num_chq Numero cheque (if Id bank account provided)
  1114. * @param string $emetteur_nom Name of cheque writer
  1115. * @param string $emetteur_banque Name of bank of cheque
  1116. * @param int $datesubend Date end subscription
  1117. * @return int rowid of record added, <0 if KO
  1118. */
  1119. function subscription($date, $montant, $accountid=0, $operation='', $label='', $num_chq='', $emetteur_nom='', $emetteur_banque='', $datesubend=0)
  1120. {
  1121. global $conf,$langs,$user;
  1122. require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
  1123. $error=0;
  1124. // Clean parameters
  1125. if (! $montant) $montant=0;
  1126. $this->db->begin();
  1127. if ($datesubend)
  1128. {
  1129. $datefin=$datesubend;
  1130. }
  1131. else
  1132. {
  1133. // If no end date, end date = date + 1 year - 1 day
  1134. $datefin = dol_time_plus_duree($date,1,'y');
  1135. $datefin = dol_time_plus_duree($datefin,-1,'d');
  1136. }
  1137. // Create subscription
  1138. $subscription=new Subscription($this->db);
  1139. $subscription->fk_adherent=$this->id;
  1140. $subscription->dateh=$date; // Date of new subscription
  1141. $subscription->datef=$datefin; // End data of new subscription
  1142. $subscription->amount=$montant;
  1143. $subscription->note=$label;
  1144. $rowid=$subscription->create($user);
  1145. if ($rowid > 0)
  1146. {
  1147. // Update denormalized subscription end date (read database subscription to find values)
  1148. // This will also update this->datefin
  1149. $result=$this->update_end_date($user);
  1150. if ($result > 0)
  1151. {
  1152. // Change properties of object (used by triggers)
  1153. $this->last_subscription_date=dol_now();
  1154. $this->last_subscription_amount=$montant;
  1155. $this->last_subscription_date_start=$date;
  1156. $this->last_subscription_date_end=$datefin;
  1157. // Call trigger
  1158. $result=$this->call_trigger('MEMBER_SUBSCRIPTION',$user);
  1159. if ($result < 0) { $error++; }
  1160. // End call triggers
  1161. }
  1162. if (! $error)
  1163. {
  1164. $this->db->commit();
  1165. return $rowid;
  1166. }
  1167. else
  1168. {
  1169. $this->db->rollback();
  1170. return -2;
  1171. }
  1172. }
  1173. else
  1174. {
  1175. $this->error=$subscription->error;
  1176. $this->db->rollback();
  1177. return -1;
  1178. }
  1179. }
  1180. /**
  1181. * Function that validate a member
  1182. *
  1183. * @param User $user user adherent qui valide
  1184. * @return int <0 if KO, 0 if nothing done, >0 if OK
  1185. */
  1186. function validate($user)
  1187. {
  1188. global $langs,$conf;
  1189. $error=0;
  1190. $now=dol_now();
  1191. // Check parameters
  1192. if ($this->statut == 1)
  1193. {
  1194. dol_syslog(get_class($this)."::validate statut of member does not allow this", LOG_WARNING);
  1195. return 0;
  1196. }
  1197. $this->db->begin();
  1198. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  1199. $sql.= " statut = 1";
  1200. $sql.= ", datevalid = '".$this->db->idate($now)."'";
  1201. $sql.= ", fk_user_valid=".$user->id;
  1202. $sql.= " WHERE rowid = ".$this->id;
  1203. dol_syslog(get_class($this)."::validate", LOG_DEBUG);
  1204. $result = $this->db->query($sql);
  1205. if ($result)
  1206. {
  1207. $this->statut=1;
  1208. // Call trigger
  1209. $result=$this->call_trigger('MEMBER_VALIDATE',$user);
  1210. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  1211. // End call triggers
  1212. $this->db->commit();
  1213. return 1;
  1214. }
  1215. else
  1216. {
  1217. $this->error=$this->db->error();
  1218. $this->db->rollback();
  1219. return -1;
  1220. }
  1221. }
  1222. /**
  1223. * Fonction qui resilie un adherent
  1224. *
  1225. * @param User $user User making change
  1226. * @return int <0 if KO, >0 if OK
  1227. */
  1228. function resiliate($user)
  1229. {
  1230. global $langs,$conf;
  1231. $error=0;
  1232. // Check paramaters
  1233. if ($this->statut == 0)
  1234. {
  1235. dol_syslog(get_class($this)."::resiliate statut of member does not allow this", LOG_WARNING);
  1236. return 0;
  1237. }
  1238. $this->db->begin();
  1239. $sql = "UPDATE ".MAIN_DB_PREFIX."adherent SET";
  1240. $sql.= " statut = 0";
  1241. $sql.= ", fk_user_valid=".$user->id;
  1242. $sql.= " WHERE rowid = ".$this->id;
  1243. $result = $this->db->query($sql);
  1244. if ($result)
  1245. {
  1246. $this->statut=0;
  1247. // Call trigger
  1248. $result=$this->call_trigger('MEMBER_RESILIATE',$user);
  1249. if ($result < 0) { $error++; $this->db->rollback(); return -1; }
  1250. // End call triggers
  1251. $this->db->commit();
  1252. return 1;
  1253. }
  1254. else
  1255. {
  1256. $this->error=$this->db->error();
  1257. $this->db->rollback();
  1258. return -1;
  1259. }
  1260. }
  1261. /**
  1262. * Function to add member into external tools mailing-list, spip, etc.
  1263. *
  1264. * @return int <0 if KO, >0 if OK
  1265. */
  1266. function add_to_abo()
  1267. {
  1268. global $conf,$langs;
  1269. include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
  1270. $mailmanspip=new MailmanSpip($this->db);
  1271. $err=0;
  1272. // mailman
  1273. if (! empty($conf->global->ADHERENT_USE_MAILMAN) && ! empty($conf->mailmanspip->enabled))
  1274. {
  1275. $result=$mailmanspip->add_to_mailman($this);
  1276. if ($result < 0)
  1277. {
  1278. if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
  1279. $err+=1;
  1280. }
  1281. foreach ($mailmanspip->mladded_ko as $tmplist => $tmpemail)
  1282. {
  1283. $langs->load("errors");
  1284. $this->errors[]=$langs->trans("ErrorFailedToAddToMailmanList",$tmpemail,$tmplist);
  1285. }
  1286. foreach ($mailmanspip->mladded_ok as $tmplist => $tmpemail)
  1287. {
  1288. $langs->load("mailmanspip");
  1289. $this->mesgs[]=$langs->trans("SuccessToAddToMailmanList",$tmpemail,$tmplist);
  1290. }
  1291. }
  1292. // spip
  1293. if (! empty($conf->global->ADHERENT_USE_SPIP) && ! empty($conf->mailmanspip->enabled))
  1294. {
  1295. $result=$mailmanspip->add_to_spip($this);
  1296. if ($result < 0)
  1297. {
  1298. $this->errors[]=$mailmanspip->error;
  1299. $err+=1;
  1300. }
  1301. }
  1302. if ($err)
  1303. {
  1304. return -$err;
  1305. }
  1306. else
  1307. {
  1308. return 1;
  1309. }
  1310. }
  1311. /**
  1312. * Function to delete a member from external tools like mailing-list, spip, etc.
  1313. *
  1314. * @return int <0 if KO, >0 if OK
  1315. */
  1316. function del_to_abo()
  1317. {
  1318. global $conf,$langs;
  1319. include_once DOL_DOCUMENT_ROOT.'/mailmanspip/class/mailmanspip.class.php';
  1320. $mailmanspip=new MailmanSpip($this->db);
  1321. $err=0;
  1322. // mailman
  1323. if (! empty($conf->global->ADHERENT_USE_MAILMAN))
  1324. {
  1325. $result=$mailmanspip->del_to_mailman($this);
  1326. if ($result < 0)
  1327. {
  1328. if (! empty($mailmanspip->error)) $this->errors[]=$mailmanspip->error;
  1329. $err+=1;
  1330. }
  1331. foreach ($mailmanspip->mlremoved_ko as $tmplist => $tmpemail)
  1332. {
  1333. $langs->load("errors");
  1334. $this->errors[]=$langs->trans("ErrorFailedToRemoveToMailmanList",$tmpemail,$tmplist);
  1335. }
  1336. foreach ($mailmanspip->mlremoved_ok as $tmplist => $tmpemail)
  1337. {
  1338. $langs->load("mailmanspip");
  1339. $this->mesgs[]=$langs->trans("SuccessToRemoveToMailmanList",$tmpemail,$tmplist);
  1340. }
  1341. }
  1342. if ($conf->global->ADHERENT_USE_SPIP && ! empty($conf->mailmanspip->enabled))
  1343. {
  1344. $result=$mailmanspip->del_to_spip($this);
  1345. if ($result < 0)
  1346. {
  1347. $this->errors[]=$mailmanspip->error;
  1348. $err+=1;
  1349. }
  1350. }
  1351. if ($err)
  1352. {
  1353. // error
  1354. return -$err;
  1355. }
  1356. else
  1357. {
  1358. return 1;
  1359. }
  1360. }
  1361. /**
  1362. * Return civility label of a member
  1363. *
  1364. * @return string Translated name of civility (translated with transnoentitiesnoconv)
  1365. */
  1366. function getCivilityLabel()
  1367. {
  1368. global $langs;
  1369. $langs->load("dict");
  1370. $code=(empty($this->civility_id)?'':$this->civility_id);
  1371. if (empty($code)) return '';
  1372. return $langs->getLabelFromKey($this->db, "Civility".$code, "c_civility", "code", "label", $code);
  1373. }
  1374. /**
  1375. * Return clicable name (with picto eventually)
  1376. *
  1377. * @param int $withpictoimg 0=No picto, 1=Include picto into link, 2=Only picto, -1=Include photo into link, -2=Only picto photo, -3=Only photo very small)
  1378. * @param int $maxlen length max label
  1379. * @param string $option Page for link
  1380. * @param string $mode ''=Show firstname and lastname, 'firstname'=Show only firstname, 'login'=Show login, 'ref'=Show ref
  1381. * @param string $morecss Add more css on link
  1382. * @return string Chaine avec URL
  1383. */
  1384. function getNomUrl($withpictoimg=0,$maxlen=0,$option='card',$mode='',$morecss='')
  1385. {
  1386. global $conf, $langs;
  1387. if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER) && $withpictoimg) $withpictoimg=0;
  1388. $result=''; $label='';
  1389. $link=''; $linkstart=''; $linkend='';
  1390. if (! empty($this->photo))
  1391. {
  1392. $label.= '<div class="photointooltip">';
  1393. $label.= Form::showphoto('memberphoto', $this, 80, 0, 0, 'photowithmargin photologintooltip', 'small', 0, 1);
  1394. $label.= '</div><div style="clear: both;"></div>';
  1395. }
  1396. $label.= '<div class="centpercent">';
  1397. $label.= '<u>' . $langs->trans("Member") . '</u>';
  1398. if (! empty($this->ref))
  1399. $label.= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
  1400. if (! empty($this->firstname) || ! empty($this->lastname))
  1401. $label.= '<br><b>' . $langs->trans('Name') . ':</b> ' . $this->getFullName($langs);
  1402. $label.='</div>';
  1403. if ($option == 'card' || $option == 'category')
  1404. {
  1405. $link = '<a href="'.DOL_URL_ROOT.'/adherents/card.php?rowid='.$this->id.'"';
  1406. }
  1407. if ($option == 'subscription')
  1408. {
  1409. $link = '<a href="'.DOL_URL_ROOT.'/adherents/subscription.php?rowid='.$this->id.'"';
  1410. }
  1411. $linkclose="";
  1412. if (empty($notooltip))
  1413. {
  1414. if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
  1415. {
  1416. $langs->load("users");
  1417. $label=$langs->trans("ShowUser");
  1418. $linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
  1419. }
  1420. $linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
  1421. $linkclose.= ' class="classfortooltip'.($morecss?' '.$morecss:'').'"';
  1422. }
  1423. $link.=$linkclose.'>';
  1424. $linkend='</a>';
  1425. //if ($withpictoimg == -1) $result.='<div class="nowrap">';
  1426. $result.=$link;
  1427. if ($withpictoimg)
  1428. {
  1429. $paddafterimage='';
  1430. if (abs($withpictoimg) == 1) $paddafterimage='style="margin-right: 3px;"';
  1431. // Only picto
  1432. if ($withpictoimg > 0) $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'">'.img_object('', 'user', $paddafterimage.' '.($notooltip?'':'class="classfortooltip"'), 0, 0, $notooltip?0:1).'</div>';
  1433. // Picto must be a photo
  1434. else $picto='<div class="inline-block nopadding valignmiddle'.($morecss?' userimg'.$morecss:'').'"'.($paddafterimage?' '.$paddafterimage:'').'>'.Form::showphoto('memberphoto', $this, 0, 0, 0, 'userphoto'.($withpictoimg==-3?'small':''), 'mini', 0, 1).'</div>';
  1435. $result.=$picto;
  1436. }
  1437. if ($withpictoimg > -2 && $withpictoimg != 2)
  1438. {
  1439. if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='<div class="inline-block nopadding valignmiddle'.((! isset($this->statut) || $this->statut)?'':' strikefordisabled').($morecss?' usertext'.$morecss:'').'">';
  1440. if ($mode == 'login') $result.=dol_trunc($this->login, $maxlen);
  1441. elseif ($mode == 'ref') $result.=$this->id;
  1442. else $result.=$this->getFullName($langs,'',($mode == 'firstname' ? 2 : -1),$maxlen);
  1443. if (empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) $result.='</div>';
  1444. }
  1445. $result.=$linkend;
  1446. //if ($withpictoimg == -1) $result.='</div>';
  1447. return $result;
  1448. }
  1449. /**
  1450. * Retourne le libelle du statut d'un adherent (brouillon, valide, resilie)
  1451. *
  1452. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  1453. * @return string Label
  1454. */
  1455. function getLibStatut($mode=0)
  1456. {
  1457. return $this->LibStatut($this->statut,$this->need_subscription,$this->datefin,$mode);
  1458. }
  1459. /**
  1460. * Renvoi le libelle d'un statut donne
  1461. *
  1462. * @param int $statut Id statut
  1463. * @param int $need_subscription 1 if member type need subscription, 0 otherwise
  1464. * @param int $date_end_subscription Date fin adhesion
  1465. * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
  1466. * @return string Label
  1467. */
  1468. function LibStatut($statut,$need_subscription,$date_end_subscription,$mode=0)
  1469. {
  1470. global $langs;
  1471. $langs->load("members");
  1472. if ($mode == 0)
  1473. {
  1474. if ($statut == -1) return $langs->trans("MemberStatusDraft");
  1475. if ($statut >= 1)
  1476. {
  1477. if (! $date_end_subscription) return $langs->trans("MemberStatusActive");
  1478. elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLate");
  1479. else return $langs->trans("MemberStatusPaid");
  1480. }
  1481. if ($statut == 0) return $langs->trans("MemberStatusResiliated");
  1482. }
  1483. if ($mode == 1)
  1484. {
  1485. if ($statut == -1) return $langs->trans("MemberStatusDraftShort");
  1486. if ($statut >= 1)
  1487. {
  1488. if (! $date_end_subscription) return $langs->trans("MemberStatusActiveShort");
  1489. elseif ($date_end_subscription < time()) return $langs->trans("MemberStatusActiveLateShort");
  1490. else return $langs->trans("MemberStatusPaidShort");
  1491. }
  1492. if ($statut == 0) return $langs->trans("MemberStatusResiliatedShort");
  1493. }
  1494. if ($mode == 2)
  1495. {
  1496. if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraftShort");
  1497. if ($statut >= 1)
  1498. {
  1499. if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActiveShort");
  1500. elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLateShort");
  1501. else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaidShort");
  1502. }
  1503. if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliatedShort");
  1504. }
  1505. if ($mode == 3)
  1506. {
  1507. if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0');
  1508. if ($statut >= 1)
  1509. {
  1510. if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1');
  1511. elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
  1512. else return img_picto($langs->trans('MemberStatusPaid'),'statut4');
  1513. }
  1514. if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5');
  1515. }
  1516. if ($mode == 4)
  1517. {
  1518. if ($statut == -1) return img_picto($langs->trans('MemberStatusDraft'),'statut0').' '.$langs->trans("MemberStatusDraft");
  1519. if ($statut >= 1)
  1520. {
  1521. if (! $date_end_subscription) return img_picto($langs->trans('MemberStatusActive'),'statut1').' '.$langs->trans("MemberStatusActive");
  1522. elseif ($date_end_subscription < time()) return img_picto($langs->trans('MemberStatusActiveLate'),'statut3').' '.$langs->trans("MemberStatusActiveLate");
  1523. else return img_picto($langs->trans('MemberStatusPaid'),'statut4').' '.$langs->trans("MemberStatusPaid");
  1524. }
  1525. if ($statut == 0) return img_picto($langs->trans('MemberStatusResiliated'),'statut5').' '.$langs->trans("MemberStatusResiliated");
  1526. }
  1527. if ($mode == 5)
  1528. {
  1529. if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
  1530. if ($statut >= 1)
  1531. {
  1532. if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveShort").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
  1533. elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLateShort").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
  1534. else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaidShort").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
  1535. }
  1536. if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
  1537. }
  1538. if ($mode == 6)
  1539. {
  1540. if ($statut == -1) return $langs->trans("MemberStatusDraft").' '.img_picto($langs->trans('MemberStatusDraft'),'statut0');
  1541. if ($statut >= 1)
  1542. {
  1543. if (! $date_end_subscription) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActive").' </span>'.img_picto($langs->trans('MemberStatusActive'),'statut1');
  1544. elseif ($date_end_subscription < time()) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusActiveLate").' </span>'.img_picto($langs->trans('MemberStatusActiveLate'),'statut3');
  1545. else return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusPaid").' </span>'.img_picto($langs->trans('MemberStatusPaid'),'statut4');
  1546. }
  1547. if ($statut == 0) return '<span class="hideonsmartphone">'.$langs->trans("MemberStatusResiliated").' </span>'.img_picto($langs->trans('MemberStatusResiliated'),'statut5');
  1548. }
  1549. }
  1550. /**
  1551. * Charge indicateurs this->nb de tableau de bord
  1552. *
  1553. * @return int <0 if KO, >0 if OK
  1554. */
  1555. function load_state_board()
  1556. {
  1557. global $conf;
  1558. $this->nb=array();
  1559. $sql = "SELECT count(a.rowid) as nb";
  1560. $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
  1561. $sql.= " WHERE a.statut > 0";
  1562. $sql.= " AND a.entity IN (".getEntity('adherent', 1).")";
  1563. $resql=$this->db->query($sql);
  1564. if ($resql)
  1565. {
  1566. while ($obj=$this->db->fetch_object($resql))
  1567. {
  1568. $this->nb["members"]=$obj->nb;
  1569. }
  1570. $this->db->free($resql);
  1571. return 1;
  1572. }
  1573. else
  1574. {
  1575. dol_print_error($this->db);
  1576. $this->error=$this->db->error();
  1577. return -1;
  1578. }
  1579. }
  1580. /**
  1581. * Load indicators for dashboard (this->nbtodo and this->nbtodolate)
  1582. *
  1583. * @param User $user Objet user
  1584. * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK
  1585. */
  1586. function load_board($user)
  1587. {
  1588. global $conf, $langs;
  1589. if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe
  1590. $now=dol_now();
  1591. $sql = "SELECT a.rowid, a.datefin, a.statut";
  1592. $sql.= " FROM ".MAIN_DB_PREFIX."adherent as a";
  1593. $sql.= " WHERE a.statut = 1";
  1594. $sql.= " AND a.entity IN (".getEntity('adherent', 1).")";
  1595. $sql.= " AND (a.datefin IS NULL or a.datefin < '".$this->db->idate($now)."')";
  1596. $resql=$this->db->query($sql);
  1597. if ($resql)
  1598. {
  1599. $langs->load("members");
  1600. $response = new WorkboardResponse();
  1601. $response->warning_delay=$conf->adherent->subscription->warning_delay/60/60/24;
  1602. $response->label=$langs->trans("MembersWithSubscriptionToReceive");
  1603. $response->url=DOL_URL_ROOT.'/adherents/list.php?mainmenu=members&amp;statut=1&amp;filter=outofdate';
  1604. $response->img=img_object('',"user");
  1605. $adherentstatic = new Adherent($this->db);
  1606. while ($obj=$this->db->fetch_object($resql))
  1607. {
  1608. $response->nbtodo++;
  1609. $adherentstatic->datefin = $this->db->jdate($obj->datefin);
  1610. $adherentstatic->statut = $obj->statut;
  1611. if ($adherentstatic->hasDelay()) {
  1612. $response->nbtodolate++;
  1613. }
  1614. }
  1615. return $response;
  1616. }
  1617. else
  1618. {
  1619. dol_print_error($this->db);
  1620. $this->error=$this->db->error();
  1621. return -1;
  1622. }
  1623. }
  1624. /**
  1625. * Create a document onto disk according to template module.
  1626. *
  1627. * @param string $modele Force template to use ('' to not force)
  1628. * @param Translate $outputlangs objet lang a utiliser pour traduction
  1629. * @param int $hidedetails Hide details of lines
  1630. * @param int $hidedesc Hide description
  1631. * @param int $hideref Hide ref
  1632. * @return int 0 if KO, 1 if OK
  1633. */
  1634. public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
  1635. {
  1636. global $conf,$langs;
  1637. $langs->load("orders");
  1638. if (! dol_strlen($modele)) {
  1639. $modele = 'standard';
  1640. if ($this->modelpdf) {
  1641. $modele = $this->modelpdf;
  1642. } elseif (! empty($conf->global->ADHERENT_ADDON_PDF)) {
  1643. $modele = $conf->global->ADHERENT_ADDON_PDF;
  1644. }
  1645. }
  1646. $modelpath = "core/modules/member/doc/";
  1647. return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref);
  1648. }
  1649. /**
  1650. * Initialise an instance with random values.
  1651. * Used to build previews or test instances.
  1652. * id must be 0 if object instance is a specimen.
  1653. *
  1654. * @return void
  1655. */
  1656. function initAsSpecimen()
  1657. {
  1658. global $user,$langs;
  1659. // Initialise parametres
  1660. $this->id=0;
  1661. $this->specimen=1;
  1662. $this->civility_id = 0;
  1663. $this->lastname = 'DOLIBARR';
  1664. $this->firstname = 'SPECIMEN';
  1665. $this->login='dolibspec';
  1666. $this->pass='dolibspec';
  1667. $this->societe = 'Societe ABC';
  1668. $this->address = '61 jump street';
  1669. $this->zip = '75000';
  1670. $this->town = 'Paris';
  1671. $this->country_id = 1;
  1672. $this->country_code = 'FR';
  1673. $this->country = 'France';
  1674. $this->morphy = 1;
  1675. $this->email = 'specimen@specimen.com';
  1676. $this->skype = 'tom.hanson';
  1677. $this->phone = '0999999999';
  1678. $this->phone_perso = '0999999998';
  1679. $this->phone_mobile = '0999999997';
  1680. $this->note_private='No comment';
  1681. $this->birth=time();
  1682. $this->photo='';
  1683. $this->public=1;
  1684. $this->statut=0;
  1685. $this->datefin=time();
  1686. $this->datevalid=time();
  1687. $this->typeid=1; // Id type adherent
  1688. $this->type='Type adherent'; // Libelle type adherent
  1689. $this->need_subscription=0;
  1690. $this->first_subscription_date=time();
  1691. $this->first_subscription_amount=10;
  1692. $this->last_subscription_date=time();
  1693. $this->last_subscription_amount=10;
  1694. }
  1695. /**
  1696. * Retourne chaine DN complete dans l'annuaire LDAP pour l'objet
  1697. *
  1698. * @param array $info Info array loaded by _load_ldap_info
  1699. * @param int $mode 0=Return full DN (uid=qqq,ou=xxx,dc=aaa,dc=bbb)
  1700. * 1=Return DN without key inside (ou=xxx,dc=aaa,dc=bbb)
  1701. * 2=Return key only (uid=qqq)
  1702. * @return string DN
  1703. */
  1704. function _load_ldap_dn($info,$mode=0)
  1705. {
  1706. global $conf;
  1707. $dn='';
  1708. if ($mode==0) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS].",".$conf->global->LDAP_MEMBER_DN;
  1709. if ($mode==1) $dn=$conf->global->LDAP_MEMBER_DN;
  1710. if ($mode==2) $dn=$conf->global->LDAP_KEY_MEMBERS."=".$info[$conf->global->LDAP_KEY_MEMBERS];
  1711. return $dn;
  1712. }
  1713. /**
  1714. * Initialise tableau info (tableau des attributs LDAP)
  1715. *
  1716. * @return array Tableau info des attributs
  1717. */
  1718. function _load_ldap_info()
  1719. {
  1720. global $conf,$langs;
  1721. $info=array();
  1722. // Object classes
  1723. $info["objectclass"]=explode(',',$conf->global->LDAP_MEMBER_OBJECT_CLASS);
  1724. $this->fullname=$this->getFullName($langs);
  1725. // Member
  1726. if ($this->fullname && ! empty($conf->global->LDAP_MEMBER_FIELD_FULLNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FULLNAME] = $this->fullname;
  1727. if ($this->lastname && ! empty($conf->global->LDAP_MEMBER_FIELD_NAME)) $info[$conf->global->LDAP_MEMBER_FIELD_NAME] = $this->lastname;
  1728. if ($this->firstname && ! empty($conf->global->LDAP_MEMBER_FIELD_FIRSTNAME)) $info[$conf->global->LDAP_MEMBER_FIELD_FIRSTNAME] = $this->firstname;
  1729. if ($this->login && ! empty($conf->global->LDAP_MEMBER_FIELD_LOGIN)) $info[$conf->global->LDAP_MEMBER_FIELD_LOGIN] = $this->login;
  1730. if ($this->pass && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD] = $this->pass; // this->pass = mot de passe non crypte
  1731. if ($this->pass && ! empty($conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED)) $info[$conf->global->LDAP_MEMBER_FIELD_PASSWORD_CRYPTED] = dol_hash($this->pass, 4); // md5 for OpenLdap TODO add type of encryption
  1732. if ($this->poste && ! empty($conf->global->LDAP_MEMBER_FIELD_TITLE)) $info[$conf->global->LDAP_MEMBER_FIELD_TITLE] = $this->poste;
  1733. if ($this->address && ! empty($conf->global->LDAP_MEMBER_FIELD_ADDRESS)) $info[$conf->global->LDAP_MEMBER_FIELD_ADDRESS] = $this->address;
  1734. if ($this->zip && ! empty($conf->global->LDAP_MEMBER_FIELD_ZIP)) $info[$conf->global->LDAP_MEMBER_FIELD_ZIP] = $this->zip;
  1735. if ($this->town && ! empty($conf->global->LDAP_MEMBER_FIELD_TOWN)) $info[$conf->global->LDAP_MEMBER_FIELD_TOWN] = $this->town;
  1736. if ($this->country_code && ! empty($conf->global->LDAP_MEMBER_FIELD_COUNTRY)) $info[$conf->global->LDAP_MEMBER_FIELD_COUNTRY] = $this->country_code;
  1737. if ($this->email && ! empty($conf->global->LDAP_MEMBER_FIELD_MAIL)) $info[$conf->global->LDAP_MEMBER_FIELD_MAIL] = $this->email;
  1738. if ($this->skype && ! empty($conf->global->LDAP_MEMBER_FIELD_SKYPE)) $info[$conf->global->LDAP_MEMBER_FIELD_SKYPE] = $this->skype;
  1739. if ($this->phone && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE] = $this->phone;
  1740. if ($this->phone_perso && ! empty($conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO)) $info[$conf->global->LDAP_MEMBER_FIELD_PHONE_PERSO] = $this->phone_perso;
  1741. if ($this->phone_mobile && ! empty($conf->global->LDAP_MEMBER_FIELD_MOBILE)) $info[$conf->global->LDAP_MEMBER_FIELD_MOBILE] = $this->phone_mobile;
  1742. if ($this->fax && ! empty($conf->global->LDAP_MEMBER_FIELD_FAX)) $info[$conf->global->LDAP_MEMBER_FIELD_FAX] = $this->fax;
  1743. if ($this->note_private && ! empty($conf->global->LDAP_MEMBER_FIELD_DESCRIPTION)) $info[$conf->global->LDAP_MEMBER_FIELD_DESCRIPTION] = $this->note_private;
  1744. if ($this->note_public && ! empty($conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC)) $info[$conf->global->LDAP_MEMBER_FIELD_NOTE_PUBLIC] = $this->note_public;
  1745. if ($this->birth && ! empty($conf->global->LDAP_MEMBER_FIELD_BIRTHDATE)) $info[$conf->global->LDAP_MEMBER_FIELD_BIRTHDATE] = dol_print_date($this->birth,'dayhourldap');
  1746. if (isset($this->statut) && ! empty($conf->global->LDAP_FIELD_MEMBER_STATUS)) $info[$conf->global->LDAP_FIELD_MEMBER_STATUS] = $this->statut;
  1747. if ($this->datefin && ! empty($conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION)) $info[$conf->global->LDAP_FIELD_MEMBER_END_LASTSUBSCRIPTION] = dol_print_date($this->datefin,'dayhourldap');
  1748. // Subscriptions
  1749. if ($this->first_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE)) $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_DATE] = dol_print_date($this->first_subscription_date,'dayhourldap');
  1750. if (isset($this->first_subscription_amount) && ! empty($conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT)) $info[$conf->global->LDAP_FIELD_MEMBER_FIRSTSUBSCRIPTION_AMOUNT] = $this->first_subscription_amount;
  1751. if ($this->last_subscription_date && ! empty($conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE)) $info[$conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_DATE] = dol_print_date($this->last_subscription_date,'dayhourldap');
  1752. if (isset($this->last_subscription_amount) && ! empty($conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT)) $info[$conf->global->LDAP_FIELD_MEMBER_LASTSUBSCRIPTION_AMOUNT] = $this->last_subscription_amount;
  1753. return $info;
  1754. }
  1755. /**
  1756. * Charge les informations d'ordre info dans l'objet adherent
  1757. *
  1758. * @param int $id Id of member to load
  1759. * @return void
  1760. */
  1761. function info($id)
  1762. {
  1763. $sql = 'SELECT a.rowid, a.datec as datec,';
  1764. $sql.= ' a.datevalid as datev,';
  1765. $sql.= ' a.tms as datem,';
  1766. $sql.= ' a.fk_user_author, a.fk_user_valid, a.fk_user_mod';
  1767. $sql.= ' FROM '.MAIN_DB_PREFIX.'adherent as a';
  1768. $sql.= ' WHERE a.rowid = '.$id;
  1769. dol_syslog(get_class($this)."::info", LOG_DEBUG);
  1770. $result=$this->db->query($sql);
  1771. if ($result)
  1772. {
  1773. if ($this->db->num_rows($result))
  1774. {
  1775. $obj = $this->db->fetch_object($result);
  1776. $this->id = $obj->rowid;
  1777. if ($obj->fk_user_author)
  1778. {
  1779. $cuser = new User($this->db);
  1780. $cuser->fetch($obj->fk_user_author);
  1781. $this->user_creation = $cuser;
  1782. }
  1783. if ($obj->fk_user_valid)
  1784. {
  1785. $vuser = new User($this->db);
  1786. $vuser->fetch($obj->fk_user_valid);
  1787. $this->user_validation = $vuser;
  1788. }
  1789. if ($obj->fk_user_mod)
  1790. {
  1791. $muser = new User($this->db);
  1792. $muser->fetch($obj->fk_user_mod);
  1793. $this->user_modification = $muser;
  1794. }
  1795. $this->date_creation = $this->db->jdate($obj->datec);
  1796. $this->date_validation = $this->db->jdate($obj->datev);
  1797. $this->date_modification = $this->db->jdate($obj->datem);
  1798. }
  1799. $this->db->free($result);
  1800. }
  1801. else
  1802. {
  1803. dol_print_error($this->db);
  1804. }
  1805. }
  1806. /**
  1807. * Sets object to supplied categories.
  1808. *
  1809. * Deletes object from existing categories not supplied.
  1810. * Adds it to non existing supplied categories.
  1811. * Existing categories are left untouch.
  1812. *
  1813. * @param int[]|int $categories Category or categories IDs
  1814. */
  1815. public function setCategories($categories)
  1816. {
  1817. // Handle single category
  1818. if (!is_array($categories)) {
  1819. $categories = array($categories);
  1820. }
  1821. // Get current categories
  1822. require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
  1823. $c = new Categorie($this->db);
  1824. $existing = $c->containing($this->id, Categorie::TYPE_MEMBER, 'id');
  1825. // Diff
  1826. if (is_array($existing)) {
  1827. $to_del = array_diff($existing, $categories);
  1828. $to_add = array_diff($categories, $existing);
  1829. } else {
  1830. $to_del = array(); // Nothing to delete
  1831. $to_add = $categories;
  1832. }
  1833. // Process
  1834. foreach ($to_del as $del) {
  1835. if ($c->fetch($del) > 0) {
  1836. $c->del_type($this, 'member');
  1837. }
  1838. }
  1839. foreach ($to_add as $add) {
  1840. if ($c->fetch($add) > 0) {
  1841. $c->add_type($this, 'member');
  1842. }
  1843. }
  1844. return;
  1845. }
  1846. /**
  1847. * Function used to replace a thirdparty id with another one.
  1848. *
  1849. * @param DoliDB $db Database handler
  1850. * @param int $origin_id Old thirdparty id
  1851. * @param int $dest_id New thirdparty id
  1852. * @return bool
  1853. */
  1854. public static function replaceThirdparty($db, $origin_id, $dest_id)
  1855. {
  1856. $tables = array(
  1857. 'adherent'
  1858. );
  1859. return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
  1860. }
  1861. /**
  1862. * Return if a member is late (subscription late) or not
  1863. *
  1864. * @return boolean True if late, False if not late
  1865. */
  1866. public function hasDelay()
  1867. {
  1868. global $conf;
  1869. //Only valid members
  1870. if ($this->statut <= 0) return false;
  1871. if (! $this->datefin) return false;
  1872. $now = dol_now();
  1873. return $this->datefin < ($now - $conf->adherent->subscription->warning_delay);
  1874. }
  1875. }