modulebuilder.lib.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  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/memory.lib.php
  20. * \brief Set of function for memory/cache 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)) return -1;
  39. if (empty($readdir)) $readdir = $destdir;
  40. if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval']))
  41. {
  42. dol_print_error('', 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.');
  43. return -1;
  44. }
  45. // Check parameters
  46. if (count($addfieldentry) > 0)
  47. {
  48. if (empty($addfieldentry['name']))
  49. {
  50. setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Name")), null, 'errors');
  51. return -2;
  52. }
  53. if (empty($addfieldentry['label']))
  54. {
  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. {
  61. setEventMessages($langs->trans('BadValueForType', $objectname), null, 'errors');
  62. return -2;
  63. }
  64. }
  65. $pathoffiletoeditsrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
  66. $pathoffiletoedittarget = $destdir.'/class/'.strtolower($objectname).'.class.php'.($readdir != $destdir ? '.new' : '');
  67. if (!dol_is_file($pathoffiletoeditsrc))
  68. {
  69. $langs->load("errors");
  70. setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
  71. return -3;
  72. }
  73. //$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
  74. //dol_delete_file($pathoffiletoedittmp, 0, 1, 1);
  75. try {
  76. include_once $pathoffiletoeditsrc;
  77. if (class_exists($objectname)) $object = new $objectname($db);
  78. else return -4;
  79. // Backup old file
  80. dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
  81. // Edit class files
  82. $contentclass = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  83. // Update ->fields (add or remove entries)
  84. if (count($object->fields))
  85. {
  86. if (is_array($addfieldentry) && count($addfieldentry))
  87. {
  88. $name = $addfieldentry['name'];
  89. unset($addfieldentry['name']);
  90. $object->fields[$name] = $addfieldentry;
  91. }
  92. if (!empty($delfieldentry))
  93. {
  94. $name = $delfieldentry;
  95. unset($object->fields[$name]);
  96. }
  97. }
  98. dol_sort_array($object->fields, 'position');
  99. $i = 0;
  100. $texttoinsert = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
  101. $texttoinsert .= "\t".'/**'."\n";
  102. $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";
  103. $texttoinsert .= "\t".' */'."\n";
  104. $texttoinsert .= "\t".'public $fields=array('."\n";
  105. if (count($object->fields))
  106. {
  107. foreach ($object->fields as $key => $val)
  108. {
  109. $i++;
  110. $texttoinsert .= "\t\t'".$key."' => array('type'=>'".$val['type']."', 'label'=>'".$val['label']."',";
  111. $texttoinsert .= " 'enabled'=>'".($val['enabled'] !== '' ? $val['enabled'] : 1)."',";
  112. $texttoinsert .= " 'position'=>".($val['position'] !== '' ? $val['position'] : 50).",";
  113. $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : $val['notnull']).",";
  114. $texttoinsert .= " 'visible'=>".($val['visible'] !== '' ? $val['visible'] : -1).",";
  115. if ($val['noteditable']) $texttoinsert .= " 'noteditable'=>'".$val['noteditable']."',";
  116. if ($val['default'] || $val['default'] === '0') $texttoinsert .= " 'default'=>'".$val['default']."',";
  117. if ($val['index']) $texttoinsert .= " 'index'=>".$val['index'].",";
  118. if ($val['foreignkey']) $texttoinsert .= " 'foreignkey'=>'".$val['foreignkey']."',";
  119. if ($val['searchall']) $texttoinsert .= " 'searchall'=>".$val['searchall'].",";
  120. if ($val['isameasure']) $texttoinsert .= " 'isameasure'=>'".$val['isameasure']."',";
  121. if ($val['css']) $texttoinsert .= " 'css'=>'".$val['css']."',";
  122. if ($val['help']) $texttoinsert .= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\",";
  123. if ($val['showoncombobox']) $texttoinsert .= " 'showoncombobox'=>'".$val['showoncombobox']."',";
  124. if ($val['disabled']) $texttoinsert .= " 'disabled'=>'".$val['disabled']."',";
  125. if ($val['autofocusoncreate']) $texttoinsert .= " 'autofocusoncreate'=>'".$val['autofocusoncreate']."',";
  126. if ($val['arrayofkeyval'])
  127. {
  128. $texttoinsert .= " 'arrayofkeyval'=>array(";
  129. $i = 0;
  130. foreach ($val['arrayofkeyval'] as $key2 => $val2)
  131. {
  132. if ($i) $texttoinsert .= ", ";
  133. $texttoinsert .= "'".$key2."'=>'".$val2."'";
  134. $i++;
  135. }
  136. $texttoinsert .= "),";
  137. }
  138. if ($val['comment']) $texttoinsert .= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\"";
  139. $texttoinsert .= "),\n";
  140. }
  141. }
  142. $texttoinsert .= "\t".');'."\n";
  143. //print ($texttoinsert);exit;
  144. if (count($object->fields))
  145. {
  146. //$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string');
  147. foreach ($object->fields as $key => $val)
  148. {
  149. $i++;
  150. //$typephp=$typetotypephp[$val['type']];
  151. $texttoinsert .= "\t".'public $'.$key.";";
  152. //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
  153. //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
  154. //$texttoinsert.= ($val['notnull']?' NOT NULL':'');
  155. //if ($i < count($object->fields)) $texttoinsert.=";";
  156. $texttoinsert .= "\n";
  157. }
  158. }
  159. $texttoinsert .= "\t".'// END MODULEBUILDER PROPERTIES';
  160. //print($texttoinsert);exit;
  161. $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
  162. dol_mkdir(dirname($pathoffiletoedittarget));
  163. //file_put_contents($pathoffiletoedittmp, $contentclass);
  164. file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
  165. @chmod($pathoffiletoedittarget, octdec($newmask));
  166. return $object;
  167. } catch (Exception $e)
  168. {
  169. print $e->getMessage();
  170. return -5;
  171. }
  172. }
  173. /**
  174. * Save data into a memory area shared by all users, all sessions on server
  175. *
  176. * @param string $destdir Directory
  177. * @param string $module Module name
  178. * @param string $objectname Name of object
  179. * @param string $newmask New mask
  180. * @param string $readdir Directory source (use $destdir when not defined)
  181. * @param Object $object If object was already loaded/known, it is pass to avoid another include and new.
  182. * @param string $moduletype 'external' or 'internal'
  183. * @return int <=0 if KO, >0 if OK
  184. * @see rebuildObjectClass()
  185. */
  186. function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external')
  187. {
  188. global $db, $langs;
  189. $error = 0;
  190. if (empty($objectname)) return -1;
  191. if (empty($readdir)) $readdir = $destdir;
  192. $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
  193. // Edit .sql file
  194. if ($moduletype == 'internal') {
  195. $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
  196. $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
  197. } else {
  198. $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
  199. $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
  200. }
  201. if (!dol_is_file($pathoffiletoeditsrc))
  202. {
  203. $langs->load("errors");
  204. setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
  205. return -1;
  206. }
  207. // Load object from myobject.class.php
  208. try {
  209. if (!is_object($object))
  210. {
  211. include_once $pathoffiletoclasssrc;
  212. if (class_exists($objectname)) $object = new $objectname($db);
  213. else return -1;
  214. }
  215. } catch (Exception $e)
  216. {
  217. print $e->getMessage();
  218. }
  219. // Backup old file
  220. dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
  221. $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  222. $i = 0;
  223. $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n";
  224. if (count($object->fields))
  225. {
  226. foreach ($object->fields as $key => $val)
  227. {
  228. $i++;
  229. $type = $val['type'];
  230. $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php'
  231. if ($type == 'html') $type = 'text'; // html modulebuilder type is a text type in database
  232. elseif ($type == 'price') $type = 'double'; // html modulebuilder type is a text type in database
  233. elseif (in_array($type, array('link', 'sellist', 'duration'))) $type = 'integer';
  234. $texttoinsert .= "\t".$key." ".$type;
  235. if ($key == 'rowid') $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY';
  236. if ($key == 'entity') $texttoinsert .= ' DEFAULT 1';
  237. else {
  238. if ($val['default'] != '')
  239. {
  240. if (preg_match('/^null$/i', $val['default'])) $texttoinsert .= " DEFAULT NULL";
  241. elseif (preg_match('/varchar/', $type)) $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'";
  242. else $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : '');
  243. }
  244. }
  245. $texttoinsert .= (($val['notnull'] > 0) ? ' NOT NULL' : '');
  246. if ($i < count($object->fields)) $texttoinsert .= ", ";
  247. $texttoinsert .= "\n";
  248. }
  249. }
  250. $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS';
  251. $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
  252. $result = file_put_contents($pathoffiletoedittarget, $contentsql);
  253. if ($result)
  254. {
  255. @chmod($pathoffiletoedittarget, octdec($newmask));
  256. } else {
  257. $error++;
  258. }
  259. // Edit .key.sql file
  260. if ($moduletype == 'internal') {
  261. $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql';
  262. $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
  263. } else {
  264. $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql';
  265. $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
  266. }
  267. $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  268. $i = 0;
  269. $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
  270. if (count($object->fields))
  271. {
  272. foreach ($object->fields as $key => $val)
  273. {
  274. $i++;
  275. if (!empty($val['index']))
  276. {
  277. $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
  278. $texttoinsert .= "\n";
  279. }
  280. if (!empty($val['foreignkey']))
  281. {
  282. $tmp = explode('.', $val['foreignkey']);
  283. if (!empty($tmp[0]) && !empty($tmp[1]))
  284. {
  285. $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].");";
  286. $texttoinsert .= "\n";
  287. }
  288. }
  289. }
  290. }
  291. $texttoinsert .= '-- END MODULEBUILDER INDEXES';
  292. $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
  293. dol_mkdir(dirname($pathoffiletoedittarget));
  294. $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
  295. if ($result)
  296. {
  297. @chmod($pathoffiletoedittarget, octdec($newmask));
  298. } else {
  299. $error++;
  300. }
  301. return $error ? -1 : 1;
  302. }