dolibarr  17.0.4
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 (to add or remove entries defined into $addfieldentry)
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 (!empty($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['alwayseditable'])) {
137  $texttoinsert .= " 'alwayseditable'=>'".$val['alwayseditable']."',";
138  }
139  if (!empty($val['default']) || (isset($val['default']) && $val['default'] === '0')) {
140  $texttoinsert .= " 'default'=>'".$val['default']."',";
141  }
142  if (!empty($val['index'])) {
143  $texttoinsert .= " 'index'=>".$val['index'].",";
144  }
145  if (!empty($val['foreignkey'])) {
146  $texttoinsert .= " 'foreignkey'=>'".$val['foreignkey']."',";
147  }
148  if (!empty($val['searchall'])) {
149  $texttoinsert .= " 'searchall'=>".$val['searchall'].",";
150  }
151  if (!empty($val['isameasure'])) {
152  $texttoinsert .= " 'isameasure'=>'".$val['isameasure']."',";
153  }
154  if (!empty($val['css'])) {
155  $texttoinsert .= " 'css'=>'".$val['css']."',";
156  }
157  if (!empty($val['cssview'])) {
158  $texttoinsert .= " 'cssview'=>'".$val['cssview']."',";
159  }
160  if (!empty($val['csslist'])) {
161  $texttoinsert .= " 'csslist'=>'".$val['csslist']."',";
162  }
163  if (!empty($val['help'])) {
164  $texttoinsert .= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\",";
165  }
166  if (!empty($val['showoncombobox'])) {
167  $texttoinsert .= " 'showoncombobox'=>'".$val['showoncombobox']."',";
168  }
169  if (!empty($val['disabled'])) {
170  $texttoinsert .= " 'disabled'=>'".$val['disabled']."',";
171  }
172  if (!empty($val['autofocusoncreate'])) {
173  $texttoinsert .= " 'autofocusoncreate'=>'".$val['autofocusoncreate']."',";
174  }
175  if (!empty($val['arrayofkeyval'])) {
176  $texttoinsert .= " 'arrayofkeyval'=>array(";
177  $i = 0;
178  foreach ($val['arrayofkeyval'] as $key2 => $val2) {
179  if ($i) {
180  $texttoinsert .= ", ";
181  }
182  $texttoinsert .= "'".$key2."'=>'".$val2."'";
183  $i++;
184  }
185  $texttoinsert .= "),";
186  }
187  if (!empty($val['validate'])) {
188  $texttoinsert .= " 'validate'=>'".$val['validate']."',";
189  }
190  if (!empty($val['comment'])) {
191  $texttoinsert .= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\"";
192  }
193 
194  $texttoinsert .= "),\n";
195  //print $texttoinsert;
196  }
197  }
198 
199  $texttoinsert .= "\t".');'."\n";
200  //print ($texttoinsert);exit;
201 
202  if (count($object->fields)) {
203  //$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string');
204 
205  foreach ($object->fields as $key => $val) {
206  $i++;
207  //$typephp=$typetotypephp[$val['type']];
208  $texttoinsert .= "\t".'public $'.$key.";";
209  //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
210  //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
211  //$texttoinsert.= ($val['notnull']?' NOT NULL':'');
212  //if ($i < count($object->fields)) $texttoinsert.=";";
213  $texttoinsert .= "\n";
214  }
215  }
216 
217  $texttoinsert .= "\t".'// END MODULEBUILDER PROPERTIES';
218 
219  //print($texttoinsert);
220 
221  $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass);
222  //print $contentclass;
223 
224  dol_mkdir(dirname($pathoffiletoedittarget));
225 
226  //file_put_contents($pathoffiletoedittmp, $contentclass);
227  $result = file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass);
228 
229  if ($result) {
230  @chmod($pathoffiletoedittarget, octdec($newmask));
231  } else {
232  $error++;
233  }
234 
235  return $error ? -1 : $object;
236  } catch (Exception $e) {
237  print $e->getMessage();
238  return -5;
239  }
240 }
241 
255 function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external')
256 {
257  global $db, $langs;
258 
259  $error = 0;
260 
261  if (empty($objectname)) {
262  return -1;
263  }
264  if (empty($readdir)) {
265  $readdir = $destdir;
266  }
267 
268  $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php';
269 
270  // Edit .sql file
271  if ($moduletype == 'internal') {
272  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
273  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
274  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
275  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
276  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
277  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
278  $pathoffiletoeditsrc = '/../install/mysql/tables/llx_'.strtolower($module).'.sql';
279  }
280  }
281  }
282  } else {
283  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql';
284  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
285  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'-'.strtolower($module).'.sql';
286  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
287  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'-'.strtolower($module).'.sql';
288  if (! dol_is_file($readdir.$pathoffiletoeditsrc)) {
289  $pathoffiletoeditsrc = '/sql/llx_'.strtolower($module).'.sql';
290  }
291  }
292  }
293  }
294 
295  // Complete path to be full path
296  $pathoffiletoedittarget = $destdir.$pathoffiletoeditsrc.($readdir != $destdir ? '.new' : '');
297  $pathoffiletoeditsrc = $readdir.$pathoffiletoeditsrc;
298 
299  if (!dol_is_file($pathoffiletoeditsrc)) {
300  $langs->load("errors");
301  setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors');
302  return -1;
303  }
304 
305  // Load object from myobject.class.php
306  try {
307  if (!is_object($object)) {
308  include_once $pathoffiletoclasssrc;
309  if (class_exists($objectname)) {
310  $object = new $objectname($db);
311  } else {
312  return -1;
313  }
314  }
315  } catch (Exception $e) {
316  print $e->getMessage();
317  }
318 
319  // Backup old file
320  dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1);
321 
322  $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
323 
324  $i = 0;
325  $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n";
326  if (count($object->fields)) {
327  foreach ($object->fields as $key => $val) {
328  $i++;
329 
330  $type = $val['type'];
331  $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php'
332 
333  if ($type == 'html') {
334  $type = 'text'; // html modulebuilder type is a text type in database
335  } elseif ($type == 'price') {
336  $type = 'double'; // html modulebuilder type is a text type in database
337  } elseif (in_array($type, array('link', 'sellist', 'duration'))) {
338  $type = 'integer';
339  }
340  $texttoinsert .= "\t".$key." ".$type;
341  if ($key == 'rowid') {
342  $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY';
343  } elseif ($type == 'timestamp') {
344  $texttoinsert .= ' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP';
345  }
346  if ($key == 'entity') {
347  $texttoinsert .= ' DEFAULT 1';
348  } else {
349  if (!empty($val['default'])) {
350  if (preg_match('/^null$/i', $val['default'])) {
351  $texttoinsert .= " DEFAULT NULL";
352  } elseif (preg_match('/varchar/', $type)) {
353  $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'";
354  } else {
355  $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : '');
356  }
357  }
358  }
359  $texttoinsert .= ((!empty($val['notnull']) && $val['notnull'] > 0) ? ' NOT NULL' : '');
360  if ($i < count($object->fields)) {
361  $texttoinsert .= ", ";
362  }
363  $texttoinsert .= "\n";
364  }
365  }
366  $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS';
367 
368  $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql);
369 
370  $result = file_put_contents($pathoffiletoedittarget, $contentsql);
371  if ($result) {
372  @chmod($pathoffiletoedittarget, octdec($newmask));
373  } else {
374  $error++;
375  setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
376  }
377 
378  // Edit .key.sql file
379  $pathoffiletoeditsrc = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoeditsrc);
380  $pathoffiletoedittarget = preg_replace('/\.sql$/', '.key.sql', $pathoffiletoedittarget);
381  $pathoffiletoedittarget = preg_replace('/\.sql.new$/', '.key.sql.new', $pathoffiletoedittarget);
382 
383  $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r');
384 
385  $i = 0;
386  $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n";
387  if (count($object->fields)) {
388  foreach ($object->fields as $key => $val) {
389  $i++;
390  if (!empty($val['index'])) {
391  $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");";
392  $texttoinsert .= "\n";
393  }
394  if (!empty($val['foreignkey'])) {
395  $tmp = explode('.', $val['foreignkey']);
396  if (!empty($tmp[0]) && !empty($tmp[1])) {
397  $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].");";
398  $texttoinsert .= "\n";
399  }
400  }
401  }
402  }
403  $texttoinsert .= '-- END MODULEBUILDER INDEXES';
404 
405  $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql);
406 
407  dol_mkdir(dirname($pathoffiletoedittarget));
408 
409  $result2 = file_put_contents($pathoffiletoedittarget, $contentsql);
410  if ($result2) {
411  @chmod($pathoffiletoedittarget, octdec($newmask));
412  } else {
413  $error++;
414  setEventMessages($langs->trans("ErrorFailToCreateFile", $pathoffiletoedittarget), null, 'errors');
415  }
416 
417  return $error ? -1 : 1;
418 }
dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1)
Copy a file to another file.
Definition: files.lib.php:713
dol_is_file($pathoffile)
Return if path is a file.
Definition: files.lib.php:481
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
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...
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir='', $object=null, $moduletype='external')
Save data into a memory area shared by all users, all sessions on server.
rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir='', $addfieldentry=array(), $delfieldentry='')
Regenerate files .class.php.