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. public function fetchChild()
  154. {
  155. if($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
  156. {
  157. foreach($this->childtables as &$childTable)
  158. {
  159. $className = ucfirst($childTable);
  160. $this->{$className}=array();
  161. $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$childTable.' WHERE '.$this->fk_element.' = '.$this->id;
  162. $res = $this->db->query($sql);
  163. if($res)
  164. {
  165. while($obj = $this->db->fetch_object($res))
  166. {
  167. $o=new $className($this->db);
  168. $o->fetch($obj->rowid);
  169. $this->{$className}[] = $o;
  170. }
  171. }
  172. else
  173. {
  174. $this->errors[] = $this->db->lasterror();
  175. }
  176. }
  177. }
  178. }
  179. /**
  180. * Function to update children data
  181. *
  182. * @param User $user user object
  183. */
  184. public function saveChild(User &$user)
  185. {
  186. if($this->withChild && !empty($this->childtables) && !empty($this->fk_element))
  187. {
  188. foreach($this->childtables as &$childTable)
  189. {
  190. $className = ucfirst($childTable);
  191. if(!empty($this->{$className}))
  192. {
  193. foreach($this->{$className} as $i => &$object)
  194. {
  195. $object->{$this->fk_element} = $this->id;
  196. $object->update($user);
  197. if($this->unsetChildDeleted && isset($object->to_delete) && $object->to_delete==true) unset($this->{$className}[$i]);
  198. }
  199. }
  200. }
  201. }
  202. }
  203. /**
  204. * Function to update object or create or delete if needed
  205. *
  206. * @param User $user user object
  207. * @return < 0 if ko, > 0 if ok
  208. */
  209. public function update(User &$user)
  210. {
  211. 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
  212. elseif (isset($this->to_delete) && $this->to_delete==true) return $this->delete($user);
  213. $error = 0;
  214. $this->db->begin();
  215. $res = $this->updateCommon($user);
  216. if ($res)
  217. {
  218. $result = $this->call_trigger(strtoupper($this->element). '_UPDATE', $user);
  219. if ($result < 0) $error++;
  220. else $this->saveChild($user);
  221. }
  222. else
  223. {
  224. $error++;
  225. $this->error = $this->db->lasterror();
  226. $this->errors[] = $this->error;
  227. }
  228. if (empty($error))
  229. {
  230. $this->db->commit();
  231. return $this->id;
  232. }
  233. else
  234. {
  235. $this->db->rollback();
  236. return -1;
  237. }
  238. }
  239. /**
  240. * Function to create object in database
  241. *
  242. * @param User $user user object
  243. * @return < 0 if ko, > 0 if ok
  244. */
  245. public function create(User &$user)
  246. {
  247. if($this->id > 0) return $this->update($user);
  248. $error = 0;
  249. $this->db->begin();
  250. $res = $this->createCommon($user);
  251. if($res)
  252. {
  253. $this->id = $this->db->last_insert_id($this->table_element);
  254. $result = $this->call_trigger(strtoupper($this->element). '_CREATE', $user);
  255. if ($result < 0) $error++;
  256. else $this->saveChild($user);
  257. }
  258. else
  259. {
  260. $error++;
  261. $this->error = $this->db->lasterror();
  262. $this->errors[] = $this->error;
  263. }
  264. if (empty($error))
  265. {
  266. $this->db->commit();
  267. return $this->id;
  268. }
  269. else
  270. {
  271. $this->db->rollback();
  272. return -1;
  273. }
  274. }
  275. /**
  276. * Function to delete object in database
  277. *
  278. * @param User $user user object
  279. * @return < 0 if ko, > 0 if ok
  280. */
  281. public function delete(User &$user)
  282. {
  283. if ($this->id <= 0) return 0;
  284. $error = 0;
  285. $this->db->begin();
  286. $result = $this->call_trigger(strtoupper($this->element). '_DELETE', $user);
  287. if ($result < 0) $error++;
  288. if (!$error)
  289. {
  290. $this->deleteCommon($user);
  291. if($this->withChild && !empty($this->childtables))
  292. {
  293. foreach($this->childtables as &$childTable)
  294. {
  295. $className = ucfirst($childTable);
  296. if (!empty($this->{$className}))
  297. {
  298. foreach($this->{$className} as &$object)
  299. {
  300. $object->delete($user);
  301. }
  302. }
  303. }
  304. }
  305. }
  306. if (empty($error))
  307. {
  308. $this->db->commit();
  309. return 1;
  310. }
  311. else
  312. {
  313. $this->error = $this->db->lasterror();
  314. $this->errors[] = $this->error;
  315. $this->db->rollback();
  316. return -1;
  317. }
  318. }
  319. /**
  320. * Function to get a formatted date
  321. *
  322. * @param string $field Attribute to return
  323. * @param string $format Output date format
  324. * @return string
  325. */
  326. public function getDate($field, $format='')
  327. {
  328. if(empty($this->{$field})) return '';
  329. else
  330. {
  331. return dol_print_date($this->{$field}, $format);
  332. }
  333. }
  334. /**
  335. * Function to set date in field
  336. *
  337. * @param string $field field to set
  338. * @param string $date formatted date to convert
  339. * @return mixed
  340. */
  341. public function setDate($field, $date)
  342. {
  343. if (empty($date))
  344. {
  345. $this->{$field} = 0;
  346. }
  347. else
  348. {
  349. require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  350. $this->{$field} = dol_stringtotime($date);
  351. }
  352. return $this->{$field};
  353. }
  354. /**
  355. * Function to update current object
  356. *
  357. * @param array $Tab Array of values
  358. * @return int
  359. */
  360. public function setValues(&$Tab)
  361. {
  362. foreach ($Tab as $key => $value)
  363. {
  364. if($this->checkFieldType($key, 'date'))
  365. {
  366. $this->setDate($key, $value);
  367. }
  368. else if( $this->checkFieldType($key, 'array'))
  369. {
  370. $this->{$key} = $value;
  371. }
  372. else if( $this->checkFieldType($key, 'float') )
  373. {
  374. $this->{$key} = (double) price2num($value);
  375. }
  376. else if( $this->checkFieldType($key, 'int') ) {
  377. $this->{$key} = (int) price2num($value);
  378. }
  379. else
  380. {
  381. $this->{$key} = $value;
  382. }
  383. }
  384. return 1;
  385. }
  386. }