dolibarr  16.0.5
modulebuilder.lib.php
Go to the documentation of this file.
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 
38 function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = '', $addfieldentry = array(), $delfieldentry = '')
39 {
40  global $db, $langs;
41 
42  if (empty($objectname)) {
43  return -6;
44  }
45  if (empty($readdir)) {
46  $readdir = $destdir;
47  }
48 
49  if (!empty($addfieldentry['arrayofkeyval']) && !is_array($addfieldentry['arrayofkeyval'])) {
50  dol_print_error('', 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.');
51  return -7;
52  }
53 
54  $error = 0;
55 
56  // Check parameters
57  if (is_array($addfieldentry) && count($addfieldentry) > 0) {
58  if (empty($addfieldentry['name'])) {
59  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Name")), null, 'errors');
60  return -2;
61  }
62  if (empty($addfieldentry['label'])) {
63  setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Label")), null, 'errors');
64  return -2;
65  }
66  if (!preg_match('/^(integer|price|sellist|varchar|double|text|html|duration)/', $addfieldentry['type'])
67  && !preg_match('/^(boolean|smallint|real|date|datetime|timestamp|phone|mail|url|ip|password)$/', $addfieldentry['type'])) {
68  setEventMessages($langs->trans('BadValueForType', $addfieldentry['type']), null, 'errors');
69  return -2;
70  }
71  }
72 
73  $pathoffiletoeditsrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
74  $pathoffiletoedittarget = $destdir.'/class/'.strtolower($objectname).'.class.php'.($readdir != $destdir ? '.new' : '');
75  if (!dol_is_file($pathoffiletoeditsrc)) {
76  $langs->load("errors");
77  setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
78  return -3;
79  }
80 
81  //$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
82  //dol_delete_file($pathoffiletoedittmp, 0, 1, 1);
83 
84  try {
85  include_once $pathoffiletoeditsrc;
86  if (class_exists($objectname)) {
87  $object = new $objectname($db);
88  } else {
89  return -4;
90  }
91 
92  // Backup old file
93  dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
94 
95  // Edit class files
96  $contentclass = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
97 
98  // Update ->fields (add or remove entries)
99  if (count($object->fields)) {
100  if (is_array($addfieldentry) && count($addfieldentry)) {
101  $name = $addfieldentry['name'];
102  unset($addfieldentry['name']);
103 
104  $object->fields[$name] = $addfieldentry;
105  }
106  if (!empty($delfieldentry)) {
107  $name = $delfieldentry;
108  unset($object->fields[$name]);
109  }
110  }
111 
112  dol_sort_array($object->fields, 'position');
113 
114  $i = 0;
115  $texttoinsert = '// BEGIN MODULEBUILDER PROPERTIES'."\n";
116  $texttoinsert .= "\t".''."\n";
119  $texttoinsert .= "\t".'public $fields=array('."\n";
120 
121  if (count($object->fields)) {
122  foreach ($object->fields as $key => $val) {
123  $i++;
124  $texttoinsert .= "\t\t'".$key."' => array('type'=>'".$val['type']."',";
125  $texttoinsert .= " 'label'=>'".$val['label']."',";
126  if ($val['picto']) {
127  $texttoinsert .= " 'picto'=>'".$val['picto']."',";
128  }
129  $texttoinsert .= " 'enabled'=>'".($val['enabled'] !== '' ? $val['enabled'] : 1)."',";
130  $texttoinsert .= " 'position'=>".($val['position'] !== '' ? $val['position'] : 50).",";
131  $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : $val['notnull']).",";
132  $texttoinsert .= " 'visible'=>".($val['visible'] !== '' ? $val['visible'] : -1).",";
133  if (!empty($val['noteditable'])) {
134  $texttoinsert .= " 'noteditable'=>'".$val['noteditable']."',";
135  }
136  if (!empty($val['default']) || (isset($val['default']) && $val['default'] === '0')) {
137  $texttoinsert .= " 'default'=>'".$val['default']."',";
138  }
139  if (!empty($val['index'])) {
140  $texttoinsert .= " 'index'=>".$val['index'].",";
141  }
142  if (!empty($val['foreignkey'])) {
143  $texttoinsert .= " 'foreignkey'=>'".$val['foreignkey']."',";
144  }
145  if (!empty($val['searchall'])) {
146  $texttoinsert .= " 'searchall'=>".$val['searchall'].",";
147  }
148  if (!empty($val['isameasure'])) {
149  $texttoinsert .= " 'isameasure'=>'".$val['isameasure']."',";
150  }
151  if (!empty($val['css'])) {
152  $texttoinsert .= " 'css'=>'".$val['css']."',";
153  }
154  if (!empty($val['cssview'])) {
155  $texttoinsert .= " 'cssview'=>'".$val['cssview']."',";
156  }
157  if (!empty($val['csslist'])) {
158  $texttoinsert .= " 'csslist'=>'".$val['csslist']."',";
159  }
160  if (!empty($val['help'])) {
161  $texttoinsert .= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\",";
162  }
163  if (!empty($val['showoncombobox'])) {
164  $texttoinsert .= " 'showoncombobox'=>'".$val['showoncombobox']."',";
165  }
166  if (!empty($val['disabled'])) {
167  $texttoinsert .= " 'disabled'=>'".$val['disabled']."',";
168  }
169  if (!empty($val['autofocusoncreate'])) {
170  $texttoinsert .= " 'autofocusoncreate'=>'".$val['autofocusoncreate']."',";
171  }
172  if (!empty($val['arrayofkeyval'])) {
173  $texttoinsert .= " 'arrayofkeyval'=>array(";
174  $i = 0;
175  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
176  if ($i) {
177  $texttoinsert .= ", ";
178  }
179  $texttoinsert .= "'".$key2."'=>'".$val2."'";
180  $i++;
181  }
182  $texttoinsert .= "),";
183  }
184  if (!empty($val['validate'])) {
185  $texttoinsert .= " 'validate'=>'".$val['validate']."',";
186  }
187  if (!empty($val['comment'])) {
188  $texttoinsert .= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\"";
189  }
190 
191  $texttoinsert .= "),\n";
192  }
193  }
194 
195  $texttoinsert .= "\t".');'."\n";
196  //print ($texttoinsert);exit;
197 
198  if (count($object->fields)) {
199  //$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string');
200 
201  foreach ($object->fields as $key => $val) {
202  $i++;
203  //$typephp=$typetotypephp[$val['type']];
204  $texttoinsert .= "\t".'public $'.$key.";";
205  //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
206  //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
207  //$texttoinsert.= ($val['notnull']?' NOT NULL':'');
208  //if ($i < count($object->fields)) $texttoinsert.=";";
209  $texttoinsert .= "\n";
210  }
211  }
212 
213  $texttoinsert .= "\t".'// END MODULEBUILDER PROPERTIES';
214 
215  //print($texttoinsert);exit;
216 
217  $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
218 
219  dol_mkdir(dirname($pathoffiletoedittarget));
220 
221  //file_put_contents($pathoffiletoedittmp, $contentclass);
222  $result = file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
223  if ($result) {
224  @chmod($pathoffiletoedittarget, octdec($newmask));
225  } else {
226  $error++;
227  }
228 
229  return $error ? -1 : $object;
230  } catch (Exception $e) {
231  print $e->getMessage();
232  return -5;
233  }
234 }
235 
249 function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external')
250 {
251  global $db, $langs;
252 
253  $error = 0;
254 
255  if (empty($objectname)) {
256  return -1;
257  }
258  if (empty($readdir)) {
259  $readdir = $destdir;
260  }
261 
262  $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
263 
264  // Edit .sql file
265  if ($moduletype == 'internal') {
266  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
267  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
268  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
269  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
270  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
271  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
272  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'.sql';
273  }
274  }
275  }
276  } else {
277  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
278  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
279  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
280  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
281  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
282  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
283  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'.sql';
284  }
285  }
286  }
287  }
288 
289  // Complete path to be full path
290  $pathoffiletoedittarget = $destdir.$pathoffiletoeditsrc.($readdir != $destdir ? '.new' : '');
291  $pathoffiletoeditsrc = $readdir.$pathoffiletoeditsrc;
292 
293  if (!dol_is_file($pathoffiletoeditsrc)) {
294  $langs->load("errors");
295  setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
296  return -1;
297  }
298 
299  // Load object from myobject.class.php
300  try {
301  if (!is_object($object)) {
302  include_once $pathoffiletoclasssrc;
303  if (class_exists($objectname)) {
304  $object = new $objectname($db);
305  } else {
306  return -1;
307  }
308  }
309  } catch (Exception $e) {
310  print $e->getMessage();
311  }
312 
313  // Backup old file
314  dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
315 
316  $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
317 
318  $i = 0;
319  $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n";
320  if (count($object->fields)) {
321  foreach ($object->fields as $key => $val) {
322  $i++;
323 
324  $type = $val['type'];
325  $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php'
326 
327  if ($type == 'html') {
328  $type = 'text'; // html modulebuilder type is a text type in database
329  } elseif ($type == 'price') {
330  $type = 'double'; // html modulebuilder type is a text type in database
331  } elseif (in_array($type, array('link', 'sellist', 'duration'))) {
332  $type = 'integer';
333  }
334  $texttoinsert .= "\t".$key." ".$type;
335  if ($key == 'rowid') {
336  $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY';
337  } elseif ($type == 'timestamp') {
338  $texttoinsert .= ' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
339  }
340  if ($key == 'entity') {
341  $texttoinsert .= ' DEFAULT 1';
342  } else {
343  if (!empty($val['default'])) {
344  if (preg_match('/^null$/i', $val['default'])) {
345  $texttoinsert .= " DEFAULT NULL";
346  } elseif (preg_match('/varchar/', $type)) {
347  $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'";
348  } else {
349  $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : '');
350  }
351  }
352  }
353  $texttoinsert .= (($val['notnull'] > 0) ? ' NOT NULL' : '');
354  if ($i < count($object->fields)) {
355  $texttoinsert .= ", ";
356  }
357  $texttoinsert .= "\n";
358  }
359  }
360  $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS';
361 
362  $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
363 
364  $result = file_put_contents($pathoffiletoedittarget, $contentsql);
365  if ($result) {
366  @chmod($pathoffiletoedittarget, octdec($newmask));
367  } else {
368  $error++;
369  setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
370  }
371 
372  // Edit .key.sql file
373  $pathoffiletoeditsrc = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoeditsrc);
374  $pathoffiletoedittarget = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoedittarget);
375  $pathoffiletoedittarget = preg_replace('/\.sql.new$/', '.key.sql.new', $pathoffiletoedittarget);
376 
377  $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
378 
379  $i = 0;
380  $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
381  if (count($object->fields)) {
382  foreach ($object->fields as $key => $val) {
383  $i++;
384  if (!empty($val['index'])) {
385  $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
386  $texttoinsert .= "\n";
387  }
388  if (!empty($val['foreignkey'])) {
389  $tmp = explode('.', $val['foreignkey']);
390  if (!empty($tmp[0]) && !empty($tmp[1])) {
391  $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].");";
392  $texttoinsert .= "\n";
393  }
394  }
395  }
396  }
397  $texttoinsert .= '-- END MODULEBUILDER INDEXES';
398 
399  $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
400 
401  dol_mkdir(dirname($pathoffiletoedittarget));
402 
403  $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
404  if ($result2) {
405  @chmod($pathoffiletoedittarget, octdec($newmask));
406  } else {
407  $error++;
408  setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
409  }
410 
411  return $error ? -1 : 1;
412 }
dol_osencode
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
Definition: functions.lib.php:8499
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
dol_sort_array
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by second index function, which produces ascending (default) or descending output...
Definition: functions.lib.php:8385
dol_is_file
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:477
Exception
dol_copy
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
Copy a file to another file.
Definition: files.lib.php:703
rebuildObjectSql
rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='', $object=null, $moduletype='external')
Save data into a memory area shared by all users, all sessions on server.
Definition: modulebuilder.lib.php:249
rebuildObjectClass
rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='', $addfieldentry=array(), $delfieldentry='')
Regenerate files .class.php.
Definition: modulebuilder.lib.php:38
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8137
dol_mkdir
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
Definition: functions.lib.php:6603