PageRenderTime 27ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/core/lib/modulebuilder.lib.php

http://github.com/Dolibarr/dolibarr
PHP | 383 lines | 271 code | 47 blank | 65 comment | 77 complexity | 383c52e6145f350be2c2802b7ec4615a MD5 | raw file
Possible License(s): GPL-2.0, AGPL-3.0, LGPL-2.0, CC-BY-SA-4.0, BSD-3-Clause, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-3.0, LGPL-2.1, MIT
  1. <?php
  2. /* Copyright (C) 2009-2010 Laurent Destailleur <eldy@users.sourceforge.net>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. * or see https://www.gnu.org/
  17. */
  18. /**
  19. * \file htdocs/core/lib/modulebuilder.lib.php
  20. * \brief Set of function for modulebuilder management
  21. */
  22. /**
  23. * Regenerate files .class.php
  24. *
  25. * @param string $destdir Directory
  26. * @param string $module Module name
  27. * @param string $objectname Name of object
  28. * @param string $newmask New mask
  29. * @param string $readdir Directory source (use $destdir when not defined)
  30. * @param string $addfieldentry Array of the field entry to add array('key'=>,'type'=>,''label'=>,'visible'=>,'enabled'=>,'position'=>,'notnull'=>','index'=>,'searchall'=>,'comment'=>,'help'=>,'isameasure')
  31. * @param string $delfieldentry Id of field to remove
  32. * @return int|object <=0 if KO, Object if OK
  33. * @see rebuildObjectSql()
  34. */
  35. function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = '', $addfieldentry = array(), $delfieldentry = '')
  36. {
  37. global $db, $langs;
  38. if (empty($objectname)) {
  39. return -1;
  40. }
  41. if (empty($readdir)) {
  42. $readdir = $destdir;
  43. }
  44. if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) {
  45. dol_print_error('', 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.');
  46. return -1;
  47. }
  48. // Check parameters
  49. if (is_array($addfieldentry) && count($addfieldentry) > 0) {
  50. if (empty($addfieldentry['name'])) {
  51. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Name")), null, 'errors');
  52. return -2;
  53. }
  54. if (empty($addfieldentry['label'])) {
  55. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Label")), null, 'errors');
  56. return -2;
  57. }
  58. if (!preg_match('/^(integer|price|sellist|varchar|double|text|html|duration)/', $addfieldentry['type'])
  59. && !preg_match('/^(boolean|real|date|datetime|timestamp)$/', $addfieldentry['type'])) {
  60. setEventMessages($langs->trans('BadValueForType', $objectname), null, 'errors');
  61. return -2;
  62. }
  63. }
  64. $pathoffiletoeditsrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
  65. $pathoffiletoedittarget = $destdir.'/class/'.strtolower($objectname).'.class.php'.($readdir != $destdir ? '.new' : '');
  66. if (!dol_is_file($pathoffiletoeditsrc)) {
  67. $langs->load("errors");
  68. setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
  69. return -3;
  70. }
  71. //$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
  72. //dol_delete_file($pathoffiletoedittmp, 0, 1, 1);
  73. try {
  74. include_once $pathoffiletoeditsrc;
  75. if (class_exists($objectname)) {
  76. $object = new $objectname($db);
  77. } else {
  78. return -4;
  79. }
  80. // Backup old file
  81. dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
  82. // Edit class files
  83. $contentclass = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  84. // Update ->fields (add or remove entries)
  85. if (count($object->fields)) {
  86. if (is_array($addfieldentry) && count($addfieldentry)) {
  87. $name = $addfieldentry['name'];
  88. unset($addfieldentry['name']);
  89. $object->fields[$name] = $addfieldentry;
  90. }
  91. if (!empty($delfieldentry)) {
  92. $name = $delfieldentry;
  93. unset($object->fields[$name]);
  94. }
  95. }
  96. dol_sort_array($object->fields, 'position');
  97. $i = 0;
  98. $texttoinsert = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
  99. $texttoinsert .= "\t".'/**'."\n";
  100. $texttoinsert .= "\t".' * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.'."\n";
  101. $texttoinsert .= "\t".' */'."\n";
  102. $texttoinsert .= "\t".'public $fields=array('."\n";
  103. if (count($object->fields)) {
  104. foreach ($object->fields as $key => $val) {
  105. $i++;
  106. $texttoinsert .= "\t\t'".$key."' => array('type'=>'".$val['type']."',";
  107. $texttoinsert .= " 'label'=>'".$val['label']."',";
  108. $texttoinsert .= " 'enabled'=>'".($val['enabled'] !== '' ? $val['enabled'] : 1)."',";
  109. $texttoinsert .= " 'position'=>".($val['position'] !== '' ? $val['position'] : 50).",";
  110. $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : $val['notnull']).",";
  111. $texttoinsert .= " 'visible'=>".($val['visible'] !== '' ? $val['visible'] : -1).",";
  112. if ($val['noteditable']) {
  113. $texttoinsert .= " 'noteditable'=>'".$val['noteditable']."',";
  114. }
  115. if ($val['default'] || $val['default'] === '0') {
  116. $texttoinsert .= " 'default'=>'".$val['default']."',";
  117. }
  118. if ($val['index']) {
  119. $texttoinsert .= " 'index'=>".$val['index'].",";
  120. }
  121. if ($val['foreignkey']) {
  122. $texttoinsert .= " 'foreignkey'=>'".$val['foreignkey']."',";
  123. }
  124. if ($val['searchall']) {
  125. $texttoinsert .= " 'searchall'=>".$val['searchall'].",";
  126. }
  127. if ($val['isameasure']) {
  128. $texttoinsert .= " 'isameasure'=>'".$val['isameasure']."',";
  129. }
  130. if ($val['css']) {
  131. $texttoinsert .= " 'css'=>'".$val['css']."',";
  132. }
  133. if ($val['cssview']) {
  134. $texttoinsert .= " 'cssview'=>'".$val['cssview']."',";
  135. }
  136. if ($val['csslist']) {
  137. $texttoinsert .= " 'csslist'=>'".$val['csslist']."',";
  138. }
  139. if ($val['help']) {
  140. $texttoinsert .= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\",";
  141. }
  142. if ($val['showoncombobox']) {
  143. $texttoinsert .= " 'showoncombobox'=>'".$val['showoncombobox']."',";
  144. }
  145. if ($val['disabled']) {
  146. $texttoinsert .= " 'disabled'=>'".$val['disabled']."',";
  147. }
  148. if ($val['autofocusoncreate']) {
  149. $texttoinsert .= " 'autofocusoncreate'=>'".$val['autofocusoncreate']."',";
  150. }
  151. if ($val['arrayofkeyval']) {
  152. $texttoinsert .= " 'arrayofkeyval'=>array(";
  153. $i = 0;
  154. foreach ($val['arrayofkeyval'] as $key2 => $val2) {
  155. if ($i) {
  156. $texttoinsert .= ", ";
  157. }
  158. $texttoinsert .= "'".$key2."'=>'".$val2."'";
  159. $i++;
  160. }
  161. $texttoinsert .= "),";
  162. }
  163. if ($val['validate']) {
  164. $texttoinsert .= " 'validate'=>'".$val['validate']."',";
  165. }
  166. if ($val['comment']) {
  167. $texttoinsert .= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\"";
  168. }
  169. $texttoinsert .= "),\n";
  170. }
  171. }
  172. $texttoinsert .= "\t".');'."\n";
  173. //print ($texttoinsert);exit;
  174. if (count($object->fields)) {
  175. //$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string');
  176. foreach ($object->fields as $key => $val) {
  177. $i++;
  178. //$typephp=$typetotypephp[$val['type']];
  179. $texttoinsert .= "\t".'public $'.$key.";";
  180. //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
  181. //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
  182. //$texttoinsert.= ($val['notnull']?' NOT NULL':'');
  183. //if ($i < count($object->fields)) $texttoinsert.=";";
  184. $texttoinsert .= "\n";
  185. }
  186. }
  187. $texttoinsert .= "\t".'// END MODULEBUILDER PROPERTIES';
  188. //print($texttoinsert);exit;
  189. $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
  190. dol_mkdir(dirname($pathoffiletoedittarget));
  191. //file_put_contents($pathoffiletoedittmp, $contentclass);
  192. file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
  193. @chmod($pathoffiletoedittarget, octdec($newmask));
  194. return $object;
  195. } catch (Exception $e) {
  196. print $e->getMessage();
  197. return -5;
  198. }
  199. }
  200. /**
  201. * Save data into a memory area shared by all users, all sessions on server
  202. *
  203. * @param string $destdir Directory
  204. * @param string $module Module name
  205. * @param string $objectname Name of object
  206. * @param string $newmask New mask
  207. * @param string $readdir Directory source (use $destdir when not defined)
  208. * @param Object $object If object was already loaded/known, it is pass to avoid another include and new.
  209. * @param string $moduletype 'external' or 'internal'
  210. * @return int <=0 if KO, >0 if OK
  211. * @see rebuildObjectClass()
  212. */
  213. function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external')
  214. {
  215. global $db, $langs;
  216. $error = 0;
  217. if (empty($objectname)) {
  218. return -1;
  219. }
  220. if (empty($readdir)) {
  221. $readdir = $destdir;
  222. }
  223. $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
  224. // Edit .sql file
  225. if ($moduletype == 'internal') {
  226. $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
  227. $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
  228. } else {
  229. $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
  230. $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
  231. }
  232. if (!dol_is_file($pathoffiletoeditsrc)) {
  233. $langs->load("errors");
  234. setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
  235. return -1;
  236. }
  237. // Load object from myobject.class.php
  238. try {
  239. if (!is_object($object)) {
  240. include_once $pathoffiletoclasssrc;
  241. if (class_exists($objectname)) {
  242. $object = new $objectname($db);
  243. } else {
  244. return -1;
  245. }
  246. }
  247. } catch (Exception $e) {
  248. print $e->getMessage();
  249. }
  250. // Backup old file
  251. dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
  252. $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  253. $i = 0;
  254. $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n";
  255. if (count($object->fields)) {
  256. foreach ($object->fields as $key => $val) {
  257. $i++;
  258. $type = $val['type'];
  259. $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php'
  260. if ($type == 'html') {
  261. $type = 'text'; // html modulebuilder type is a text type in database
  262. } elseif ($type == 'price') {
  263. $type = 'double'; // html modulebuilder type is a text type in database
  264. } elseif (in_array($type, array('link', 'sellist', 'duration'))) {
  265. $type = 'integer';
  266. }
  267. $texttoinsert .= "\t".$key." ".$type;
  268. if ($key == 'rowid') {
  269. $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY';
  270. }
  271. if ($key == 'entity') {
  272. $texttoinsert .= ' DEFAULT 1';
  273. } else {
  274. if ($val['default'] != '') {
  275. if (preg_match('/^null$/i', $val['default'])) {
  276. $texttoinsert .= " DEFAULT NULL";
  277. } elseif (preg_match('/varchar/', $type)) {
  278. $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'";
  279. } else {
  280. $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : '');
  281. }
  282. }
  283. }
  284. $texttoinsert .= (($val['notnull'] > 0) ? ' NOT NULL' : '');
  285. if ($i < count($object->fields)) {
  286. $texttoinsert .= ", ";
  287. }
  288. $texttoinsert .= "\n";
  289. }
  290. }
  291. $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS';
  292. $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
  293. $result = file_put_contents($pathoffiletoedittarget, $contentsql);
  294. if ($result) {
  295. @chmod($pathoffiletoedittarget, octdec($newmask));
  296. } else {
  297. $error++;
  298. }
  299. // Edit .key.sql file
  300. if ($moduletype == 'internal') {
  301. $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql';
  302. $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
  303. } else {
  304. $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql';
  305. $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
  306. }
  307. $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  308. $i = 0;
  309. $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
  310. if (count($object->fields)) {
  311. foreach ($object->fields as $key => $val) {
  312. $i++;
  313. if (!empty($val['index'])) {
  314. $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
  315. $texttoinsert .= "\n";
  316. }
  317. if (!empty($val['foreignkey'])) {
  318. $tmp = explode('.', $val['foreignkey']);
  319. if (!empty($tmp[0]) && !empty($tmp[1])) {
  320. $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD CONSTRAINT llx_".strtolower($module).'_'.strtolower($objectname)."_".$key." FOREIGN KEY (".$key.") REFERENCES llx_".preg_replace('/^llx_/', '', $tmp[0])."(".$tmp[1].");";
  321. $texttoinsert .= "\n";
  322. }
  323. }
  324. }
  325. }
  326. $texttoinsert .= '-- END MODULEBUILDER INDEXES';
  327. $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
  328. dol_mkdir(dirname($pathoffiletoedittarget));
  329. $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
  330. if ($result) {
  331. @chmod($pathoffiletoedittarget, octdec($newmask));
  332. } else {
  333. $error++;
  334. }
  335. return $error ? -1 : 1;
  336. }