extrafields.class.php 50 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599
  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 Sebastien Di Cintio <sdicintio@ressource-toi.org>
  5. * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
  6. * Copyright (C) 2009-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  7. * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@capnetworks.com>
  8. * Copyright (C) 2013 Florian Henry <forian.henry@open-concept.pro>
  9. * Copyright (C) 2015 Charles-Fr BENKE <charles.fr@benke.fr>
  10. * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. * the Free Software Foundation; either version 3 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU General Public License
  23. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  24. */
  25. /**
  26. * \file htdocs/core/class/extrafields.class.php
  27. * \ingroup core
  28. * \brief File of class to manage extra fields
  29. */
  30. /**
  31. * Class to manage standard extra fields
  32. */
  33. class ExtraFields
  34. {
  35. var $db;
  36. // Tableau contenant le nom des champs en clef et la definition de ces champs
  37. var $attribute_type;
  38. // Tableau contenant le nom des champs en clef et le label de ces champs en value
  39. var $attribute_label;
  40. // Tableau contenant le nom des champs en clef et la taille/longueur max de ces champs en value
  41. var $attribute_size;
  42. // Tableau contenant le nom des choix en clef et la valeur de ces choix en value
  43. var $attribute_choice;
  44. // Array to store if attribute is unique or not
  45. var $attribute_unique;
  46. // Array to store if attribute is required or not
  47. var $attribute_required;
  48. // Array to store parameters of attribute (used in select type)
  49. var $attribute_param;
  50. // Array to store position of attribute
  51. var $attribute_pos;
  52. // Array to store if attribute is editable regardless of the document status
  53. var $attribute_alwayseditable;
  54. // Array to store permission to check
  55. var $attribute_perms;
  56. // Array to store permission to check
  57. var $attribute_list;
  58. var $error;
  59. var $errno;
  60. var $attribute_hidden;
  61. public static $type2label=array(
  62. 'varchar'=>'String',
  63. 'text'=>'TextLong',
  64. 'int'=>'Int',
  65. 'double'=>'Float',
  66. 'date'=>'Date',
  67. 'datetime'=>'DateAndTime',
  68. 'boolean'=>'Boolean',
  69. 'price'=>'ExtrafieldPrice',
  70. 'phone'=>'ExtrafieldPhone',
  71. 'mail'=>'ExtrafieldMail',
  72. 'select' => 'ExtrafieldSelect',
  73. 'sellist' => 'ExtrafieldSelectList',
  74. 'radio' => 'ExtrafieldRadio',
  75. 'checkbox' => 'ExtrafieldCheckBox',
  76. 'chkbxlst' => 'ExtrafieldCheckBoxFromList',
  77. 'link' => 'ExtrafieldLink',
  78. 'separate' => 'ExtrafieldSeparator',
  79. );
  80. /**
  81. * Constructor
  82. *
  83. * @param DoliDB $db Database handler
  84. */
  85. function __construct($db)
  86. {
  87. $this->db = $db;
  88. $this->error = array();
  89. $this->attribute_type = array();
  90. $this->attribute_label = array();
  91. $this->attribute_size = array();
  92. $this->attribute_elementtype = array();
  93. $this->attribute_unique = array();
  94. $this->attribute_required = array();
  95. $this->attribute_perms = array();
  96. $this->attribute_list = array();
  97. $this->attribute_hidden = array();
  98. }
  99. /**
  100. * Add a new extra field parameter
  101. *
  102. * @param string $attrname Code of attribute
  103. * @param string $label label of attribute
  104. * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
  105. * @param int $pos Position of attribute
  106. * @param string $size Size/length of attribute
  107. * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...)
  108. * @param int $unique Is field unique or not
  109. * @param int $required Is field required or not
  110. * @param string $default_value Defaulted value (Example: '', '0', 'null', 'avalue')
  111. * @param array $param Params for field
  112. * @param int $alwayseditable Is attribute always editable regardless of the document status
  113. * @param string $perms Permission to check
  114. * @param int $list Into list view by default
  115. * @param int $ishidden Is hidden extrafield
  116. * @return int <=0 if KO, >0 if OK
  117. */
  118. function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param=0, $alwayseditable=0, $perms='', $list=0, $ishidden=0)
  119. {
  120. if (empty($attrname)) return -1;
  121. if (empty($label)) return -1;
  122. if ($elementtype == 'thirdparty') $elementtype='societe';
  123. if ($elementtype == 'contact') $elementtype='socpeople';
  124. // Create field into database except for separator type which is not stored in database
  125. if ($type != 'separate')
  126. {
  127. $result=$this->create($attrname, $type, $size, $elementtype, $unique, $required, $default_value, $param, $perms, $list);
  128. }
  129. $err1=$this->errno;
  130. if ($result > 0 || $err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' || $type == 'separate')
  131. {
  132. // Add declaration of field into table
  133. $result2=$this->create_label($attrname,$label,$type,$pos,$size,$elementtype, $unique, $required, $param, $alwayseditable, $perms, $list, $ishidden);
  134. $err2=$this->errno;
  135. if ($result2 > 0 || ($err1 == 'DB_ERROR_COLUMN_ALREADY_EXISTS' && $err2 == 'DB_ERROR_RECORD_ALREADY_EXISTS'))
  136. {
  137. $this->error='';
  138. $this->errno=0;
  139. return 1;
  140. }
  141. else return -2;
  142. }
  143. else
  144. {
  145. return -1;
  146. }
  147. }
  148. /**
  149. * Add a new optional attribute.
  150. * This is a private method. For public method, use addExtraField.
  151. *
  152. * @param string $attrname code of attribute
  153. * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour')
  154. * @param string $length Size/length of attribute ('5', '24,8', ...)
  155. * @param string $elementtype Element type ('member', 'product', 'thirdparty', 'contact', ...)
  156. * @param int $unique Is field unique or not
  157. * @param int $required Is field required or not
  158. * @param string $default_value Default value for field
  159. * @param array $param Params for field (ex for select list : array('options'=>array('value'=>'label of option'))
  160. * @param string $perms Permission
  161. * @param int $list Into list view by default
  162. * @return int <=0 if KO, >0 if OK
  163. */
  164. private function create($attrname, $type='varchar', $length=255, $elementtype='member', $unique=0, $required=0, $default_value='',$param='', $perms='', $list=0)
  165. {
  166. if ($elementtype == 'thirdparty') $elementtype='societe';
  167. if ($elementtype == 'contact') $elementtype='socpeople';
  168. $table=$elementtype.'_extrafields';
  169. if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9_]*$/",$attrname) && ! is_numeric($attrname))
  170. {
  171. if ($type=='boolean') {
  172. $typedb='int';
  173. $lengthdb='1';
  174. } elseif($type=='price') {
  175. $typedb='double';
  176. $lengthdb='24,8';
  177. } elseif($type=='phone') {
  178. $typedb='varchar';
  179. $lengthdb='20';
  180. }elseif($type=='mail') {
  181. $typedb='varchar';
  182. $lengthdb='128';
  183. } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') ||($type=='checkbox') ||($type=='chkbxlst')){
  184. $typedb='text';
  185. $lengthdb='';
  186. } elseif ($type=='link') {
  187. $typedb='int';
  188. $lengthdb='11';
  189. } else {
  190. $typedb=$type;
  191. $lengthdb=$length;
  192. }
  193. $field_desc = array(
  194. 'type'=>$typedb,
  195. 'value'=>$lengthdb,
  196. 'null'=>($required?'NOT NULL':'NULL'),
  197. 'default' => $default_value
  198. );
  199. $result=$this->db->DDLAddField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
  200. if ($result > 0)
  201. {
  202. if ($unique)
  203. {
  204. $sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
  205. $resql=$this->db->query($sql,1,'dml');
  206. }
  207. return 1;
  208. }
  209. else
  210. {
  211. $this->error=$this->db->lasterror();
  212. $this->errno=$this->db->lasterrno();
  213. return -1;
  214. }
  215. }
  216. else
  217. {
  218. return 0;
  219. }
  220. }
  221. /**
  222. * Add description of a new optional attribute
  223. *
  224. * @param string $attrname code of attribute
  225. * @param string $label label of attribute
  226. * @param int $type Type of attribute ('int', 'text', 'varchar', 'date', 'datehour', 'float')
  227. * @param int $pos Position of attribute
  228. * @param string $size Size/length of attribute ('5', '24,8', ...)
  229. * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...)
  230. * @param int $unique Is field unique or not
  231. * @param int $required Is field required or not
  232. * @param array||string $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
  233. * @param int $alwayseditable Is attribute always editable regardless of the document status
  234. * @param string $perms Permission to check
  235. * @param int $list Into list view by default
  236. * @param int $ishidden Is hidden extrafield
  237. * @return int <=0 if KO, >0 if OK
  238. */
  239. private function create_label($attrname, $label='', $type='', $pos=0, $size=0, $elementtype='member', $unique=0, $required=0, $param='', $alwayseditable=0, $perms='', $list=0, $ishidden=0)
  240. {
  241. global $conf;
  242. if ($elementtype == 'thirdparty') $elementtype='societe';
  243. if ($elementtype == 'contact') $elementtype='socpeople';
  244. // Clean parameters
  245. if (empty($pos)) $pos=0;
  246. if (empty($list)) $list=0;
  247. if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname) && ! is_numeric($attrname))
  248. {
  249. if(is_array($param) && count($param) > 0)
  250. {
  251. $params = $this->db->escape(serialize($param));
  252. }
  253. elseif (strlen($param) > 0)
  254. {
  255. $params = trim($param);
  256. }
  257. else
  258. {
  259. $params='';
  260. }
  261. $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(name, label, type, pos, size, entity, elementtype, fieldunique, fieldrequired, param, alwayseditable, perms, list, ishidden)";
  262. $sql.= " VALUES('".$attrname."',";
  263. $sql.= " '".$this->db->escape($label)."',";
  264. $sql.= " '".$type."',";
  265. $sql.= " '".$pos."',";
  266. $sql.= " '".$size."',";
  267. $sql.= " ".$conf->entity.",";
  268. $sql.= " '".$elementtype."',";
  269. $sql.= " '".$unique."',";
  270. $sql.= " '".$required."',";
  271. $sql.= " '".$params."',";
  272. $sql.= " '".$alwayseditable."',";
  273. $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").",";
  274. $sql.= " ".$list;
  275. $sql.= ", ".$ishidden;
  276. $sql.=')';
  277. dol_syslog(get_class($this)."::create_label", LOG_DEBUG);
  278. if ($this->db->query($sql))
  279. {
  280. return 1;
  281. }
  282. else
  283. {
  284. $this->error=$this->db->lasterror();
  285. $this->errno=$this->db->lasterrno();
  286. return -1;
  287. }
  288. }
  289. }
  290. /**
  291. * Delete an optional attribute
  292. *
  293. * @param string $attrname Code of attribute to delete
  294. * @param string $elementtype Element type ('member', 'product', 'thirdparty', 'contact', ...)
  295. * @return int < 0 if KO, 0 if nothing is done, 1 if OK
  296. */
  297. function delete($attrname, $elementtype='member')
  298. {
  299. if ($elementtype == 'thirdparty') $elementtype='societe';
  300. if ($elementtype == 'contact') $elementtype='socpeople';
  301. $table=$elementtype.'_extrafields';
  302. if (! empty($attrname) && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
  303. {
  304. $result=$this->db->DDLDropField(MAIN_DB_PREFIX.$table,$attrname); // This also drop the unique key
  305. if ($result < 0)
  306. {
  307. $this->error=$this->db->lasterror();
  308. }
  309. $result=$this->delete_label($attrname,$elementtype);
  310. return $result;
  311. }
  312. else
  313. {
  314. return 0;
  315. }
  316. }
  317. /**
  318. * Delete description of an optional attribute
  319. *
  320. * @param string $attrname Code of attribute to delete
  321. * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...)
  322. * @return int < 0 if KO, 0 if nothing is done, 1 if OK
  323. */
  324. private function delete_label($attrname, $elementtype='member')
  325. {
  326. global $conf;
  327. if ($elementtype == 'thirdparty') $elementtype='societe';
  328. if ($elementtype == 'contact') $elementtype='socpeople';
  329. if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
  330. {
  331. $sql = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
  332. $sql.= " WHERE name = '".$attrname."'";
  333. $sql.= " AND entity IN (0,".$conf->entity.')';
  334. $sql.= " AND elementtype = '".$elementtype."'";
  335. dol_syslog(get_class($this)."::delete_label", LOG_DEBUG);
  336. $resql=$this->db->query($sql);
  337. if ($resql)
  338. {
  339. return 1;
  340. }
  341. else
  342. {
  343. print dol_print_error($this->db);
  344. return -1;
  345. }
  346. }
  347. else
  348. {
  349. return 0;
  350. }
  351. }
  352. /**
  353. * Modify type of a personalized attribute
  354. *
  355. * @param string $attrname Name of attribute
  356. * @param string $label Label of attribute
  357. * @param string $type Type of attribute
  358. * @param int $length Length of attribute
  359. * @param string $elementtype Element type ('member', 'product', 'thirdparty', 'contact', ...)
  360. * @param int $unique Is field unique or not
  361. * @param int $required Is field required or not
  362. * @param int $pos Position of attribute
  363. * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
  364. * @param int $alwayseditable Is attribute always editable regardless of the document status
  365. * @param string $perms Permission to check
  366. * @param int $list Into list view by default
  367. * @param int $ishidden Is hidden extrafield
  368. * @return int >0 if OK, <=0 if KO
  369. */
  370. function update($attrname,$label,$type,$length,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0, $perms='',$list='',$ishidden=0)
  371. {
  372. if ($elementtype == 'thirdparty') $elementtype='societe';
  373. if ($elementtype == 'contact') $elementtype='socpeople';
  374. $table=$elementtype.'_extrafields';
  375. if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
  376. {
  377. if ($type=='boolean') {
  378. $typedb='int';
  379. $lengthdb='1';
  380. } elseif($type=='price') {
  381. $typedb='double';
  382. $lengthdb='24,8';
  383. } elseif($type=='phone') {
  384. $typedb='varchar';
  385. $lengthdb='20';
  386. }elseif($type=='mail') {
  387. $typedb='varchar';
  388. $lengthdb='128';
  389. } elseif (($type=='select') || ($type=='sellist') || ($type=='radio') || ($type=='checkbox') || ($type=='chkbxlst')) {
  390. $typedb='text';
  391. $lengthdb='';
  392. } elseif ($type=='link') {
  393. $typedb='int';
  394. $lengthdb='11';
  395. } else {
  396. $typedb=$type;
  397. $lengthdb=$length;
  398. }
  399. $field_desc = array('type'=>$typedb, 'value'=>$lengthdb, 'null'=>($required?'NOT NULL':'NULL'));
  400. if ($type != 'separate') // No table update when separate type
  401. {
  402. $result=$this->db->DDLUpdateField(MAIN_DB_PREFIX.$table, $attrname, $field_desc);
  403. }
  404. if ($result > 0 || $type == 'separate')
  405. {
  406. if ($label)
  407. {
  408. $result=$this->update_label($attrname,$label,$type,$length,$elementtype,$unique,$required,$pos,$param,$alwayseditable,$perms,$list,$ishidden);
  409. }
  410. if ($result > 0)
  411. {
  412. $sql='';
  413. if ($unique)
  414. {
  415. $sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." ADD UNIQUE INDEX uk_".$table."_".$attrname." (".$attrname.")";
  416. }
  417. else
  418. {
  419. $sql="ALTER TABLE ".MAIN_DB_PREFIX.$table." DROP INDEX uk_".$table."_".$attrname;
  420. }
  421. dol_syslog(get_class($this).'::update', LOG_DEBUG);
  422. $resql=$this->db->query($sql,1,'dml');
  423. return 1;
  424. }
  425. else
  426. {
  427. $this->error=$this->db->lasterror();
  428. return -1;
  429. }
  430. }
  431. else
  432. {
  433. $this->error=$this->db->lasterror();
  434. return -1;
  435. }
  436. }
  437. else
  438. {
  439. return 0;
  440. }
  441. }
  442. /**
  443. * Modify description of personalized attribute
  444. *
  445. * @param string $attrname Name of attribute
  446. * @param string $label Label of attribute
  447. * @param string $type Type of attribute
  448. * @param int $size Length of attribute
  449. * @param string $elementtype Element type ('member', 'product', 'thirdparty', ...)
  450. * @param int $unique Is field unique or not
  451. * @param int $required Is field required or not
  452. * @param int $pos Position of attribute
  453. * @param array $param Params for field (ex for select list : array('options' => array(value'=>'label of option')) )
  454. * @param int $alwayseditable Is attribute always editable regardless of the document status
  455. * @param string $perms Permission to check
  456. * @param int $list Into list view by default
  457. * @param int $ishidden Is hidden extrafield
  458. * @return int <=0 if KO, >0 if OK
  459. */
  460. private function update_label($attrname,$label,$type,$size,$elementtype,$unique=0,$required=0,$pos=0,$param='',$alwayseditable=0,$perms='',$list=0,$ishidden=0)
  461. {
  462. global $conf;
  463. dol_syslog(get_class($this)."::update_label ".$attrname.", ".$label.", ".$type.", ".$size.", ".$elementtype.", ".$unique.", ".$required.", ".$pos.", ".$alwayseditable.", ".$perms.", ".$list.", ".$ishidden);
  464. // Clean parameters
  465. if ($elementtype == 'thirdparty') $elementtype='societe';
  466. if ($elementtype == 'contact') $elementtype='socpeople';
  467. if (empty($list)) $list=0;
  468. if (isset($attrname) && $attrname != '' && preg_match("/^\w[a-zA-Z0-9-_]*$/",$attrname))
  469. {
  470. $this->db->begin();
  471. if(is_array($param) && count($param) > 0)
  472. {
  473. $param = $this->db->escape(serialize($param));
  474. }
  475. $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."extrafields";
  476. $sql_del.= " WHERE name = '".$attrname."'";
  477. $sql_del.= " AND entity = ".$conf->entity;
  478. $sql_del.= " AND elementtype = '".$elementtype."'";
  479. dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
  480. $resql1=$this->db->query($sql_del);
  481. $sql = "INSERT INTO ".MAIN_DB_PREFIX."extrafields(";
  482. $sql.= " name,"; // This is code
  483. $sql.= " entity,";
  484. $sql.= " label,";
  485. $sql.= " type,";
  486. $sql.= " size,";
  487. $sql.= " elementtype,";
  488. $sql.= " fieldunique,";
  489. $sql.= " fieldrequired,";
  490. $sql.= " perms,";
  491. $sql.= " pos,";
  492. $sql.= " alwayseditable,";
  493. $sql.= " param,";
  494. $sql.= " list";
  495. $sql.= ", ishidden";
  496. $sql.= ") VALUES (";
  497. $sql.= "'".$attrname."',";
  498. $sql.= " ".$conf->entity.",";
  499. $sql.= " '".$this->db->escape($label)."',";
  500. $sql.= " '".$type."',";
  501. $sql.= " '".$size."',";
  502. $sql.= " '".$elementtype."',";
  503. $sql.= " '".$unique."',";
  504. $sql.= " '".$required."',";
  505. $sql.= " ".($perms?"'".$this->db->escape($perms)."'":"null").",";
  506. $sql.= " '".$pos."',";
  507. $sql.= " '".$alwayseditable."',";
  508. $sql.= " '".$param."',";
  509. $sql.= " ".$list;
  510. $sql.= ", ".$ishidden;
  511. $sql.= ")";
  512. dol_syslog(get_class($this)."::update_label", LOG_DEBUG);
  513. $resql2=$this->db->query($sql);
  514. if ($resql1 && $resql2)
  515. {
  516. $this->db->commit();
  517. return 1;
  518. }
  519. else
  520. {
  521. $this->db->rollback();
  522. print dol_print_error($this->db);
  523. return -1;
  524. }
  525. }
  526. else
  527. {
  528. return 0;
  529. }
  530. }
  531. /**
  532. * Load array this->attribute_xxx like attribute_label, attribute_type, ...
  533. *
  534. * @param string $elementtype Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...)
  535. * @param boolean $forceload Force load of extra fields whatever is option MAIN_EXTRAFIELDS_DISABLED
  536. * @return array Array of attributes for all extra fields
  537. */
  538. function fetch_name_optionals_label($elementtype,$forceload=false)
  539. {
  540. global $conf;
  541. if ( empty($elementtype) ) return array();
  542. if ($elementtype == 'thirdparty') $elementtype='societe';
  543. if ($elementtype == 'contact') $elementtype='socpeople';
  544. $array_name_label=array();
  545. // For avoid conflicts with external modules
  546. if (!$forceload && !empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) return $array_name_label;
  547. $sql = "SELECT rowid,name,label,type,size,elementtype,fieldunique,fieldrequired,param,pos,alwayseditable,perms,list,ishidden";
  548. $sql.= " FROM ".MAIN_DB_PREFIX."extrafields";
  549. $sql.= " WHERE entity IN (0,".$conf->entity.")";
  550. if ($elementtype) $sql.= " AND elementtype = '".$elementtype."'";
  551. $sql.= " ORDER BY pos";
  552. dol_syslog(get_class($this)."::fetch_name_optionals_label", LOG_DEBUG);
  553. $resql=$this->db->query($sql);
  554. if ($resql)
  555. {
  556. if ($this->db->num_rows($resql))
  557. {
  558. while ($tab = $this->db->fetch_object($resql))
  559. {
  560. // we can add this attribute to adherent object
  561. if ($tab->type != 'separate')
  562. {
  563. $array_name_label[$tab->name]=$tab->label;
  564. }
  565. $this->attribute_type[$tab->name]=$tab->type;
  566. $this->attribute_label[$tab->name]=$tab->label;
  567. $this->attribute_size[$tab->name]=$tab->size;
  568. $this->attribute_elementtype[$tab->name]=$tab->elementtype;
  569. $this->attribute_unique[$tab->name]=$tab->fieldunique;
  570. $this->attribute_required[$tab->name]=$tab->fieldrequired;
  571. $this->attribute_param[$tab->name]=($tab->param ? unserialize($tab->param) : '');
  572. $this->attribute_pos[$tab->name]=$tab->pos;
  573. $this->attribute_alwayseditable[$tab->name]=$tab->alwayseditable;
  574. $this->attribute_perms[$tab->name]=$tab->perms;
  575. $this->attribute_list[$tab->name]=$tab->list;
  576. $this->attribute_hidden[$tab->name]=$tab->ishidden;
  577. }
  578. }
  579. }
  580. else
  581. {
  582. $this->error=$this->db->lasterror();
  583. dol_syslog(get_class($this)."::fetch_name_optionals_label ".$this->error, LOG_ERR);
  584. }
  585. return $array_name_label;
  586. }
  587. /**
  588. * Return HTML string to put an input field into a page
  589. *
  590. * @param string $key Key of attribute
  591. * @param string $value Value to show (for date type it must be in timestamp format)
  592. * @param string $moreparam To add more parametes on html input tag
  593. * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names)
  594. * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names)
  595. * @param int $showsize Value for size attributed
  596. * @param int $objectid Current object id
  597. * @return string
  598. */
  599. function showInputField($key,$value,$moreparam='',$keyprefix='',$keysuffix='',$showsize=0, $objectid=0)
  600. {
  601. global $conf,$langs;
  602. $label=$this->attribute_label[$key];
  603. $type =$this->attribute_type[$key];
  604. $size =$this->attribute_size[$key];
  605. $elementtype=$this->attribute_elementtype[$key];
  606. $unique=$this->attribute_unique[$key];
  607. $required=$this->attribute_required[$key];
  608. $param=$this->attribute_param[$key];
  609. $perms=$this->attribute_perms[$key];
  610. $list=$this->attribute_list[$key];
  611. $hidden=$this->attribute_hidden[$key];
  612. if (empty($showsize))
  613. {
  614. if ($type == 'date')
  615. {
  616. $showsize=10;
  617. }
  618. elseif ($type == 'datetime')
  619. {
  620. $showsize=19;
  621. }
  622. elseif (in_array($type,array('int','double')))
  623. {
  624. $showsize=10;
  625. }
  626. else
  627. {
  628. $showsize=round($size);
  629. if ($showsize > 48) $showsize=48;
  630. }
  631. }
  632. if (in_array($type,array('date','datetime')))
  633. {
  634. $tmp=explode(',',$size);
  635. $newsize=$tmp[0];
  636. $showtime = in_array($type,array('datetime')) ? 1 : 0;
  637. // Do not show current date when field not required (see select_date() method)
  638. if (!$required && $value == '') $value = '-1';
  639. require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
  640. global $form;
  641. if (! is_object($form)) $form=new Form($this->db);
  642. // TODO Must also support $moreparam
  643. $out = $form->select_date($value, $keysuffix.'options_'.$key.$keyprefix, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1);
  644. }
  645. elseif (in_array($type,array('int')))
  646. {
  647. $tmp=explode(',',$size);
  648. $newsize=$tmp[0];
  649. $out='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="'.$showsize.'" maxlength="'.$newsize.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
  650. }
  651. elseif ($type == 'varchar')
  652. {
  653. $out='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="'.$showsize.'" maxlength="'.$size.'" value="'.$value.'"'.($moreparam?$moreparam:'').'>';
  654. }
  655. elseif ($type == 'text')
  656. {
  657. require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
  658. $doleditor=new DolEditor($keysuffix.'options_'.$key.$keyprefix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100);
  659. $out=$doleditor->Create(1);
  660. }
  661. elseif ($type == 'boolean')
  662. {
  663. $checked='';
  664. if (!empty($value)) {
  665. $checked=' checked value="1" ';
  666. } else {
  667. $checked=' value="1" ';
  668. }
  669. $out='<input type="checkbox" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" '.$checked.' '.($moreparam?$moreparam:'').'>';
  670. }
  671. elseif ($type == 'mail')
  672. {
  673. $out='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="32" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
  674. }
  675. elseif ($type == 'phone')
  676. {
  677. $out='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="20" value="'.$value.'" '.($moreparam?$moreparam:'').'>';
  678. }
  679. elseif ($type == 'price')
  680. {
  681. $out='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="6" value="'.price($value).'" '.($moreparam?$moreparam:'').'> '.$langs->getCurrencySymbol($conf->currency);
  682. }
  683. elseif ($type == 'double')
  684. {
  685. if (!empty($value)) {
  686. $value=price($value);
  687. }
  688. $out='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="6" value="'.$value.'" '.($moreparam?$moreparam:'').'> ';
  689. }
  690. elseif ($type == 'select')
  691. {
  692. $out = '';
  693. if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
  694. {
  695. include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
  696. $out.= ajax_combobox($keysuffix.'options_'.$key.$keyprefix, array(), 0);
  697. }
  698. $out.='<select class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" id="options_'.$key.$keyprefix.'" '.($moreparam?$moreparam:'').'>';
  699. $out.='<option value="0">&nbsp;</option>';
  700. foreach ($param['options'] as $key => $val)
  701. {
  702. if ($key == '') continue;
  703. list($val, $parent) = explode('|', $val);
  704. $out.='<option value="'.$key.'"';
  705. $out.= ($value==$key?' selected':'');
  706. $out.= (!empty($parent)?' parent="'.$parent.'"':'');
  707. $out.='>'.$val.'</option>';
  708. }
  709. $out.='</select>';
  710. }
  711. elseif ($type == 'sellist')
  712. {
  713. $out = '';
  714. if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->MAIN_EXTRAFIELDS_USE_SELECT2))
  715. {
  716. include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
  717. $out.= ajax_combobox($keysuffix.'options_'.$key.$keyprefix, array(), 0);
  718. }
  719. $out.='<select class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" id="options_'.$key.$keyprefix.'" '.($moreparam?$moreparam:'').'>';
  720. if (is_array($param['options']))
  721. {
  722. $param_list=array_keys($param['options']);
  723. $InfoFieldList = explode(":", $param_list[0]);
  724. // 0 : tableName
  725. // 1 : label field name
  726. // 2 : key fields name (if differ of rowid)
  727. // 3 : key field parent (for dependent lists)
  728. // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
  729. $keyList=(empty($InfoFieldList[2])?'rowid':$InfoFieldList[2].' as rowid');
  730. if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3]))
  731. {
  732. list($parentName, $parentField) = explode('|', $InfoFieldList[3]);
  733. $keyList.= ', '.$parentField;
  734. }
  735. if (count($InfoFieldList) > 4 && ! empty($InfoFieldList[4]))
  736. {
  737. if (strpos($InfoFieldList[4], 'extra.') !== false)
  738. {
  739. $keyList='main.'.$InfoFieldList[2].' as rowid';
  740. } else {
  741. $keyList=$InfoFieldList[2].' as rowid';
  742. }
  743. }
  744. $fields_label = explode('|',$InfoFieldList[1]);
  745. if (is_array($fields_label))
  746. {
  747. $keyList .=', ';
  748. $keyList .= implode(', ', $fields_label);
  749. }
  750. $sqlwhere='';
  751. $sql = 'SELECT '.$keyList;
  752. $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
  753. if (!empty($InfoFieldList[4]))
  754. {
  755. // can use SELECT request
  756. if (strpos($InfoFieldList[4], '$SEL$')!==false) {
  757. $InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
  758. }
  759. // current object id can be use into filter
  760. if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
  761. $InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
  762. } else {
  763. $InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
  764. }
  765. //We have to join on extrafield table
  766. if (strpos($InfoFieldList[4], 'extra')!==false)
  767. {
  768. $sql.= ' as main, '.MAIN_DB_PREFIX .$InfoFieldList[0].'_extrafields as extra';
  769. $sqlwhere.= ' WHERE extra.fk_object=main.'.$InfoFieldList[2]. ' AND '.$InfoFieldList[4];
  770. }
  771. else
  772. {
  773. $sqlwhere.= ' WHERE '.$InfoFieldList[4];
  774. }
  775. }
  776. else
  777. {
  778. $sqlwhere.= ' WHERE 1=1';
  779. }
  780. // Some tables may have field, some other not. For the moment we disable it.
  781. if (in_array($InfoFieldList[0],array('tablewithentity')))
  782. {
  783. $sqlwhere.= ' AND entity = '.$conf->entity;
  784. }
  785. $sql.=$sqlwhere;
  786. //print $sql;
  787. $sql .= ' ORDER BY ' . implode(', ', $fields_label);
  788. dol_syslog(get_class($this).'::showInputField type=sellist', LOG_DEBUG);
  789. $resql = $this->db->query($sql);
  790. if ($resql)
  791. {
  792. $out.='<option value="0">&nbsp;</option>';
  793. $num = $this->db->num_rows($resql);
  794. $i = 0;
  795. while ($i < $num)
  796. {
  797. $labeltoshow='';
  798. $obj = $this->db->fetch_object($resql);
  799. // Several field into label (eq table:code|libelle:rowid)
  800. $fields_label = explode('|',$InfoFieldList[1]);
  801. if(is_array($fields_label))
  802. {
  803. $notrans = true;
  804. foreach ($fields_label as $field_toshow)
  805. {
  806. $labeltoshow.= $obj->$field_toshow.' ';
  807. }
  808. }
  809. else
  810. {
  811. $labeltoshow=$obj->{$InfoFieldList[1]};
  812. }
  813. $labeltoshow=dol_trunc($labeltoshow,45);
  814. if ($value==$obj->rowid)
  815. {
  816. foreach ($fields_label as $field_toshow)
  817. {
  818. $translabel=$langs->trans($obj->$field_toshow);
  819. if ($translabel!=$obj->$field_toshow) {
  820. $labeltoshow=dol_trunc($translabel,18).' ';
  821. }else {
  822. $labeltoshow=dol_trunc($obj->$field_toshow,18).' ';
  823. }
  824. }
  825. $out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
  826. }
  827. else
  828. {
  829. if(!$notrans)
  830. {
  831. $translabel=$langs->trans($obj->{$InfoFieldList[1]});
  832. if ($translabel!=$obj->{$InfoFieldList[1]}) {
  833. $labeltoshow=dol_trunc($translabel,18);
  834. }
  835. else {
  836. $labeltoshow=dol_trunc($obj->{$InfoFieldList[1]},18);
  837. }
  838. }
  839. if (empty($labeltoshow)) $labeltoshow='(not defined)';
  840. if ($value==$obj->rowid)
  841. {
  842. $out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
  843. }
  844. if (!empty($InfoFieldList[3]))
  845. {
  846. $parent = $parentName.':'.$obj->{$parentField};
  847. }
  848. $out.='<option value="'.$obj->rowid.'"';
  849. $out.= ($value==$obj->rowid?' selected':'');
  850. $out.= (!empty($parent)?' parent="'.$parent.'"':'');
  851. $out.='>'.$labeltoshow.'</option>';
  852. }
  853. $i++;
  854. }
  855. $this->db->free($resql);
  856. }
  857. else {
  858. print 'Error in request '.$sql.' '.$this->db->lasterror().'. Check setup of extra parameters.<br>';
  859. }
  860. }
  861. $out.='</select>';
  862. }
  863. elseif ($type == 'checkbox')
  864. {
  865. $out='';
  866. $value_arr=explode(',',$value);
  867. foreach ($param['options'] as $keyopt=>$val )
  868. {
  869. $out.='<input class="flat" type="checkbox" name="'.$keysuffix.'options_'.$key.$keyprefix.'[]" '.($moreparam?$moreparam:'');
  870. $out.=' value="'.$keyopt.'"';
  871. if ((is_array($value_arr)) && in_array($keyopt,$value_arr)) {
  872. $out.= 'checked';
  873. }else {
  874. $out.='';
  875. }
  876. $out.='/>'.$val.'<br>';
  877. }
  878. }
  879. elseif ($type == 'radio')
  880. {
  881. $out='';
  882. foreach ($param['options'] as $keyopt=>$val )
  883. {
  884. $out.='<input class="flat" type="radio" name="'.$keysuffix.'options_'.$key.$keyprefix.'" '.($moreparam?$moreparam:'');
  885. $out.=' value="'.$keyopt.'"';
  886. $out.= ($value==$keyopt?'checked':'');
  887. $out.='/>'.$val.'<br>';
  888. }
  889. }
  890. elseif ($type == 'chkbxlst')
  891. {
  892. if (is_array($value)) {
  893. $value_arr = $value;
  894. }
  895. else {
  896. $value_arr = explode(',', $value);
  897. }
  898. if (is_array($param['options'])) {
  899. $param_list = array_keys($param['options']);
  900. $InfoFieldList = explode(":", $param_list[0]);
  901. // 0 : tableName
  902. // 1 : label field name
  903. // 2 : key fields name (if differ of rowid)
  904. // 3 : key field parent (for dependent lists)
  905. // 4 : where clause filter on column or table extrafield, syntax field='value' or extra.field=value
  906. $keyList = (empty($InfoFieldList[2]) ? 'rowid' : $InfoFieldList[2] . ' as rowid');
  907. if (count($InfoFieldList) > 3 && ! empty($InfoFieldList[3])) {
  908. list ( $parentName, $parentField ) = explode('|', $InfoFieldList[3]);
  909. $keyList .= ', ' . $parentField;
  910. }
  911. if (count($InfoFieldList) > 4 && ! empty($InfoFieldList[4])) {
  912. if (strpos($InfoFieldList[4], 'extra.') !== false) {
  913. $keyList = 'main.' . $InfoFieldList[2] . ' as rowid';
  914. } else {
  915. $keyList = $InfoFieldList[2] . ' as rowid';
  916. }
  917. }
  918. $fields_label = explode('|', $InfoFieldList[1]);
  919. if (is_array($fields_label)) {
  920. $keyList .= ', ';
  921. $keyList .= implode(', ', $fields_label);
  922. }
  923. $sqlwhere = '';
  924. $sql = 'SELECT ' . $keyList;
  925. $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
  926. if (! empty($InfoFieldList[4])) {
  927. // can use SELECT request
  928. if (strpos($InfoFieldList[4], '$SEL$')!==false) {
  929. $InfoFieldList[4]=str_replace('$SEL$','SELECT',$InfoFieldList[4]);
  930. }
  931. // current object id can be use into filter
  932. if (strpos($InfoFieldList[4], '$ID$')!==false && !empty($objectid)) {
  933. $InfoFieldList[4]=str_replace('$ID$',$objectid,$InfoFieldList[4]);
  934. } else {
  935. $InfoFieldList[4]=str_replace('$ID$','0',$InfoFieldList[4]);
  936. }
  937. // We have to join on extrafield table
  938. if (strpos($InfoFieldList[4], 'extra') !== false) {
  939. $sql .= ' as main, ' . MAIN_DB_PREFIX . $InfoFieldList[0] . '_extrafields as extra';
  940. $sqlwhere .= ' WHERE extra.fk_object=main.' . $InfoFieldList[2] . ' AND ' . $InfoFieldList[4];
  941. } else {
  942. $sqlwhere .= ' WHERE ' . $InfoFieldList[4];
  943. }
  944. } else {
  945. $sqlwhere .= ' WHERE 1=1';
  946. }
  947. // Some tables may have field, some other not. For the moment we disable it.
  948. if (in_array($InfoFieldList[0], array ('tablewithentity')))
  949. {
  950. $sqlwhere .= ' AND entity = ' . $conf->entity;
  951. }
  952. // $sql.=preg_replace('/^ AND /','',$sqlwhere);
  953. // print $sql;
  954. $sql .= $sqlwhere;
  955. dol_syslog(get_class($this) . '::showInputField type=chkbxlst',LOG_DEBUG);
  956. $resql = $this->db->query($sql);
  957. if ($resql) {
  958. $num = $this->db->num_rows($resql);
  959. $i = 0;
  960. while ( $i < $num ) {
  961. $labeltoshow = '';
  962. $obj = $this->db->fetch_object($resql);
  963. // Several field into label (eq table:code|libelle:rowid)
  964. $fields_label = explode('|', $InfoFieldList[1]);
  965. if (is_array($fields_label)) {
  966. $notrans = true;
  967. foreach ( $fields_label as $field_toshow ) {
  968. $labeltoshow .= $obj->$field_toshow . ' ';
  969. }
  970. } else {
  971. $labeltoshow = $obj->{$InfoFieldList[1]};
  972. }
  973. $labeltoshow = dol_trunc($labeltoshow, 45);
  974. if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
  975. foreach ( $fields_label as $field_toshow ) {
  976. $translabel = $langs->trans($obj->$field_toshow);
  977. if ($translabel != $obj->$field_toshow) {
  978. $labeltoshow = dol_trunc($translabel, 18) . ' ';
  979. } else {
  980. $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' ';
  981. }
  982. }
  983. $out .= '<input class="flat" type="checkbox" name="'.$keysuffix.'options_' . $key . $keyprefix . '[]" ' . ($moreparam ? $moreparam : '');
  984. $out .= ' value="' . $obj->rowid . '"';
  985. $out .= 'checked';
  986. $out .= '/>' . $labeltoshow . '<br>';
  987. } else {
  988. if (! $notrans) {
  989. $translabel = $langs->trans($obj->{$InfoFieldList[1]});
  990. if ($translabel != $obj->{$InfoFieldList[1]}) {
  991. $labeltoshow = dol_trunc($translabel, 18);
  992. } else {
  993. $labeltoshow = dol_trunc($obj->{$InfoFieldList[1]}, 18);
  994. }
  995. }
  996. if (empty($labeltoshow))
  997. $labeltoshow = '(not defined)';
  998. if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
  999. $out .= '<input class="flat" type="checkbox" name="'.$keysuffix.'options_' . $key . $keyprefix . '[]" ' . ($moreparam ? $moreparam : '');
  1000. $out .= ' value="' . $obj->rowid . '"';
  1001. $out .= 'checked';
  1002. $out .= '';
  1003. $out .= '/>' . $labeltoshow . '<br>';
  1004. }
  1005. if (! empty($InfoFieldList[3])) {
  1006. $parent = $parentName . ':' . $obj->{$parentField};
  1007. }
  1008. $out .= '<input class="flat" type="checkbox" name="'.$keysuffix.'options_' . $key . $keyprefix . '[]" ' . ($moreparam ? $moreparam : '');
  1009. $out .= ' value="' . $obj->rowid . '"';
  1010. $out .= ((is_array($value_arr) && in_array($obj->rowid, $value_arr)) ? ' checked ' : '');
  1011. ;
  1012. $out .= '';
  1013. $out .= '/>' . $labeltoshow . '<br>';
  1014. }
  1015. $i ++;
  1016. }
  1017. $this->db->free($resql);
  1018. } else {
  1019. print 'Error in request ' . $sql . ' ' . $this->db->lasterror() . '. Check setup of extra parameters.<br>';
  1020. }
  1021. }
  1022. $out .= '</select>';
  1023. }
  1024. elseif ($type == 'link')
  1025. {
  1026. $out='';
  1027. $param_list=array_keys($param['options']);
  1028. // 0 : ObjectName
  1029. // 1 : classPath
  1030. $InfoFieldList = explode(":", $param_list[0]);
  1031. dol_include_once($InfoFieldList[1]);
  1032. if ($InfoFieldList[0] && class_exists($InfoFieldList[0]))
  1033. {
  1034. $object = new $InfoFieldList[0]($this->db);
  1035. if (!empty($value)) $object->fetch($value);
  1036. $valuetoshow=$object->ref;
  1037. if ($object->element == 'societe') $valuetoshow=$object->name; // Special case for thirdparty because ref is id because name is not unique
  1038. $out.='<input type="text" class="flat" name="'.$keysuffix.'options_'.$key.$keyprefix.'" size="20" value="'.$valuetoshow.'" >';
  1039. }
  1040. else
  1041. {
  1042. dol_syslog('Error bad setup of extrafield', LOG_WARNING);
  1043. $out.='Error bad setup of extrafield';
  1044. }
  1045. }
  1046. if (!empty($hidden)) {
  1047. $out='<input type="hidden" value="'.$value.'" name="'.$keysuffix.'options_'.$key.$keyprefix.'" id="'.$keysuffix.'options_'.$key.$keyprefix.'"/>';
  1048. }
  1049. /* Add comments
  1050. if ($type == 'date') $out.=' (YYYY-MM-DD)';
  1051. elseif ($type == 'datetime') $out.=' (YYYY-MM-DD HH:MM:SS)';
  1052. */
  1053. return $out;
  1054. }
  1055. /**
  1056. * Return HTML string to put an output field into a page
  1057. *
  1058. * @param string $key Key of attribute
  1059. * @param string $value Value to show
  1060. * @param string $moreparam To add more parametes on html input tag (only checkbox use html input for output rendering)
  1061. * @return string Formated value
  1062. */
  1063. function showOutputField($key,$value,$moreparam='')
  1064. {
  1065. global $conf,$langs;
  1066. $label=$this->attribute_label[$key];
  1067. $type=$this->attribute_type[$key];
  1068. $size=$this->attribute_size[$key];
  1069. $elementtype=$this->attribute_elementtype[$key];
  1070. $unique=$this->attribute_unique[$key];
  1071. $required=$this->attribute_required[$key];
  1072. $params=$this->attribute_param[$key];
  1073. $perms=$this->attribute_perms[$key];
  1074. $list=$this->attribute_list[$key];
  1075. $hidden=$this->attribute_hidden[$key];
  1076. $showsize=0;
  1077. if ($type == 'date')
  1078. {
  1079. $showsize=10;
  1080. $value=dol_print_date($value,'day');
  1081. }
  1082. elseif ($type == 'datetime')
  1083. {
  1084. $showsize=19;
  1085. $value=dol_print_date($value,'dayhour');
  1086. }
  1087. elseif ($type == 'int')
  1088. {
  1089. $showsize=10;
  1090. }
  1091. elseif ($type == 'double')
  1092. {
  1093. if (!empty($value)) {
  1094. $value=price($value);
  1095. }
  1096. }
  1097. elseif ($type == 'boolean')
  1098. {
  1099. $checked='';
  1100. if (!empty($value)) {
  1101. $checked=' checked ';
  1102. }
  1103. $value='<input type="checkbox" '.$checked.' '.($moreparam?$moreparam:'').' readonly disabled>';
  1104. }
  1105. elseif ($type == 'mail')
  1106. {
  1107. $value=dol_print_email($value);
  1108. }
  1109. elseif ($type == 'phone')
  1110. {
  1111. $value=dol_print_phone($value);
  1112. }
  1113. elseif ($type == 'price')
  1114. {
  1115. $value=price($value,0,$langs,0,0,-1,$conf->currency);
  1116. }
  1117. elseif ($type == 'select')
  1118. {
  1119. $value=$params['options'][$value];
  1120. }
  1121. elseif ($type == 'sellist')
  1122. {
  1123. $param_list=array_keys($params['options']);
  1124. $InfoFieldList = explode(":", $param_list[0]);
  1125. $selectkey="rowid";
  1126. $keyList='rowid';
  1127. if (count($InfoFieldList)>=3)
  1128. {
  1129. $selectkey = $InfoFieldList[2];
  1130. $keyList=$InfoFieldList[2].' as rowid';
  1131. }
  1132. $fields_label = explode('|',$InfoFieldList[1]);
  1133. if(is_array($fields_label)) {
  1134. $keyList .=', ';
  1135. $keyList .= implode(', ', $fields_label);
  1136. }
  1137. $sql = 'SELECT '.$keyList;
  1138. $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[0];
  1139. if (strpos($InfoFieldList[4], 'extra')!==false)
  1140. {
  1141. $sql.= ' as main';
  1142. }
  1143. $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
  1144. //$sql.= ' AND entity = '.$conf->entity;
  1145. dol_syslog(get_class($this).':showOutputField:$type=sellist', LOG_DEBUG);
  1146. $resql = $this->db->query($sql);
  1147. if ($resql)
  1148. {
  1149. $value=''; // value was used, so now we reste it to use it to build final output
  1150. $obj = $this->db->fetch_object($resql);
  1151. // Several field into label (eq table:code|libelle:rowid)
  1152. $fields_label = explode('|',$InfoFieldList[1]);
  1153. if(is_array($fields_label) && count($fields_label)>1)
  1154. {
  1155. foreach ($fields_label as $field_toshow)
  1156. {
  1157. $translabel='';
  1158. if (!empty($obj->$field_toshow)) {
  1159. $translabel=$langs->trans($obj->$field_toshow);
  1160. }
  1161. if ($translabel!=$field_toshow) {
  1162. $value.=dol_trunc($translabel,18).' ';
  1163. }else {
  1164. $value.=$obj->$field_toshow.' ';
  1165. }
  1166. }
  1167. }
  1168. else
  1169. {
  1170. $translabel='';
  1171. if (!empty($obj->{$InfoFieldList[1]})) {
  1172. $translabel=$langs->trans($obj->{$InfoFieldList[1]});
  1173. }
  1174. if ($translabel!=$obj->{$InfoFieldList[1]}) {
  1175. $value=dol_trunc($translabel,18);
  1176. }else {
  1177. $value=$obj->{$InfoFieldList[1]};
  1178. }
  1179. }
  1180. }
  1181. else dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING);
  1182. }
  1183. elseif ($type == 'radio')
  1184. {
  1185. $value=$params['options'][$value];
  1186. }
  1187. elseif ($type == 'checkbox')
  1188. {
  1189. $value_arr=explode(',',$value);
  1190. $value='';
  1191. if (is_array($value_arr))
  1192. {
  1193. foreach ($value_arr as $keyval=>$valueval) {
  1194. $value.=$params['options'][$valueval].'<br>';
  1195. }
  1196. }
  1197. }
  1198. elseif ($type == 'chkbxlst')
  1199. {
  1200. $value_arr = explode(',', $value);
  1201. $param_list = array_keys($params['options']);
  1202. $InfoFieldList = explode(":", $param_list[0]);
  1203. $selectkey = "rowid";
  1204. $keyList = 'rowid';
  1205. if (count($InfoFieldList) >= 3) {
  1206. $selectkey = $InfoFieldList[2];
  1207. $keyList = $InfoFieldList[2] . ' as rowid';
  1208. }
  1209. $fields_label = explode('|', $InfoFieldList[1]);
  1210. if (is_array($fields_label)) {
  1211. $keyList .= ', ';
  1212. $keyList .= implode(', ', $fields_label);
  1213. }
  1214. $sql = 'SELECT ' . $keyList;
  1215. $sql .= ' FROM ' . MAIN_DB_PREFIX . $InfoFieldList[0];
  1216. if (strpos($InfoFieldList[4], 'extra') !== false) {
  1217. $sql .= ' as main';
  1218. }
  1219. // $sql.= " WHERE ".$selectkey."='".$this->db->escape($value)."'";
  1220. // $sql.= ' AND entity = '.$conf->entity;
  1221. dol_syslog(get_class($this) . ':showOutputField:$type=chkbxlst',LOG_DEBUG);
  1222. $resql = $this->db->query($sql);
  1223. if ($resql) {
  1224. $value = ''; // value was used, so now we reste it to use it to build final output
  1225. while ( $obj = $this->db->fetch_object($resql) ) {
  1226. // Several field into label (eq table:code|libelle:rowid)
  1227. $fields_label = explode('|', $InfoFieldList[1]);
  1228. if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) {
  1229. if (is_array($fields_label) && count($fields_label) > 1) {
  1230. foreach ( $fields_label as $field_toshow ) {
  1231. $translabel = '';
  1232. if (! empty($obj->$field_toshow)) {
  1233. $translabel = $langs->trans($obj->$field_toshow);
  1234. }
  1235. if ($translabel != $field_toshow) {
  1236. $value .= dol_trunc($translabel, 18) . '<BR>';
  1237. } else {
  1238. $value .= $obj->$field_toshow . '<BR>';
  1239. }
  1240. }
  1241. } else {
  1242. $translabel = '';
  1243. if (! empty($obj->{$InfoFieldList[1]})) {
  1244. $translabel = $langs->trans($obj->{$InfoFieldList[1]});
  1245. }
  1246. if ($translabel != $obj->{$InfoFieldList[1]}) {
  1247. $value .= dol_trunc($translabel, 18) . '<BR>';
  1248. } else {
  1249. $value .= $obj->{$InfoFieldList[1]} . '<BR>';
  1250. }
  1251. }
  1252. }
  1253. }
  1254. } else
  1255. dol_syslog(get_class($this) . '::showOutputField error ' . $this->db->lasterror(), LOG_WARNING);
  1256. }
  1257. elseif ($type == 'link')
  1258. {
  1259. $out='';
  1260. // only if something to display (perf)
  1261. if ($value)
  1262. {
  1263. $param_list=array_keys($params['options']);
  1264. // 0 : ObjectName
  1265. // 1 : classPath
  1266. $InfoFieldList = explode(":", $param_list[0]);
  1267. dol_include_once($InfoFieldList[1]);
  1268. if ($InfoFieldList[0] && class_exists($InfoFieldList[0]))
  1269. {
  1270. $object = new $InfoFieldList[0]($this->db);
  1271. $object->fetch($value);
  1272. $value=$object->getNomUrl(3);
  1273. }
  1274. else
  1275. {
  1276. dol_syslog('Error bad setup of extrafield', LOG_WARNING);
  1277. $out.='Error bad setup of extrafield';
  1278. }
  1279. }
  1280. }
  1281. elseif ($type == 'text')
  1282. {
  1283. $value=dol_htmlentitiesbr($value);
  1284. }
  1285. else
  1286. {
  1287. $showsize=round($size);
  1288. if ($showsize > 48) $showsize=48;
  1289. }
  1290. //print $type.'-'.$size;
  1291. $out=$value;
  1292. if (!empty($hidden)) {
  1293. $out='';
  1294. }
  1295. return $out;
  1296. }
  1297. /**
  1298. * Return tag to describe alignement to use for this extrafield
  1299. *
  1300. * @param string $key Key of attribute
  1301. * @return string Formated value
  1302. */
  1303. function getAlignFlag($key)
  1304. {
  1305. global $conf,$langs;
  1306. $type=$this->attribute_type[$key];
  1307. $align='';
  1308. if ($type == 'date')
  1309. {
  1310. $align="center";
  1311. }
  1312. elseif ($type == 'datetime')
  1313. {
  1314. $align="center";
  1315. }
  1316. elseif ($type == 'int')
  1317. {
  1318. $align="right";
  1319. }
  1320. elseif ($type == 'double')
  1321. {
  1322. $align="right";
  1323. }
  1324. elseif ($type == 'boolean')
  1325. {
  1326. $align="center";
  1327. }
  1328. elseif ($type == 'radio')
  1329. {
  1330. $align="center";
  1331. }
  1332. elseif ($type == 'checkbox')
  1333. {
  1334. $align="center";
  1335. }
  1336. return $align;
  1337. }
  1338. /**
  1339. * Return HTML string to print separator extrafield
  1340. *
  1341. * @param string $key Key of attribute
  1342. * @return string
  1343. */
  1344. function showSeparator($key)
  1345. {
  1346. $out = '<tr class="liste_titre"><td colspan="4"><strong>'.$this->attribute_label[$key].'</strong></td></tr>';
  1347. return $out;
  1348. }
  1349. /**
  1350. * Fill array_options property of object by extrafields value (using for data sent by forms)
  1351. *
  1352. * @param array $extralabels $array of extrafields
  1353. * @param object $object Object
  1354. * @param string $onlykey Only following key is filled. When we make update of only one extrafield ($action = 'update_extras'), calling page must must set this to avoid to have other extrafields being reset.
  1355. * @return int 1 if array_options set, 0 if no value, -1 if error (field required missing for example)
  1356. */
  1357. function setOptionalsFromPost($extralabels,&$object,$onlykey='')
  1358. {
  1359. global $_POST, $langs;
  1360. $nofillrequired='';// For error when required field left blank
  1361. $error_field_required = array();
  1362. if (is_array($extralabels))
  1363. {
  1364. // Get extra fields
  1365. foreach ($extralabels as $key => $value)
  1366. {
  1367. if (! empty($onlykey) && $key != $onlykey) continue;
  1368. $key_type = $this->attribute_type[$key];
  1369. if($this->attribute_required[$key] && !GETPOST("options_$key",2))
  1370. {
  1371. $nofillrequired++;
  1372. $error_field_required[] = $value;
  1373. }
  1374. if (in_array($key_type,array('date','datetime')))
  1375. {
  1376. // Clean parameters
  1377. $value_key=dol_mktime($_POST["options_".$key."hour"], $_POST["options_".$key."min"], 0, $_POST["options_".$key."month"], $_POST["options_".$key."day"], $_POST["options_".$key."year"]);
  1378. }
  1379. else if (in_array($key_type,array('checkbox','chkbxlst')))
  1380. {
  1381. $value_arr=GETPOST("options_".$key);
  1382. if (!empty($value_arr)) {
  1383. $value_key=implode($value_arr,',');
  1384. }else {
  1385. $value_key='';
  1386. }
  1387. }
  1388. else if (in_array($key_type,array('price','double')))
  1389. {
  1390. $value_arr=GETPOST("options_".$key);
  1391. $value_key=price2num($value_arr);
  1392. }
  1393. else
  1394. {
  1395. $value_key=GETPOST("options_".$key);
  1396. }
  1397. $object->array_options["options_".$key]=$value_key;
  1398. }
  1399. if($nofillrequired) {
  1400. $langs->load('errors');
  1401. setEventMessages($langs->trans('ErrorFieldsRequired').' : '.implode(', ',$error_field_required), null, 'errors');
  1402. return -1;
  1403. }
  1404. else {
  1405. return 1;
  1406. }
  1407. }
  1408. else {
  1409. return 0;
  1410. }
  1411. }
  1412. /**
  1413. * return array_options array for object by extrafields value (using for data send by forms)
  1414. *
  1415. * @param array $extralabels $array of extrafields
  1416. * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names)
  1417. * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names)
  1418. * @return int 1 if array_options set / 0 if no value
  1419. */
  1420. function getOptionalsFromPost($extralabels,$keyprefix='',$keysuffix='')
  1421. {
  1422. global $_POST;
  1423. $array_options = array();
  1424. if (is_array($extralabels))
  1425. {
  1426. // Get extra fields
  1427. foreach ($extralabels as $key => $value)
  1428. {
  1429. $key_type = $this->attribute_type[$key];
  1430. if (in_array($key_type,array('date','datetime')))
  1431. {
  1432. // Clean parameters
  1433. $value_key=dol_mktime($_POST[$keysuffix."options_".$key.$keyprefix."hour"], $_POST[$keysuffix."options_".$key.$keyprefix."min"], 0, $_POST[$keysuffix."options_".$key.$keyprefix."month"], $_POST[$keysuffix."options_".$key.$keyprefix."day"], $_POST[$keysuffix."options_".$key.$keyprefix."year"]);
  1434. }
  1435. else if (in_array($key_type,array('checkbox')))
  1436. {
  1437. $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
  1438. // Make sure we get an array even if there's only one checkbox
  1439. $value_arr=(array) $value_arr;
  1440. $value_key=implode(',', $value_arr);
  1441. }
  1442. else if (in_array($key_type,array('price','double')))
  1443. {
  1444. $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix);
  1445. $value_key=price2num($value_arr);
  1446. }
  1447. else
  1448. {
  1449. $value_key=GETPOST($keysuffix."options_".$key.$keyprefix);
  1450. }
  1451. $array_options[$keysuffix."options_".$key]=$value_key; // No keyprefix here. keyprefix is used only for read.
  1452. }
  1453. return $array_options;
  1454. }
  1455. else {
  1456. return 0;
  1457. }
  1458. }
  1459. }