extrafields.class.php 50 KB

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