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/** 20 * \file htdocs/core/lib/memory.lib.php 21 * \brief Set of function for memory/cache management 22 */ 23 24 25/** 26 * Regenerate files .class.php 27 * 28 * @param string $destdir Directory 29 * @param string $module Module name 30 * @param string $objectname Name of object 31 * @param string $newmask New mask 32 * @param string $readdir Directory source (use $destdir when not defined) 33 * @param string $addfieldentry Array of the field entry to add array('key'=>,'type'=>,''label'=>,'visible'=>,'enabled'=>,'position'=>,'notnull'=>','index'=>,'searchall'=>,'comment'=>,'help'=>,'isameasure') 34 * @param string $delfieldentry Id of field to remove 35 * @return int|object <=0 if KO, Object if OK 36 * @see rebuildObjectSql() 37 */ 38function rebuildObjectClass($destdir, $module, $objectname, $newmask, $readdir = '', $addfieldentry = array(), $delfieldentry = '') 39{ 40 global $db, $langs; 41 42 if (empty($objectname)) { 43 return -1; 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 -1; 52 } 53 54 // Check parameters 55 if (is_array($addfieldentry) && count($addfieldentry) > 0) { 56 if (empty($addfieldentry['name'])) { 57 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Name")), null, 'errors'); 58 return -2; 59 } 60 if (empty($addfieldentry['label'])) { 61 setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv("Label")), null, 'errors'); 62 return -2; 63 } 64 if (!preg_match('/^(integer|price|sellist|varchar|double|text|html|duration)/', $addfieldentry['type']) 65 && !preg_match('/^(boolean|real|date|datetime|timestamp)$/', $addfieldentry['type'])) { 66 setEventMessages($langs->trans('BadValueForType', $objectname), null, 'errors'); 67 return -2; 68 } 69 } 70 71 $pathoffiletoeditsrc = $readdir.'/class/'.strtolower($objectname).'.class.php'; 72 $pathoffiletoedittarget = $destdir.'/class/'.strtolower($objectname).'.class.php'.($readdir != $destdir ? '.new' : ''); 73 if (!dol_is_file($pathoffiletoeditsrc)) { 74 $langs->load("errors"); 75 setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors'); 76 return -3; 77 } 78 79 //$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp'; 80 //dol_delete_file($pathoffiletoedittmp, 0, 1, 1); 81 82 try { 83 include_once $pathoffiletoeditsrc; 84 if (class_exists($objectname)) { 85 $object = new $objectname($db); 86 } else { 87 return -4; 88 } 89 90 // Backup old file 91 dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1); 92 93 // Edit class files 94 $contentclass = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r'); 95 96 // Update ->fields (add or remove entries) 97 if (count($object->fields)) { 98 if (is_array($addfieldentry) && count($addfieldentry)) { 99 $name = $addfieldentry['name']; 100 unset($addfieldentry['name']); 101 102 $object->fields[$name] = $addfieldentry; 103 } 104 if (!empty($delfieldentry)) { 105 $name = $delfieldentry; 106 unset($object->fields[$name]); 107 } 108 } 109 110 dol_sort_array($object->fields, 'position'); 111 112 $i = 0; 113 $texttoinsert = '// BEGIN MODULEBUILDER PROPERTIES'."\n"; 114 $texttoinsert .= "\t".'/**'."\n"; 115 $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"; 116 $texttoinsert .= "\t".' */'."\n"; 117 $texttoinsert .= "\t".'public $fields=array('."\n"; 118 119 if (count($object->fields)) { 120 foreach ($object->fields as $key => $val) { 121 $i++; 122 $texttoinsert .= "\t\t'".$key."' => array('type'=>'".$val['type']."',"; 123 $texttoinsert .= " 'label'=>'".$val['label']."',"; 124 $texttoinsert .= " 'enabled'=>'".($val['enabled'] !== '' ? $val['enabled'] : 1)."',"; 125 $texttoinsert .= " 'position'=>".($val['position'] !== '' ? $val['position'] : 50).","; 126 $texttoinsert .= " 'notnull'=>".(empty($val['notnull']) ? 0 : $val['notnull']).","; 127 $texttoinsert .= " 'visible'=>".($val['visible'] !== '' ? $val['visible'] : -1).","; 128 if ($val['noteditable']) { 129 $texttoinsert .= " 'noteditable'=>'".$val['noteditable']."',"; 130 } 131 if ($val['default'] || $val['default'] === '0') { 132 $texttoinsert .= " 'default'=>'".$val['default']."',"; 133 } 134 if ($val['index']) { 135 $texttoinsert .= " 'index'=>".$val['index'].","; 136 } 137 if ($val['foreignkey']) { 138 $texttoinsert .= " 'foreignkey'=>'".$val['foreignkey']."',"; 139 } 140 if ($val['searchall']) { 141 $texttoinsert .= " 'searchall'=>".$val['searchall'].","; 142 } 143 if ($val['isameasure']) { 144 $texttoinsert .= " 'isameasure'=>'".$val['isameasure']."',"; 145 } 146 if ($val['css']) { 147 $texttoinsert .= " 'css'=>'".$val['css']."',"; 148 } 149 if ($val['cssview']) { 150 $texttoinsert .= " 'cssview'=>'".$val['cssview']."',"; 151 } 152 if ($val['csslist']) { 153 $texttoinsert .= " 'csslist'=>'".$val['csslist']."',"; 154 } 155 if ($val['help']) { 156 $texttoinsert .= " 'help'=>\"".preg_replace('/"/', '', $val['help'])."\","; 157 } 158 if ($val['showoncombobox']) { 159 $texttoinsert .= " 'showoncombobox'=>'".$val['showoncombobox']."',"; 160 } 161 if ($val['disabled']) { 162 $texttoinsert .= " 'disabled'=>'".$val['disabled']."',"; 163 } 164 if ($val['autofocusoncreate']) { 165 $texttoinsert .= " 'autofocusoncreate'=>'".$val['autofocusoncreate']."',"; 166 } 167 if ($val['arrayofkeyval']) { 168 $texttoinsert .= " 'arrayofkeyval'=>array("; 169 $i = 0; 170 foreach ($val['arrayofkeyval'] as $key2 => $val2) { 171 if ($i) { 172 $texttoinsert .= ", "; 173 } 174 $texttoinsert .= "'".$key2."'=>'".$val2."'"; 175 $i++; 176 } 177 $texttoinsert .= "),"; 178 } 179 if ($val['comment']) { 180 $texttoinsert .= " 'comment'=>\"".preg_replace('/"/', '', $val['comment'])."\""; 181 } 182 183 $texttoinsert .= "),\n"; 184 } 185 } 186 187 $texttoinsert .= "\t".');'."\n"; 188 //print ($texttoinsert);exit; 189 190 if (count($object->fields)) { 191 //$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string'); 192 193 foreach ($object->fields as $key => $val) { 194 $i++; 195 //$typephp=$typetotypephp[$val['type']]; 196 $texttoinsert .= "\t".'public $'.$key.";"; 197 //if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY'; 198 //if ($key == 'entity') $texttoinsert.= ' DEFAULT 1'; 199 //$texttoinsert.= ($val['notnull']?' NOT NULL':''); 200 //if ($i < count($object->fields)) $texttoinsert.=";"; 201 $texttoinsert .= "\n"; 202 } 203 } 204 205 $texttoinsert .= "\t".'// END MODULEBUILDER PROPERTIES'; 206 207 //print($texttoinsert);exit; 208 209 $contentclass = preg_replace('/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims', $texttoinsert, $contentclass); 210 211 dol_mkdir(dirname($pathoffiletoedittarget)); 212 213 //file_put_contents($pathoffiletoedittmp, $contentclass); 214 file_put_contents(dol_osencode($pathoffiletoedittarget), $contentclass); 215 @chmod($pathoffiletoedittarget, octdec($newmask)); 216 217 return $object; 218 } catch (Exception $e) { 219 print $e->getMessage(); 220 return -5; 221 } 222} 223 224/** 225 * Save data into a memory area shared by all users, all sessions on server 226 * 227 * @param string $destdir Directory 228 * @param string $module Module name 229 * @param string $objectname Name of object 230 * @param string $newmask New mask 231 * @param string $readdir Directory source (use $destdir when not defined) 232 * @param Object $object If object was already loaded/known, it is pass to avoid another include and new. 233 * @param string $moduletype 'external' or 'internal' 234 * @return int <=0 if KO, >0 if OK 235 * @see rebuildObjectClass() 236 */ 237function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = '', $object = null, $moduletype = 'external') 238{ 239 global $db, $langs; 240 241 $error = 0; 242 243 if (empty($objectname)) { 244 return -1; 245 } 246 if (empty($readdir)) { 247 $readdir = $destdir; 248 } 249 250 $pathoffiletoclasssrc = $readdir.'/class/'.strtolower($objectname).'.class.php'; 251 252 // Edit .sql file 253 if ($moduletype == 'internal') { 254 $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; 255 $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); 256 } else { 257 $pathoffiletoeditsrc = $readdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'; 258 $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.sql'.($readdir != $destdir ? '.new' : ''); 259 } 260 261 if (!dol_is_file($pathoffiletoeditsrc)) { 262 $langs->load("errors"); 263 setEventMessages($langs->trans("ErrorFileNotFound", $pathoffiletoeditsrc), null, 'errors'); 264 return -1; 265 } 266 267 // Load object from myobject.class.php 268 try { 269 if (!is_object($object)) { 270 include_once $pathoffiletoclasssrc; 271 if (class_exists($objectname)) { 272 $object = new $objectname($db); 273 } else { 274 return -1; 275 } 276 } 277 } catch (Exception $e) { 278 print $e->getMessage(); 279 } 280 281 // Backup old file 282 dol_copy($pathoffiletoedittarget, $pathoffiletoedittarget.'.back', $newmask, 1); 283 284 $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r'); 285 286 $i = 0; 287 $texttoinsert = '-- BEGIN MODULEBUILDER FIELDS'."\n"; 288 if (count($object->fields)) { 289 foreach ($object->fields as $key => $val) { 290 $i++; 291 292 $type = $val['type']; 293 $type = preg_replace('/:.*$/', '', $type); // For case type = 'integer:Societe:societe/class/societe.class.php' 294 295 if ($type == 'html') { 296 $type = 'text'; // html modulebuilder type is a text type in database 297 } elseif ($type == 'price') { 298 $type = 'double'; // html modulebuilder type is a text type in database 299 } elseif (in_array($type, array('link', 'sellist', 'duration'))) { 300 $type = 'integer'; 301 } 302 $texttoinsert .= "\t".$key." ".$type; 303 if ($key == 'rowid') { 304 $texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY'; 305 } 306 if ($key == 'entity') { 307 $texttoinsert .= ' DEFAULT 1'; 308 } else { 309 if ($val['default'] != '') { 310 if (preg_match('/^null$/i', $val['default'])) { 311 $texttoinsert .= " DEFAULT NULL"; 312 } elseif (preg_match('/varchar/', $type)) { 313 $texttoinsert .= " DEFAULT '".$db->escape($val['default'])."'"; 314 } else { 315 $texttoinsert .= (($val['default'] > 0) ? ' DEFAULT '.$val['default'] : ''); 316 } 317 } 318 } 319 $texttoinsert .= (($val['notnull'] > 0) ? ' NOT NULL' : ''); 320 if ($i < count($object->fields)) { 321 $texttoinsert .= ", "; 322 } 323 $texttoinsert .= "\n"; 324 } 325 } 326 $texttoinsert .= "\t".'-- END MODULEBUILDER FIELDS'; 327 328 $contentsql = preg_replace('/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims', $texttoinsert, $contentsql); 329 330 $result = file_put_contents($pathoffiletoedittarget, $contentsql); 331 if ($result) { 332 @chmod($pathoffiletoedittarget, octdec($newmask)); 333 } else { 334 $error++; 335 } 336 337 // Edit .key.sql file 338 if ($moduletype == 'internal') { 339 $pathoffiletoeditsrc = $readdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; 340 $pathoffiletoedittarget = $destdir.'/../install/mysql/tables/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); 341 } else { 342 $pathoffiletoeditsrc = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'; 343 $pathoffiletoedittarget = $destdir.'/sql/llx_'.strtolower($module).'_'.strtolower($objectname).'.key.sql'.($readdir != $destdir ? '.new' : ''); 344 } 345 346 $contentsql = file_get_contents(dol_osencode($pathoffiletoeditsrc), 'r'); 347 348 $i = 0; 349 $texttoinsert = '-- BEGIN MODULEBUILDER INDEXES'."\n"; 350 if (count($object->fields)) { 351 foreach ($object->fields as $key => $val) { 352 $i++; 353 if (!empty($val['index'])) { 354 $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");"; 355 $texttoinsert .= "\n"; 356 } 357 if (!empty($val['foreignkey'])) { 358 $tmp = explode('.', $val['foreignkey']); 359 if (!empty($tmp[0]) && !empty($tmp[1])) { 360 $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].");"; 361 $texttoinsert .= "\n"; 362 } 363 } 364 } 365 } 366 $texttoinsert .= '-- END MODULEBUILDER INDEXES'; 367 368 $contentsql = preg_replace('/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims', $texttoinsert, $contentsql); 369 370 dol_mkdir(dirname($pathoffiletoedittarget)); 371 372 $result2 = file_put_contents($pathoffiletoedittarget, $contentsql); 373 if ($result) { 374 @chmod($pathoffiletoedittarget, octdec($newmask)); 375 } else { 376 $error++; 377 } 378 379 return $error ? -1 : 1; 380} 381