2017-07-12 01:55:07 +02:00
< ? php
/* Copyright ( C ) 2009 - 2010 Laurent Destailleur < eldy @ users . sourceforge . net >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
2019-09-23 21:55:30 +02:00
* along with this program . If not , see < https :// www . gnu . org / licenses />.
* or see https :// www . gnu . org /
2017-07-12 01:55:07 +02:00
*/
/**
2021-11-07 13:51:31 +01:00
* \file htdocs / core / lib / modulebuilder . lib . php
* \brief Set of function for modulebuilder management
2017-07-12 01:55:07 +02:00
*/
/**
2017-09-05 20:42:34 +02:00
* Regenerate files . class . php
2017-07-12 01:55:07 +02:00
*
* @ param string $destdir Directory
* @ param string $module Module name
* @ param string $objectname Name of object
* @ param string $newmask New mask
2017-08-05 11:35:42 +02:00
* @ param string $readdir Directory source ( use $destdir when not defined )
2022-07-15 15:35:45 +02:00
* @ param string $addfieldentry Array of 1 field entry to add array ( 'key' => , 'type' => , '' label '=>,' visible '=>,' enabled '=>,' position '=>,' notnull '=>' , 'index' => , 'searchall' => , 'comment' => , 'help' => , 'isameasure' )
2017-09-05 20:42:34 +02:00
* @ param string $delfieldentry Id of field to remove
2017-09-23 18:17:34 +02:00
* @ return int | object <= 0 if KO , Object if OK
2019-03-11 01:01:15 +01:00
* @ see rebuildObjectSql ()
2017-07-12 01:55:07 +02:00
*/
2019-01-27 15:20:16 +01:00
function rebuildObjectClass ( $destdir , $module , $objectname , $newmask , $readdir = '' , $addfieldentry = array (), $delfieldentry = '' )
2017-07-12 01:55:07 +02:00
{
2020-04-05 02:44:59 +02:00
global $db , $langs ;
2021-02-23 22:03:23 +01:00
if ( empty ( $objectname )) {
2022-07-15 15:35:45 +02:00
return - 6 ;
2021-02-23 22:03:23 +01:00
}
if ( empty ( $readdir )) {
$readdir = $destdir ;
}
2020-04-05 02:44:59 +02:00
2021-02-23 22:03:23 +01:00
if ( ! empty ( $addfieldentry [ 'arrayofkeyval' ]) && ! is_array ( $addfieldentry [ 'arrayofkeyval' ])) {
2020-04-05 02:44:59 +02:00
dol_print_error ( '' , 'Bad parameter addfieldentry with a property arrayofkeyval defined but that is not an array.' );
2022-07-15 15:35:45 +02:00
return - 7 ;
2020-04-05 02:44:59 +02:00
}
2022-07-15 15:35:45 +02:00
$error = 0 ;
2020-04-05 02:44:59 +02:00
// Check parameters
2021-03-02 15:27:20 +01:00
if ( is_array ( $addfieldentry ) && count ( $addfieldentry ) > 0 ) {
2021-02-23 22:03:23 +01:00
if ( empty ( $addfieldentry [ 'name' ])) {
2020-04-05 02:44:59 +02:00
setEventMessages ( $langs -> trans ( 'ErrorFieldRequired' , $langs -> transnoentitiesnoconv ( " Name " )), null , 'errors' );
return - 2 ;
}
2021-02-23 22:03:23 +01:00
if ( empty ( $addfieldentry [ 'label' ])) {
2020-04-05 02:44:59 +02:00
setEventMessages ( $langs -> trans ( 'ErrorFieldRequired' , $langs -> transnoentitiesnoconv ( " Label " )), null , 'errors' );
return - 2 ;
}
if ( ! preg_match ( '/^(integer|price|sellist|varchar|double|text|html|duration)/' , $addfieldentry [ 'type' ])
2022-07-15 15:35:45 +02:00
&& ! preg_match ( '/^(boolean|smallint|real|date|datetime|timestamp|phone|mail|url|ip|password)$/' , $addfieldentry [ 'type' ])) {
setEventMessages ( $langs -> trans ( 'BadValueForType' , $addfieldentry [ 'type' ]), null , 'errors' );
2020-04-05 02:44:59 +02:00
return - 2 ;
}
}
$pathoffiletoeditsrc = $readdir . '/class/' . strtolower ( $objectname ) . '.class.php' ;
$pathoffiletoedittarget = $destdir . '/class/' . strtolower ( $objectname ) . '.class.php' . ( $readdir != $destdir ? '.new' : '' );
2021-02-23 22:03:23 +01:00
if ( ! dol_is_file ( $pathoffiletoeditsrc )) {
2020-04-05 02:44:59 +02:00
$langs -> load ( " errors " );
setEventMessages ( $langs -> trans ( " ErrorFileNotFound " , $pathoffiletoeditsrc ), null , 'errors' );
return - 3 ;
}
//$pathoffiletoedittmp=$destdir.'/class/'.strtolower($objectname).'.class.php.tmp';
//dol_delete_file($pathoffiletoedittmp, 0, 1, 1);
2020-05-21 01:41:27 +02:00
try {
2020-04-05 02:44:59 +02:00
include_once $pathoffiletoeditsrc ;
2021-02-23 22:03:23 +01:00
if ( class_exists ( $objectname )) {
$object = new $objectname ( $db );
} else {
return - 4 ;
}
2020-04-05 02:44:59 +02:00
// Backup old file
dol_copy ( $pathoffiletoedittarget , $pathoffiletoedittarget . '.back' , $newmask , 1 );
// Edit class files
$contentclass = file_get_contents ( dol_osencode ( $pathoffiletoeditsrc ), 'r' );
2022-09-27 01:05:22 +02:00
// Update ->fields (to add or remove entries defined into $addfieldentry)
2021-02-23 22:03:23 +01:00
if ( count ( $object -> fields )) {
if ( is_array ( $addfieldentry ) && count ( $addfieldentry )) {
2019-11-19 09:30:26 +01:00
$name = $addfieldentry [ 'name' ];
2020-04-05 02:44:59 +02:00
unset ( $addfieldentry [ 'name' ]);
$object -> fields [ $name ] = $addfieldentry ;
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $delfieldentry )) {
2020-04-05 02:44:59 +02:00
$name = $delfieldentry ;
unset ( $object -> fields [ $name ]);
}
}
dol_sort_array ( $object -> fields , 'position' );
$i = 0 ;
$texttoinsert = '// BEGIN MODULEBUILDER PROPERTIES' . " \n " ;
$texttoinsert .= " \t " . '/**' . " \n " ;
$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 " ;
$texttoinsert .= " \t " . ' */' . " \n " ;
$texttoinsert .= " \t " . 'public $fields=array(' . " \n " ;
2021-02-23 22:03:23 +01:00
if ( count ( $object -> fields )) {
foreach ( $object -> fields as $key => $val ) {
2020-04-05 02:44:59 +02:00
$i ++ ;
2021-04-06 18:51:43 +02:00
$texttoinsert .= " \t \t ' " . $key . " ' => array('type'=>' " . $val [ 'type' ] . " ', " ;
$texttoinsert .= " 'label'=>' " . $val [ 'label' ] . " ', " ;
2022-09-01 13:10:25 +02:00
if ( ! empty ( $val [ 'picto' ])) {
2022-05-01 17:58:37 +02:00
$texttoinsert .= " 'picto'=>' " . $val [ 'picto' ] . " ', " ;
}
2020-05-31 23:23:42 +02:00
$texttoinsert .= " 'enabled'=>' " . ( $val [ 'enabled' ] !== '' ? $val [ 'enabled' ] : 1 ) . " ', " ;
2020-04-05 02:44:59 +02:00
$texttoinsert .= " 'position'=> " . ( $val [ 'position' ] !== '' ? $val [ 'position' ] : 50 ) . " , " ;
$texttoinsert .= " 'notnull'=> " . ( empty ( $val [ 'notnull' ]) ? 0 : $val [ 'notnull' ]) . " , " ;
$texttoinsert .= " 'visible'=> " . ( $val [ 'visible' ] !== '' ? $val [ 'visible' ] : - 1 ) . " , " ;
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'noteditable' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'noteditable'=>' " . $val [ 'noteditable' ] . " ', " ;
}
2022-09-27 01:05:22 +02:00
if ( ! empty ( $val [ 'alwayseditable' ])) {
$texttoinsert .= " 'alwayseditable'=>' " . $val [ 'alwayseditable' ] . " ', " ;
}
2022-04-15 14:42:34 +02:00
if ( ! empty ( $val [ 'default' ]) || ( isset ( $val [ 'default' ]) && $val [ 'default' ] === '0' )) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'default'=>' " . $val [ 'default' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'index' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'index'=> " . $val [ 'index' ] . " , " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'foreignkey' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'foreignkey'=>' " . $val [ 'foreignkey' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'searchall' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'searchall'=> " . $val [ 'searchall' ] . " , " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'isameasure' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'isameasure'=>' " . $val [ 'isameasure' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'css' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'css'=>' " . $val [ 'css' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'cssview' ])) {
2021-04-06 18:51:43 +02:00
$texttoinsert .= " 'cssview'=>' " . $val [ 'cssview' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'csslist' ])) {
2021-04-06 18:51:43 +02:00
$texttoinsert .= " 'csslist'=>' " . $val [ 'csslist' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'help' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'help'=> \" " . preg_replace ( '/"/' , '' , $val [ 'help' ]) . " \" , " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'showoncombobox' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'showoncombobox'=>' " . $val [ 'showoncombobox' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'disabled' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'disabled'=>' " . $val [ 'disabled' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'autofocusoncreate' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'autofocusoncreate'=>' " . $val [ 'autofocusoncreate' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'arrayofkeyval' ])) {
2020-04-05 02:44:59 +02:00
$texttoinsert .= " 'arrayofkeyval'=>array( " ;
$i = 0 ;
2021-02-23 22:03:23 +01:00
foreach ( $val [ 'arrayofkeyval' ] as $key2 => $val2 ) {
if ( $i ) {
$texttoinsert .= " , " ;
}
2020-04-05 02:44:59 +02:00
$texttoinsert .= " ' " . $key2 . " '=>' " . $val2 . " ' " ;
$i ++ ;
}
$texttoinsert .= " ), " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'validate' ])) {
2021-07-11 14:05:26 +02:00
$texttoinsert .= " 'validate'=>' " . $val [ 'validate' ] . " ', " ;
}
2022-02-21 15:41:41 +01:00
if ( ! empty ( $val [ 'comment' ])) {
2021-02-23 22:03:23 +01:00
$texttoinsert .= " 'comment'=> \" " . preg_replace ( '/"/' , '' , $val [ 'comment' ]) . " \" " ;
}
2020-04-05 02:44:59 +02:00
$texttoinsert .= " ), \n " ;
2022-09-27 01:05:22 +02:00
//print $texttoinsert;
2020-04-05 02:44:59 +02:00
}
}
$texttoinsert .= " \t " . ');' . " \n " ;
2017-09-23 18:17:34 +02:00
//print ($texttoinsert);exit;
2017-07-12 11:52:07 +02:00
2021-02-23 22:03:23 +01:00
if ( count ( $object -> fields )) {
2020-04-05 02:44:59 +02:00
//$typetotypephp=array('integer'=>'integer', 'duration'=>'integer', 'varchar'=>'string');
2021-02-23 22:03:23 +01:00
foreach ( $object -> fields as $key => $val ) {
2020-04-05 02:44:59 +02:00
$i ++ ;
//$typephp=$typetotypephp[$val['type']];
$texttoinsert .= " \t " . 'public $' . $key . " ; " ;
//if ($key == 'rowid') $texttoinsert.= ' AUTO_INCREMENT PRIMARY KEY';
//if ($key == 'entity') $texttoinsert.= ' DEFAULT 1';
//$texttoinsert.= ($val['notnull']?' NOT NULL':'');
//if ($i < count($object->fields)) $texttoinsert.=";";
$texttoinsert .= " \n " ;
}
}
$texttoinsert .= " \t " . '// END MODULEBUILDER PROPERTIES' ;
2022-09-27 01:05:22 +02:00
//print($texttoinsert);
2020-04-05 02:44:59 +02:00
$contentclass = preg_replace ( '/\/\/ BEGIN MODULEBUILDER PROPERTIES.*END MODULEBUILDER PROPERTIES/ims' , $texttoinsert , $contentclass );
2022-09-27 01:05:22 +02:00
//print $contentclass;
2020-04-05 02:44:59 +02:00
dol_mkdir ( dirname ( $pathoffiletoedittarget ));
//file_put_contents($pathoffiletoedittmp, $contentclass);
2022-07-15 15:35:45 +02:00
$result = file_put_contents ( dol_osencode ( $pathoffiletoedittarget ), $contentclass );
2022-09-27 01:05:22 +02:00
2022-07-15 15:35:45 +02:00
if ( $result ) {
2023-02-17 19:30:50 +01:00
dolChmod ( $pathoffiletoedittarget , $newmask );
2022-07-15 15:35:45 +02:00
} else {
$error ++ ;
}
2020-04-05 02:44:59 +02:00
2022-07-15 15:35:45 +02:00
return $error ? - 1 : $object ;
2021-02-23 22:03:23 +01:00
} catch ( Exception $e ) {
2020-04-05 02:44:59 +02:00
print $e -> getMessage ();
return - 5 ;
}
2017-07-12 11:52:07 +02:00
}
/**
* Save data into a memory area shared by all users , all sessions on server
*
* @ param string $destdir Directory
* @ param string $module Module name
* @ param string $objectname Name of object
* @ param string $newmask New mask
2017-08-05 11:35:42 +02:00
* @ param string $readdir Directory source ( use $destdir when not defined )
2020-08-06 15:55:04 +02:00
* @ param Object $object If object was already loaded / known , it is pass to avoid another include and new .
* @ param string $moduletype 'external' or 'internal'
2017-08-05 11:35:42 +02:00
* @ return int <= 0 if KO , > 0 if OK
2019-03-11 01:01:15 +01:00
* @ see rebuildObjectClass ()
2017-07-12 11:52:07 +02:00
*/
2020-08-06 15:55:04 +02:00
function rebuildObjectSql ( $destdir , $module , $objectname , $newmask , $readdir = '' , $object = null , $moduletype = 'external' )
2017-07-12 11:52:07 +02:00
{
2020-04-05 02:44:59 +02:00
global $db , $langs ;
2017-07-12 11:52:07 +02:00
2020-04-05 02:44:59 +02:00
$error = 0 ;
2017-09-23 18:17:34 +02:00
2021-02-23 22:03:23 +01:00
if ( empty ( $objectname )) {
return - 1 ;
}
if ( empty ( $readdir )) {
$readdir = $destdir ;
}
2017-08-05 11:35:42 +02:00
2020-04-05 02:44:59 +02:00
$pathoffiletoclasssrc = $readdir . '/class/' . strtolower ( $objectname ) . '.class.php' ;
2017-08-05 11:44:27 +02:00
2020-04-05 02:44:59 +02:00
// Edit .sql file
2020-08-06 15:55:04 +02:00
if ( $moduletype == 'internal' ) {
2022-07-15 15:35:45 +02:00
$pathoffiletoeditsrc = '/../install/mysql/tables/llx_' . strtolower ( $module ) . '_' . strtolower ( $objectname ) . '.sql' ;
if ( ! dol_is_file ( $readdir . $pathoffiletoeditsrc )) {
$pathoffiletoeditsrc = '/../install/mysql/tables/llx_' . strtolower ( $module ) . '_' . strtolower ( $objectname ) . '-' . strtolower ( $module ) . '.sql' ;
if ( ! dol_is_file ( $readdir . $pathoffiletoeditsrc )) {
$pathoffiletoeditsrc = '/../install/mysql/tables/llx_' . strtolower ( $module ) . '-' . strtolower ( $module ) . '.sql' ;
if ( ! dol_is_file ( $readdir . $pathoffiletoeditsrc )) {
$pathoffiletoeditsrc = '/../install/mysql/tables/llx_' . strtolower ( $module ) . '.sql' ;
}
}
}
2020-08-06 15:55:04 +02:00
} else {
2022-07-15 15:35:45 +02:00
$pathoffiletoeditsrc = '/sql/llx_' . strtolower ( $module ) . '_' . strtolower ( $objectname ) . '.sql' ;
if ( ! dol_is_file ( $readdir . $pathoffiletoeditsrc )) {
$pathoffiletoeditsrc = '/sql/llx_' . strtolower ( $module ) . '_' . strtolower ( $objectname ) . '-' . strtolower ( $module ) . '.sql' ;
if ( ! dol_is_file ( $readdir . $pathoffiletoeditsrc )) {
$pathoffiletoeditsrc = '/sql/llx_' . strtolower ( $module ) . '-' . strtolower ( $module ) . '.sql' ;
if ( ! dol_is_file ( $readdir . $pathoffiletoeditsrc )) {
$pathoffiletoeditsrc = '/sql/llx_' . strtolower ( $module ) . '.sql' ;
}
}
}
2020-08-06 15:55:04 +02:00
}
2022-07-15 15:35:45 +02:00
// Complete path to be full path
$pathoffiletoedittarget = $destdir . $pathoffiletoeditsrc . ( $readdir != $destdir ? '.new' : '' );
$pathoffiletoeditsrc = $readdir . $pathoffiletoeditsrc ;
2021-02-23 22:03:23 +01:00
if ( ! dol_is_file ( $pathoffiletoeditsrc )) {
2020-04-05 02:44:59 +02:00
$langs -> load ( " errors " );
setEventMessages ( $langs -> trans ( " ErrorFileNotFound " , $pathoffiletoeditsrc ), null , 'errors' );
return - 1 ;
}
// Load object from myobject.class.php
2020-05-21 01:41:27 +02:00
try {
2021-02-23 22:03:23 +01:00
if ( ! is_object ( $object )) {
2020-04-05 02:44:59 +02:00
include_once $pathoffiletoclasssrc ;
2021-02-23 22:03:23 +01:00
if ( class_exists ( $objectname )) {
$object = new $objectname ( $db );
} else {
return - 1 ;
}
2020-04-05 02:44:59 +02:00
}
2021-02-23 22:03:23 +01:00
} catch ( Exception $e ) {
2020-04-05 02:44:59 +02:00
print $e -> getMessage ();
}
// Backup old file
dol_copy ( $pathoffiletoedittarget , $pathoffiletoedittarget . '.back' , $newmask , 1 );
$contentsql = file_get_contents ( dol_osencode ( $pathoffiletoeditsrc ), 'r' );
$i = 0 ;
$texttoinsert = '-- BEGIN MODULEBUILDER FIELDS' . " \n " ;
2021-02-23 22:03:23 +01:00
if ( count ( $object -> fields )) {
foreach ( $object -> fields as $key => $val ) {
2020-04-05 02:44:59 +02:00
$i ++ ;
$type = $val [ 'type' ];
$type = preg_replace ( '/:.*$/' , '' , $type ); // For case type = 'integer:Societe:societe/class/societe.class.php'
2021-02-23 22:03:23 +01:00
if ( $type == 'html' ) {
$type = 'text' ; // html modulebuilder type is a text type in database
} elseif ( $type == 'price' ) {
$type = 'double' ; // html modulebuilder type is a text type in database
} elseif ( in_array ( $type , array ( 'link' , 'sellist' , 'duration' ))) {
$type = 'integer' ;
}
2020-04-05 02:44:59 +02:00
$texttoinsert .= " \t " . $key . " " . $type ;
2021-02-23 22:03:23 +01:00
if ( $key == 'rowid' ) {
$texttoinsert .= ' AUTO_INCREMENT PRIMARY KEY' ;
2022-01-11 00:55:54 +01:00
} elseif ( $type == 'timestamp' ) {
$texttoinsert .= ' DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP' ;
2021-02-23 22:03:23 +01:00
}
if ( $key == 'entity' ) {
$texttoinsert .= ' DEFAULT 1' ;
} else {
2022-02-22 16:35:10 +01:00
if ( ! empty ( $val [ 'default' ])) {
2021-02-23 22:03:23 +01:00
if ( preg_match ( '/^null$/i' , $val [ 'default' ])) {
$texttoinsert .= " DEFAULT NULL " ;
} elseif ( preg_match ( '/varchar/' , $type )) {
$texttoinsert .= " DEFAULT ' " . $db -> escape ( $val [ 'default' ]) . " ' " ;
} else {
$texttoinsert .= (( $val [ 'default' ] > 0 ) ? ' DEFAULT ' . $val [ 'default' ] : '' );
}
2020-04-05 02:44:59 +02:00
}
}
2022-11-27 00:44:05 +01:00
$texttoinsert .= (( ! empty ( $val [ 'notnull' ]) && $val [ 'notnull' ] > 0 ) ? ' NOT NULL' : '' );
2021-02-23 22:03:23 +01:00
if ( $i < count ( $object -> fields )) {
$texttoinsert .= " , " ;
}
2020-04-05 02:44:59 +02:00
$texttoinsert .= " \n " ;
}
}
$texttoinsert .= " \t " . '-- END MODULEBUILDER FIELDS' ;
$contentsql = preg_replace ( '/-- BEGIN MODULEBUILDER FIELDS.*END MODULEBUILDER FIELDS/ims' , $texttoinsert , $contentsql );
$result = file_put_contents ( $pathoffiletoedittarget , $contentsql );
2021-02-23 22:03:23 +01:00
if ( $result ) {
2023-02-17 19:30:50 +01:00
dolChmod ( $pathoffiletoedittarget , $newmask );
2020-05-21 15:05:19 +02:00
} else {
2020-04-05 02:44:59 +02:00
$error ++ ;
2022-07-15 15:35:45 +02:00
setEventMessages ( $langs -> trans ( " ErrorFailToCreateFile " , $pathoffiletoedittarget ), null , 'errors' );
2020-04-05 02:44:59 +02:00
}
// Edit .key.sql file
2022-07-15 15:35:45 +02:00
$pathoffiletoeditsrc = preg_replace ( '/\.sql$/' , '.key.sql' , $pathoffiletoeditsrc );
$pathoffiletoedittarget = preg_replace ( '/\.sql$/' , '.key.sql' , $pathoffiletoedittarget );
$pathoffiletoedittarget = preg_replace ( '/\.sql.new$/' , '.key.sql.new' , $pathoffiletoedittarget );
2020-04-05 02:44:59 +02:00
$contentsql = file_get_contents ( dol_osencode ( $pathoffiletoeditsrc ), 'r' );
$i = 0 ;
$texttoinsert = '-- BEGIN MODULEBUILDER INDEXES' . " \n " ;
2021-02-23 22:03:23 +01:00
if ( count ( $object -> fields )) {
foreach ( $object -> fields as $key => $val ) {
2020-04-05 02:44:59 +02:00
$i ++ ;
2021-02-23 22:03:23 +01:00
if ( ! empty ( $val [ 'index' ])) {
2020-04-05 02:44:59 +02:00
$texttoinsert .= " ALTER TABLE llx_ " . strtolower ( $module ) . '_' . strtolower ( $objectname ) . " ADD INDEX idx_ " . strtolower ( $module ) . '_' . strtolower ( $objectname ) . " _ " . $key . " ( " . $key . " ); " ;
$texttoinsert .= " \n " ;
}
2021-02-23 22:03:23 +01:00
if ( ! empty ( $val [ 'foreignkey' ])) {
2020-04-05 02:44:59 +02:00
$tmp = explode ( '.' , $val [ 'foreignkey' ]);
2021-02-23 22:03:23 +01:00
if ( ! empty ( $tmp [ 0 ]) && ! empty ( $tmp [ 1 ])) {
2020-04-05 02:44:59 +02:00
$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 ] . " ); " ;
$texttoinsert .= " \n " ;
}
}
}
}
$texttoinsert .= '-- END MODULEBUILDER INDEXES' ;
$contentsql = preg_replace ( '/-- BEGIN MODULEBUILDER INDEXES.*END MODULEBUILDER INDEXES/ims' , $texttoinsert , $contentsql );
dol_mkdir ( dirname ( $pathoffiletoedittarget ));
$result2 = file_put_contents ( $pathoffiletoedittarget , $contentsql );
2022-07-15 15:35:45 +02:00
if ( $result2 ) {
2023-02-17 19:30:50 +01:00
dolChmod ( $pathoffiletoedittarget , $newmask );
2020-05-21 15:05:19 +02:00
} else {
2020-04-05 02:44:59 +02:00
$error ++ ;
2022-07-15 15:35:45 +02:00
setEventMessages ( $langs -> trans ( " ErrorFailToCreateFile " , $pathoffiletoedittarget ), null , 'errors' );
2020-04-05 02:44:59 +02:00
}
return $error ? - 1 : 1 ;
2017-07-12 01:55:07 +02:00
}
2023-03-15 10:33:42 +01:00
/**
2023-03-13 12:39:28 +01:00
* Get list of existing objects from directory
2023-03-18 02:39:02 +01:00
*
2023-03-13 12:39:28 +01:00
* @ param string $destdir Directory
2023-03-18 10:20:03 +01:00
* @ return array | int <= 0 if KO , array if OK
2023-03-13 12:39:28 +01:00
*/
2023-03-14 14:48:48 +01:00
function dolGetListOfObjectClasses ( $destdir )
2023-03-13 12:39:28 +01:00
{
$objects = array ();
$listofobject = dol_dir_list ( $destdir . '/class' , 'files' , 0 , '\.class\.php$' );
foreach ( $listofobject as $fileobj ) {
if ( preg_match ( '/^api_/' , $fileobj [ 'name' ])) {
continue ;
}
if ( preg_match ( '/^actions_/' , $fileobj [ 'name' ])) {
continue ;
}
$tmpcontent = file_get_contents ( $fileobj [ 'fullname' ]);
$reg = array ();
if ( preg_match ( '/class\s+([^\s]*)\s+extends\s+CommonObject/ims' , $tmpcontent , $reg )) {
$objectnameloop = $reg [ 1 ];
$objects [ $fileobj [ 'fullname' ]] = $objectnameloop ;
}
}
if ( count ( $objects ) > 0 ) {
return $objects ;
2023-03-18 10:20:03 +01:00
}
return - 1 ;
2023-03-18 02:39:02 +01:00
}
/**
* Delete all permissions
*
2023-03-15 10:33:42 +01:00
* @ param string $file file with path
* @ return void
*/
2023-03-16 10:40:18 +01:00
function deletePerms ( $file )
2023-03-15 10:33:42 +01:00
{
$start = " /* BEGIN MODULEBUILDER PERMISSIONS */ " ;
$end = " /* END MODULEBUILDER PERMISSIONS */ " ;
2023-03-16 10:40:18 +01:00
$i = 1 ;
$array = array ();
$lines = file ( $file );
// Search for start and end lines
foreach ( $lines as $i => $line ) {
if ( strpos ( $line , $start ) !== false ) {
$start_line = $i + 1 ;
// Copy lines until the end on array
while (( $line = $lines [ ++ $i ]) !== false ) {
if ( strpos ( $line , $end ) !== false ) {
$end_line = $i + 1 ;
break ;
}
$array [] = $line ;
}
break ;
}
2023-03-15 10:33:42 +01:00
}
2023-03-16 10:40:18 +01:00
$allContent = implode ( " " , $array );
dolReplaceInFile ( $file , array ( $allContent => '' ));
}
2023-05-02 18:02:36 +02:00
/**
* Compare two value
* @ param int | string $a value 1
* @ param int | string $b value 2
* @ return int less 0 if str1 is less than str2 ; > 0 if str1 is greater than str2 , and 0 if they are equal .
*/
function compareFirstValue ( $a , $b )
{
return strcmp ( $a [ 0 ], $b [ 0 ]);
}
2023-03-16 10:40:18 +01:00
/**
* Rewriting all permissions after any actions
* @ param string $file filename or path
* @ param array $permissions permissions existing in file
2023-05-03 15:33:58 +02:00
* @ param int | null $key key for permission needed
2023-03-16 10:40:18 +01:00
* @ param array | null $right $right to update or add
2023-05-03 15:33:58 +02:00
* @ param string | null $objectname name of object
* @ param string | null $module name of module
* @ param int $action 0 for delete , 1 for add , 2 for update , - 1 when delete object completly , - 2 for generate rights after add
2023-03-16 10:40:18 +01:00
* @ return int 1 if OK , - 1 if KO
*/
2023-05-03 15:33:58 +02:00
function reWriteAllPermissions ( $file , $permissions , $key , $right , $objectname , $module , $action )
2023-03-16 10:40:18 +01:00
{
$error = 0 ;
$rights = array ();
if ( $action == 0 ) {
// delete right from permissions array
array_splice ( $permissions , array_search ( $permissions [ $key ], $permissions ), 1 );
} elseif ( $action == 1 ) {
array_push ( $permissions , $right );
} elseif ( $action == 2 && ! empty ( $right )) {
// update right from permissions array
array_splice ( $permissions , array_search ( $permissions [ $key ], $permissions ), 1 , $right );
2023-05-03 15:33:58 +02:00
} elseif ( $action == - 1 && ! empty ( $objectname )) {
// when delete object
$key = null ;
$right = null ;
foreach ( $permissions as $perms ) {
if ( $perms [ 4 ] === strtolower ( $objectname )) {
array_splice ( $permissions , array_search ( $perms , $permissions ), 1 );
}
}
} elseif ( $action == - 2 && ! empty ( $objectname ) && ! empty ( $module )) {
$key = null ;
$right = null ;
$objectOfRights = array ();
//check if object already declared in rights file
foreach ( $permissions as $right ) {
$objectOfRights [] = $right [ 4 ];
}
if ( in_array ( strtolower ( $objectname ), $objectOfRights )) {
$error ++ ;
} else {
$permsToadd = array ();
$perms = array (
'read' => 'Read objects of ' . ucfirst ( $module ),
'write' => 'Create/Update objects of ' . ucfirst ( $module ),
'delete' => 'Delete objects of ' . ucfirst ( $module )
);
$i = 0 ;
foreach ( $perms as $index => $value ) {
$permsToadd [ $i ][ 0 ] = '' ;
$permsToadd [ $i ][ 1 ] = $value ;
$permsToadd [ $i ][ 4 ] = strtolower ( $objectname );
$permsToadd [ $i ][ 5 ] = $index ;
array_push ( $permissions , $permsToadd [ $i ]);
$i ++ ;
}
}
2023-03-16 10:40:18 +01:00
} else {
2023-03-15 10:33:42 +01:00
$error ++ ;
}
if ( ! $error ) {
2023-03-16 10:40:18 +01:00
// prepare permissions array
$count_perms = count ( $permissions );
for ( $i = 0 ; $i < $count_perms ; $i ++ ) {
$permissions [ $i ][ 0 ] = " \$ this->rights[ \$ r][0] = \$ this->numero . sprintf('%02d', \$ r + 1) " ;
$permissions [ $i ][ 1 ] = " \$ this->rights[ \$ r][1] = ' " . $permissions [ $i ][ 1 ] . " ' " ;
$permissions [ $i ][ 4 ] = " \$ this->rights[ \$ r][4] = ' " . $permissions [ $i ][ 4 ] . " ' " ;
$permissions [ $i ][ 5 ] = " \$ this->rights[ \$ r][5] = ' " . $permissions [ $i ][ 5 ] . " '; \n \t \t " ;
2023-03-15 10:33:42 +01:00
}
2023-05-02 18:02:36 +02:00
// for group permissions by object
$perms_grouped = array ();
foreach ( $permissions as $perms ) {
$object = $perms [ 4 ];
if ( ! isset ( $perms_grouped [ $object ])) {
$perms_grouped [ $object ] = [];
}
$perms_grouped [ $object ][] = $perms ;
}
//$perms_grouped = array_values($perms_grouped);
$permissions = $perms_grouped ;
// parcourir les objets
$o = 0 ;
foreach ( $permissions as & $object ) {
// récupérer la permission de l'objet
$p = 1 ;
foreach ( $object as & $obj ) {
if ( str_contains ( $obj [ 5 ], 'read' )) {
$obj [ 0 ] = " \$ this->rights[ \$ r][0] = \$ this->numero . sprintf('%02d', ( " . $o . " * 10) + 0 + 1) " ;
} elseif ( str_contains ( $obj [ 5 ], 'write' )) {
$obj [ 0 ] = " \$ this->rights[ \$ r][0] = \$ this->numero . sprintf('%02d', ( " . $o . " * 10) + 1 + 1) " ;
} elseif ( str_contains ( $obj [ 5 ], 'delete' )) {
$obj [ 0 ] = " \$ this->rights[ \$ r][0] = \$ this->numero . sprintf('%02d', ( " . $o . " * 10) + 2 + 1) " ;
} else {
$obj [ 0 ] = " \$ this->rights[ \$ r][0] = \$ this->numero . sprintf('%02d', ( " . $o . " * 10) + " . $p . " + 1) " ;
$p ++ ;
}
}
usort ( $object , 'compareFirstValue' );
$o ++ ;
}
2023-03-16 10:40:18 +01:00
//convert to string
foreach ( $permissions as $perms ) {
2023-05-02 18:02:36 +02:00
foreach ( $perms as $per ) {
$rights [] = implode ( " ; \n \t \t " , $per );
$rights [] = " \$ r++; \n \t \t " ;
}
2023-03-15 10:33:42 +01:00
}
2023-03-16 10:40:18 +01:00
$rights_str = implode ( " " , $rights );
// delete all permission from file
deletePerms ( $file );
// rewrite all permission again
dolReplaceInFile ( $file , array ( '/* BEGIN MODULEBUILDER PERMISSIONS */' => '/* BEGIN MODULEBUILDER PERMISSIONS */' . " \n \t \t " . $rights_str ));
return 1 ;
2023-05-02 18:02:36 +02:00
} else {
return - 1 ;
2023-03-15 10:33:42 +01:00
}
}
2023-03-18 02:55:35 +01:00
/**
* Write all properties of the object in AsciiDoc format
* @ param string $file path of the class
* @ param string $objectname name of the objectClass
* @ param string $destfile file where write table of properties
* @ return int 1 if OK , - 1 if KO
*/
function writePropsInAsciiDoc ( $file , $objectname , $destfile )
{
// stock all properties in array
$attributesUnique = array ( 'label' , 'type' , 'arrayofkeyval' , 'notnull' , 'default' , 'index' , 'foreignkey' , 'position' , 'enabled' , 'visible' , 'noteditable' , 'alwayseditable' , 'searchall' , 'isameasure' , 'css' , 'cssview' , 'csslist' , 'help' , 'showoncombobox' , 'validate' , 'comment' , 'picto' );
$start = " public \$ fields=array( " ;
$end = " ); " ;
$i = 1 ;
$keys = array ();
$lines = file ( $file );
// Search for start and end lines
foreach ( $lines as $i => $line ) {
if ( strpos ( $line , $start ) !== false ) {
// Copy lines until the end on array
while (( $line = $lines [ ++ $i ]) !== false ) {
if ( strpos ( $line , $end ) !== false ) {
break ;
}
$keys [] = $line ;
}
break ;
}
}
// write the begin of table with specifics options
$table = " == DATA SPECIFICATIONS \n " ;
$table .= " == Table of fields and their properties for object * $objectname * : \n " ;
$table .= " [options='header',grid=rows,frame=topbot,width=100%,caption=Organisation] \n " ;
$table .= " |=== \n " ;
$table .= " |code " ;
// write all properties in the header of the table
foreach ( $attributesUnique as $attUnique ) {
$table .= " | " . $attUnique ;
}
$table .= " \n " ;
$countKeys = count ( $keys );
for ( $j = 0 ; $j < $countKeys ; $j ++ ) {
$string = $keys [ $j ];
$string = trim ( $string , " ' " );
$string = rtrim ( $string , " , " );
$array = [];
eval ( " \$ array = [ $string ]; " );
// check if is array after cleaning string
if ( ! is_array ( $array )) {
return - 1 ;
}
// name of field
$field = array_keys ( $array );
// all values of each property
$values = array_values ( $array );
// check each field has all properties and add it if missed
if ( count ( $values [ 0 ]) <= 22 ) {
foreach ( $attributesUnique as $cle ) {
if ( ! in_array ( $cle , array_keys ( $values [ 0 ]))) {
$values [ 0 ][ $cle ] = '' ;
}
}
}
//reorganize $values with order attributeUnique
$valuesRestructured = array ();
foreach ( $attributesUnique as $key ) {
if ( array_key_exists ( $key , $values [ 0 ])) {
$valuesRestructured [ $key ] = $values [ 0 ][ $key ];
}
}
// write all values of properties for each field
$table .= " |* " . $field [ 0 ] . " *| " ;
$table .= implode ( " | " , array_values ( $valuesRestructured )) . " \n " ;
}
// end table
$table .= " |=== " ;
2023-03-24 18:42:13 +01:00
$table .= " __ end table for object $objectname " ;
2023-03-18 02:55:35 +01:00
//write in file
$writeInFile = dolReplaceInFile ( $destfile , array ( '== DATA SPECIFICATIONS' => $table ));
if ( $writeInFile < 0 ) {
return - 1 ;
}
return 1 ;
}
2023-03-24 18:21:06 +01:00
2023-03-20 19:43:23 +01:00
/**
* Delete property from documentation if we delete object
* @ param string $file file or path
* @ param string $objectname name of object wants to deleted
* @ return void
*/
function deletePropsFromDoc ( $file , $objectname )
{
$start = " == Table of fields and their properties for object * " . ucfirst ( $objectname ) . " * : " ;
2023-03-24 18:42:13 +01:00
$end = " __ end table for object " . ucfirst ( $objectname );
2023-03-21 12:57:02 +01:00
$str = file_get_contents ( $file );
$search = '/' . preg_quote ( $start , '/' ) . '(.*?)' . preg_quote ( $end , '/' ) . '/s' ;
$new_contents = preg_replace ( $search , '' , $str );
file_put_contents ( $file , $new_contents );
2023-03-20 19:43:23 +01:00
}
2023-04-05 11:08:34 +02:00
2023-03-24 18:21:06 +01:00
/**
* Search a string and return all lines needed from file
* @ param string $file file for searching
* @ param string $start start line if exist
* @ param string $end end line if exist
* @ return string return the content needed
*/
function getFromFile ( $file , $start , $end )
{
$i = 1 ;
$keys = array ();
$lines = file ( $file );
// Search for start and end lines
foreach ( $lines as $i => $line ) {
if ( strpos ( $line , $start ) !== false ) {
// Copy lines until the end on array
while (( $line = $lines [ ++ $i ]) !== false ) {
if ( strpos ( $line , $end ) !== false ) {
break ;
}
$keys [] = $line ;
}
break ;
}
}
$content = implode ( " " , $keys );
return $content ;
}
/**
* Write all permissions of each object in AsciiDoc format
* @ param string $file path of the class
* @ param string $destfile file where write table of permissions
* @ return int 1 if OK , - 1 if KO
*/
function writePermsInAsciiDoc ( $file , $destfile )
{
global $langs ;
//search and get all permssion in stirng
$start = '/* BEGIN MODULEBUILDER PERMISSIONS */' ;
$end = '/* END MODULEBUILDER PERMISSIONS */' ;
$content = getFromFile ( $file , $start , $end );
if ( empty ( $content )) {
return - 1 ;
}
//prepare table
$string = " [options='header',grid=rows,width=60%,caption=Organisation] \n " ;
$string .= " |=== \n " ;
// header for table
$header = array ( $langs -> trans ( 'Objects' ), $langs -> trans ( 'Permission' ));
foreach ( $header as $h ) {
$string .= " | " . $h ;
}
$string .= " \n " ;
//content table
$array = explode ( " ; " , $content );
$indexIgnored = 15 ;
$permissions = array_slice ( $array , $indexIgnored , null , true );
// delete occurrences "$r++" and ID
$permissions = str_replace ( '$r++' , 1 , $permissions );
$permsN = array ();
foreach ( $permissions as $i => $element ) {
if ( $element == 1 ) {
unset ( $permissions [ $i ]);
}
if ( str_contains ( $element , '$this->numero' )) {
unset ( $permissions [ $i ]);
}
if ( str_contains ( $element , '$this->rights[$r][5]' )) {
unset ( $permissions [ $i ]);
}
}
// cleaning the string on each element
foreach ( $permissions as $key => $element ) {
$element = str_replace ( " ' " , '' , $element );
$element = trim ( $element , " ' " );
$permsN [] = substr ( $element , strpos ( $element , " = " ) + 1 );
}
array_pop ( $permsN );
// Group permissions by Object and add it to string
$temp_array = [];
$final_array = [];
$countRights = count ( $permsN );
for ( $i = 0 ; $i < $countRights ; $i ++ ) {
// Add current element to temporary array
$temp_array [] = $permsN [ $i ];
// add them to the final array and empty the temporary array
if ( count ( $temp_array ) == 2 ) {
$final_array [] = $temp_array ;
$temp_array = [];
}
}
// add it to the final array
if ( count ( $temp_array ) > 0 ) {
$final_array [] = $temp_array ;
}
$result = array ();
foreach ( $final_array as $subarray ) {
// found object
$key = $subarray [ 1 ];
// add sub array to object
$result [ $key ][] = $subarray ;
}
foreach ( $result as $i => $pems ) {
$string .= " |* " . $i . " *| " ;
foreach ( $pems as $tab ) {
$string .= $tab [ 0 ] . " , " ;
}
$string .= " \n " ;
}
// end table
$string .= " \n |=== \n " ;
$write = dolReplaceInFile ( $destfile , array ( '__DATA_PERMISSIONS__' => $string ));
if ( $write < 0 ) {
return - 1 ;
}
return 1 ;
}
2023-04-13 17:13:56 +02:00
/**
* Add Object in ModuleApi File
* @ param string $file path of file
* @ param array $objects array of objects in the module
* @ param string $modulename name of module
* @ return int 1 if OK , - 1 if KO
*/
function addObjectsToApiFile ( $file , $objects , $modulename )
{
if ( ! file_exists ( $file )) {
return - 1 ;
}
$content = file ( $file );
$includeClass = " dol_include_once('/mymodule/class/myobject.class.php'); " ;
$props = " public \$ myobject; " ;
$varcomented = " @var MyObject \$ myobject { @type MyObject} " ;
$constructObj = " \$ this->myobject = new MyObject( \$ this->db); " ;
// add properties and declare them in consturctor
foreach ( $content as $lineNumber => & $lineContent ) {
if ( strpos ( $lineContent , $varcomented ) !== false ) {
$lineContent = '' ;
foreach ( $objects as $object ) {
$lineContent .= " \t * @var " . $object . " \$ " . strtolower ( $object ) . " { @type " . $object . " } " . PHP_EOL ;
}
//var_dump($lineContent);exit;
}
if ( strpos ( $lineContent , $props ) !== false ) {
$lineContent = '' ;
foreach ( $objects as $object ) {
$lineContent .= " \t public \$ " . strtolower ( $object ) . " ; " . PHP_EOL ;
}
}
if ( strpos ( $lineContent , $constructObj ) !== false ) {
$lineContent = '' ;
foreach ( $objects as $object ) {
$lineContent .= " \t \t \$ this-> " . strtolower ( $object ) . " = new " . $object . " ( \$ this->db); " . PHP_EOL ;
}
}
if ( strpos ( $lineContent , $includeClass ) !== false ) {
$lineContent = '' ;
foreach ( $objects as $object ) {
$lineContent .= " dol_include_once('/ " . strtolower ( $modulename ) . " /class/ " . strtolower ( $object ) . " .class.php'); " . PHP_EOL ;
}
}
}
$allContent = implode ( " " , $content );
file_put_contents ( $file , $allContent );
//add methods for each object
$allContent = getFromFile ( $file , '/*begin methods CRUD*/' , '/*end methods CRUD*/' );
foreach ( $objects as $object ) {
$contentReplaced = str_replace ([ " myobject " , " MyObject " ], [ strtolower ( $object ), $object ], $allContent );
dolReplaceInFile ( $file , array ( '/*end methods CRUD*/' => '/*CRUD FOR ' . strtoupper ( $object ) . '*/' . " \n " . $contentReplaced . " \n \t " . '/*END CRUD FOR ' . strtoupper ( $object ) . '*/' . " \n \t " . '/*end methods CRUD*/' ));
}
dolReplaceInFile ( $file , array ( $allContent => '' , 'MyModule' => ucfirst ( $modulename )));
return 1 ;
}
/**
* Remove Object variables and methods from API_Module File
* @ param string $file file api module
* @ param string $objectname name of object whant to remove
* @ param string $modulename name of module
* @ return int 1 if OK , - 1 if KO
*/
function removeObjectFromApiFile ( $file , $objectname , $modulename )
{
$begin = '/*CRUD FOR ' . strtoupper ( $objectname ) . '*/' ;
$end = '/*END CRUD FOR ' . strtoupper ( $objectname ) . '*/' ;
$includeClass = " dol_include_once('/ " . strtolower ( $modulename ) . " /class/ " . strtolower ( $objectname ) . " .class.php'); " ;
$varcomentedDel = " \t * @var " . $objectname . " \$ " . strtolower ( $objectname ) . " { @type " . $objectname . " } " ;
$propsDel = " \t public \$ " . strtolower ( $objectname ) . " ; " ;
$constructObjDel = " \t \t \$ this-> " . strtolower ( $objectname ) . " = new " . $objectname . " ( \$ this->db); " ;
if ( ! file_exists ( $file )) {
return - 1 ;
}
$content = file ( $file );
// for delete property and the initialization from the construct
foreach ( $content as $lineNumber => & $lineContent ) {
if ( strpos ( $lineContent , $includeClass ) !== false ) {
$lineContent = '' ;
}
if ( strpos ( $lineContent , $varcomentedDel ) !== false ) {
$lineContent = '' ;
}
if ( strpos ( $lineContent , $propsDel ) !== false ) {
$lineContent = '' ;
}
if ( strpos ( $lineContent , $constructObjDel ) !== false ) {
$lineContent = '' ;
}
}
$allContent = implode ( " " , $content );
file_put_contents ( $file , $allContent );
// for delete methods of object
$allContent = getFromFile ( $file , $begin , $end );
$check = dolReplaceInFile ( $file , array ( $allContent => '' ));
if ( $check ) {
dolReplaceInFile ( $file , array ( $begin => '' , $end => '' ));
}
return 1 ;
}