coreobject.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. <?php
  2. /* EXPERIMENTAL
  3. *
  4. * Copyright (C) 2016 ATM Consulting <support@atm-consulting.fr>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/core/class/coreobject.class.php
  21. * \ingroup core
  22. * \brief File of class to manage all object. Might be replace or merge into commonobject
  23. */
  24. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  25. class CoreObject extends CommonObject
  26. {
  27. public $withChild = true;
  28. /**
  29. * @var Array $_fields Fields to synchronize with Database
  30. */
  31. protected $fields=array();
  32. /**
  33. * Constructor
  34. *
  35. * @param DoliDB $db Database handler
  36. */
  37. function __construct(DoliDB &$db)
  38. {
  39. $this->db = $db;
  40. }
  41. /**
  42. * Function to init fields
  43. *
  44. * @return bool
  45. */
  46. protected function init()
  47. {
  48. $this->id = 0;
  49. $this->datec = 0;
  50. $this->tms = 0;
  51. if (!empty($this->fields))
  52. {
  53. foreach ($this->fields as $field=>$info)
  54. {
  55. if ($this->isDate($info)) $this->{$field} = time();
  56. elseif ($this->isArray($info)) $this->{$field} = array();
  57. elseif ($this->isInt($info)) $this->{$field} = (int) 0;
  58. elseif ($this->isFloat($info)) $this->{$field} = (double) 0;
  59. else $this->{$field} = '';
  60. }
  61. $this->to_delete=false;
  62. $this->is_clone=false;
  63. return true;
  64. }
  65. else
  66. {
  67. return false;
  68. }
  69. }
  70. /**
  71. * Test type of field
  72. *
  73. * @param string $field name of field
  74. * @param string $type type of field to test
  75. * @return value of field or false
  76. */
  77. private function checkFieldType($field, $type)
  78. {
  79. if (isset($this->fields[$field]) && method_exists($this, 'is_'.$type))
  80. {
  81. return $this->{'is_'.$type}($this->fields[$field]);
  82. }
  83. else
  84. {
  85. return false;
  86. }
  87. }
  88. /**
  89. * Get object and children from database
  90. *
  91. * @param int $id Id of object to load
  92. * @param bool $loadChild used to load children from database
  93. * @return int >0 if OK, <0 if KO, 0 if not found
  94. */
  95. public function fetch($id, $loadChild = true)
  96. {
  97. $res = $this->fetchCommon($id);
  98. if($res>0) {
  99. if ($loadChild) $this->fetchChild();
  100. }
  101. return $res;
  102. }
  103. /**
  104. * Function to instantiate a new child
  105. *
  106. * @param string $tabName Table name of child
  107. * @param int $id If id is given, we try to return his key if exist or load if we try_to_load
  108. * @param string $key Attribute name of the object id
  109. * @param bool $try_to_load Force the fetch if an id is given
  110. * @return int
  111. */
  112. public function addChild($tabName, $id=0, $key='id', $try_to_load = false)
  113. {
  114. if(!empty($id))
  115. {
  116. foreach($this->{$tabName} as $k=>&$object)
  117. {
  118. if($object->{$key} === $id) return $k;
  119. }
  120. }
  121. $k = count($this->{$tabName});
  122. $className = ucfirst($tabName);
  123. $this->{$tabName}[$k] = new $className($this->db);
  124. if($id>0 && $key==='id' && $try_to_load)
  125. {
  126. $this->{$tabName}[$k]->fetch($id);
  127. }
  128. return $k;
  129. }
  130. /**
  131. * Function to set a child as to delete
  132. *
  133. * @param string $tabName Table name of child
  134. * @param int $id Id of child to set as to delete
  135. * @param string $key Attribute name of the object id
  136. * @return bool
  137. */
  138. public function removeChild($tabName, $id, $key='id')
  139. {
  140. foreach ($this->{$tabName} as &$object)
  141. {
  142. if ($object->{$key} == $id)
  143. {
  144. $object->to_delete = true;
  145. return true;
  146. }
  147. }
  148. return false;
  149. }
  150. /**
  151. * Function to fetch children objects
  152. *
  153. * @return void
  154. */
  155. public function fetchChild()
  156. {
  157. if($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
  158. {
  159. foreach($this->childtables as &$childTable)
  160. {
  161. $className = ucfirst($childTable);
  162. $this->{$className}=array();
  163. $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$childTable.' WHERE '.$this->fk_element.' = '.$this->id;
  164. $res = $this->db->query($sql);
  165. if($res)
  166. {
  167. while($obj = $this->db->fetch_object($res))
  168. {
  169. $o=new $className($this->db);
  170. $o->fetch($obj->rowid);
  171. $this->{$className}[] = $o;
  172. }
  173. }
  174. else
  175. {
  176. $this->errors[] = $this->db->lasterror();
  177. }
  178. }
  179. }
  180. }
  181. /**
  182. * Function to update children data
  183. *
  184. * @param User $user user object
  185. * @return void
  186. */
  187. public function saveChild(User &$user)
  188. {
  189. if($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
  190. {
  191. foreach($this->childtables as &$childTable)
  192. {
  193. $className = ucfirst($childTable);
  194. if(!empty($this->{$className}))
  195. {
  196. foreach($this->{$className} as $i => &$object)
  197. {
  198. $object->{$this->fk_element} = $this->id;
  199. $object->update($user);
  200. if($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete==true) unset($this->{$className}[$i]);
  201. }
  202. }
  203. }
  204. }
  205. }
  206. /**
  207. * Function to update object or create or delete if needed
  208. *
  209. * @param User $user user object
  210. * @return < 0 if ko, > 0 if ok
  211. */
  212. public function update(User &$user)
  213. {
  214. if (empty($this->id)) return $this->create($user); // To test, with that, no need to test on high level object, the core decide it, update just needed
  215. elseif (isset($this->to_delete) && $this->to_delete==true) return $this->delete($user);
  216. $error = 0;
  217. $this->db->begin();
  218. $res = $this->updateCommon($user);
  219. if ($res)
  220. {
  221. $result = $this->call_trigger(strtoupper($this->element). '_UPDATE', $user);
  222. if ($result < 0) $error++;
  223. else $this->saveChild($user);
  224. }
  225. else
  226. {
  227. $error++;
  228. $this->error = $this->db->lasterror();
  229. $this->errors[] = $this->error;
  230. }
  231. if (empty($error))
  232. {
  233. $this->db->commit();
  234. return $this->id;
  235. }
  236. else
  237. {
  238. $this->db->rollback();
  239. return -1;
  240. }
  241. }
  242. /**
  243. * Function to create object in database
  244. *
  245. * @param User $user user object
  246. * @return < 0 if ko, > 0 if ok
  247. */
  248. public function create(User &$user)
  249. {
  250. if($this->id > 0) return $this->update($user);
  251. $error = 0;
  252. $this->db->begin();
  253. $res = $this->createCommon($user);
  254. if($res)
  255. {
  256. $this->id = $this->db->last_insert_id($this->table_element);
  257. $result = $this->call_trigger(strtoupper($this->element). '_CREATE', $user);
  258. if ($result < 0) $error++;
  259. else $this->saveChild($user);
  260. }
  261. else
  262. {
  263. $error++;
  264. $this->error = $this->db->lasterror();
  265. $this->errors[] = $this->error;
  266. }
  267. if (empty($error))
  268. {
  269. $this->db->commit();
  270. return $this->id;
  271. }
  272. else
  273. {
  274. $this->db->rollback();
  275. return -1;
  276. }
  277. }
  278. /**
  279. * Function to delete object in database
  280. *
  281. * @param User $user user object
  282. * @return < 0 if ko, > 0 if ok
  283. */
  284. public function delete(User &$user)
  285. {
  286. if ($this->id <= 0) return 0;
  287. $error = 0;
  288. $this->db->begin();
  289. $result = $this->call_trigger(strtoupper($this->element). '_DELETE', $user);
  290. if ($result < 0) $error++;
  291. if (!$error)
  292. {
  293. $this->deleteCommon($user);
  294. if($this->withChild && !empty($this->childtables))
  295. {
  296. foreach($this->childtables as &$childTable)
  297. {
  298. $className = ucfirst($childTable);
  299. if (!empty($this->{$className}))
  300. {
  301. foreach($this->{$className} as &$object)
  302. {
  303. $object->delete($user);
  304. }
  305. }
  306. }
  307. }
  308. }
  309. if (empty($error))
  310. {
  311. $this->db->commit();
  312. return 1;
  313. }
  314. else
  315. {
  316. $this->error = $this->db->lasterror();
  317. $this->errors[] = $this->error;
  318. $this->db->rollback();
  319. return -1;
  320. }
  321. }
  322. /**
  323. * Function to get a formatted date
  324. *
  325. * @param string $field Attribute to return
  326. * @param string $format Output date format
  327. * @return string
  328. */
  329. public function getDate($field, $format='')
  330. {
  331. if(empty($this->{$field})) return '';
  332. else
  333. {
  334. return dol_print_date($this->{$field}, $format);
  335. }
  336. }
  337. /**
  338. * Function to set date in field
  339. *
  340. * @param string $field field to set
  341. * @param string $date formatted date to convert
  342. * @return mixed
  343. */
  344. public function setDate($field, $date)
  345. {
  346. if (empty($date))
  347. {
  348. $this->{$field} = 0;
  349. }
  350. else
  351. {
  352. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  353. $this->{$field} = dol_stringtotime($date);
  354. }
  355. return $this->{$field};
  356. }
  357. /**
  358. * Function to update current object
  359. *
  360. * @param array $Tab Array of values
  361. * @return int
  362. */
  363. public function setValues(&$Tab)
  364. {
  365. foreach ($Tab as $key => $value)
  366. {
  367. if($this->checkFieldType($key, 'date'))
  368. {
  369. $this->setDate($key, $value);
  370. }
  371. else if( $this->checkFieldType($key, 'array'))
  372. {
  373. $this->{$key} = $value;
  374. }
  375. else if( $this->checkFieldType($key, 'float') )
  376. {
  377. $this->{$key} = (double) price2num($value);
  378. }
  379. else if( $this->checkFieldType($key, 'int') ) {
  380. $this->{$key} = (int) price2num($value);
  381. }
  382. else
  383. {
  384. $this->{$key} = $value;
  385. }
  386. }
  387. return 1;
  388. }
  389. }