modulebuilder.lib.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  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 <http://www.gnu.org/licenses/>.
  16. * or see http://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('/^(price|boolean|sellist|integer|date|timestamp|varchar|double|text|html)/', $addfieldentry['type']))
  59. {
  60. setEventMessages($langs->trans('BadFormatForType', $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. {
  68. $langs->load("errors");
  69. setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
  70. return -3;
  71. }
  72. //$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
  73. //dol_delete_file($pathoffiletoedittmp, 0, 1, 1);
  74. try
  75. {
  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.= " 'visible'=>".($val['visible']!=''?$val['visible']:-1).",";
  113. $texttoinsert.= " 'position'=>".($val['position']!=''?$val['position']:50).",";
  114. $texttoinsert.= " 'notnull'=>".($val['notnull']!=''?$val['notnull']:-1).",";
  115. if ($val['default']) $texttoinsert.= " 'default'=>'".$val['default']."',";
  116. if ($val['index']) $texttoinsert.= " 'index'=>".$val['index'].",";
  117. if ($val['searchall']) $texttoinsert.= " 'searchall'=>".$val['searchall'].",";
  118. if ($val['isameasure']) $texttoinsert.= " 'isameasure'=>'".$val['isameasure']."',";
  119. if ($val['foreignkey']) $texttoinsert.= " 'foreignkey'=>'".$val['foreignkey']."',";
  120. if ($val['help']) $texttoinsert.= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\",";
  121. if ($val['comment']) $texttoinsert.= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\",";
  122. if ($val['showoncombobox']) $texttoinsert.= " 'showoncombobox'=>'".$val['showoncombobox']."',";
  123. if ($val['arrayofkeyval'])
  124. {
  125. $texttoinsert.= " 'arrayofkeyval'=>array(";
  126. $i=0;
  127. foreach($val['arrayofkeyval'] as $key2 => $val2)
  128. {
  129. if ($i) $texttoinsert.=", ";
  130. $texttoinsert.="'".$key2."'=>'".$val2."'";
  131. $i++;
  132. }
  133. $texttoinsert.= ")";
  134. }
  135. $texttoinsert.= "),\n";
  136. }
  137. }
  138. $texttoinsert.= "\t".');'."\n";
  139. //print ($texttoinsert);exit;
  140. if (count($object->fields))
  141. {
  142. $typetotypephp=array('integer'=>'integer', 'varchar'=>'string');
  143. foreach($object->fields as $key => $val)
  144. {
  145. $i++;
  146. //$typephp=$typetotypephp[$val['type']];
  147. $texttoinsert.= "\t".'public $'.$key.";";
  148. //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
  149. //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
  150. //$texttoinsert.= ($val['notnull']?' NOT NULL':'');
  151. //if ($i < count($object->fields)) $texttoinsert.=";";
  152. $texttoinsert.= "\n";
  153. }
  154. }
  155. $texttoinsert.= "\t".'// END MODULEBUILDER PROPERTIES';
  156. //print($texttoinsert);exit;
  157. $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
  158. dol_mkdir(dirname($pathoffiletoedittarget));
  159. //file_put_contents($pathoffiletoedittmp, $contentclass);
  160. file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
  161. @chmod($pathoffiletoedittarget, octdec($newmask));
  162. return $object;
  163. }
  164. catch(Exception $e)
  165. {
  166. print $e->getMessage();
  167. return -5;
  168. }
  169. }
  170. /**
  171. * Save data into a memory area shared by all users, all sessions on server
  172. *
  173. * @param string $destdir Directory
  174. * @param string $module Module name
  175. * @param string $objectname Name of object
  176. * @param string $newmask New mask
  177. * @param string $readdir Directory source (use $destdir when not defined)
  178. * @param Object $object If object was already loaded/known, it is pass to avaoid another include and new.
  179. * @return int <=0 if KO, >0 if OK
  180. * @see rebuildObjectClass
  181. */
  182. function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='', $object=null)
  183. {
  184. global $db, $langs;
  185. $error = 0;
  186. if (empty($objectname)) return -1;
  187. if (empty($readdir)) $readdir=$destdir;
  188. $pathoffiletoclasssrc=$readdir.'/class/'.strtolower($objectname).'.class.php';
  189. // Edit .sql file
  190. $pathoffiletoeditsrc=$readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
  191. $pathoffiletoedittarget=$destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : '');
  192. if (! dol_is_file($pathoffiletoeditsrc))
  193. {
  194. $langs->load("errors");
  195. setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
  196. return -1;
  197. }
  198. // Load object from myobject.class.php
  199. try
  200. {
  201. if (! is_object($object))
  202. {
  203. include_once $pathoffiletoclasssrc;
  204. if (class_exists($objectname)) $object=new $objectname($db);
  205. else return -1;
  206. }
  207. }
  208. catch(Exception $e)
  209. {
  210. print $e->getMessage();
  211. }
  212. // Backup old file
  213. dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
  214. $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  215. $i=0;
  216. $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n";
  217. if (count($object->fields))
  218. {
  219. foreach($object->fields as $key => $val)
  220. {
  221. $i++;
  222. $type = $val['type'];
  223. $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php'
  224. if ($type == 'html') $type = 'text'; // html modulebuilder type is a text type in database
  225. else if ($type == 'price') $type = 'double'; // html modulebuilder type is a text type in database
  226. else if ($type == 'link' || $type == 'sellist') $type = 'integer';
  227. $texttoinsert.= "\t".$key." ".$type;
  228. if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
  229. if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
  230. else
  231. {
  232. if ($val['default'] != '')
  233. {
  234. if (preg_match('/^null$/i', $val['default'])) $texttoinsert.= " DEFAULT NULL";
  235. else if (preg_match('/varchar/', $type )) $texttoinsert.= " DEFAULT '".$db->escape($val['default'])."'";
  236. else $texttoinsert.= (($val['default'] > 0)?' DEFAULT '.$val['default']:'');
  237. }
  238. }
  239. $texttoinsert.= (($val['notnull'] > 0)?' NOT NULL':'');
  240. if ($i < count($object->fields)) $texttoinsert.=", ";
  241. $texttoinsert.= "\n";
  242. }
  243. }
  244. $texttoinsert.= "\t".'-- END MODULEBUILDER FIELDS';
  245. $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
  246. $result = file_put_contents($pathoffiletoedittarget, $contentsql);
  247. if ($result)
  248. {
  249. @chmod($pathoffiletoedittarget, octdec($newmask));
  250. }
  251. else
  252. {
  253. $error++;
  254. }
  255. // Edit .key.sql file
  256. $pathoffiletoeditsrc=$destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql';
  257. $pathoffiletoedittarget=$destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : '');
  258. $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
  259. $i=0;
  260. $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
  261. if (count($object->fields))
  262. {
  263. foreach($object->fields as $key => $val)
  264. {
  265. $i++;
  266. if (! empty($val['index']))
  267. {
  268. $texttoinsert.= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
  269. $texttoinsert.= "\n";
  270. }
  271. if (! empty($val['foreignkey']))
  272. {
  273. $tmp=explode('.',$val['foreignkey']);
  274. if (! empty($tmp[0]) && ! empty($tmp[1]))
  275. {
  276. $texttoinsert.= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD CONSTRAINT llx_".strtolower($module).'_'.strtolower($objectname)."_".$key." FOREIGN KEY (".$key.") REFERENCES ".$tmp[0]."(".$tmp[1].");";
  277. $texttoinsert.= "\n";
  278. }
  279. }
  280. }
  281. }
  282. $texttoinsert.= '-- END MODULEBUILDER INDEXES';
  283. $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
  284. dol_mkdir(dirname($pathoffiletoedittarget));
  285. $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
  286. if ($result)
  287. {
  288. @chmod($pathoffiletoedittarget, octdec($newmask));
  289. }
  290. else
  291. {
  292. $error++;
  293. }
  294. return $error ? -1 : 1;
  295. }