xoops forums

irmtfan

Module Developer
Posted on: 2013/5/9 2:51
irmtfan
irmtfan (Show more)
Module Developer
Posts: 3419
Since: 2003/12/7
#31

Re: SmartClone 1.10 Beta 1 ready for testing

@zyspec:
I dont need to use eval for class and function naming.
I just need to have one reliable and consistent "xoops_module_pre_install_module" function or class and in this function i will change all table names and all class/ function names just like SmartClone do it for any module. (I will use the smartclone class)
In other words "xoops_module_pre_install_module" will be my embedded SmartClone in the module.
Also I think I need to use one more eval for "xoops_module_update_$dirname" to check and do the cloning and let user update the module with ease.

as i said before i dont need to do anything for ""xoops_module_uninstall_$dirname" because Core will drop my tables.

but In my idea with the current clone system the only problem is every clone is one separate module and all class and functions will be cloned. (but in D3 way all clones will use class and functions from the parent)

I still cannot find any reason why Xoops Core developers defined install/update/uninstall functions with dirname?

dirname is not needed because as i said before at one time only one module is Oninstall,Onupdate or Onuninstall.
so one fix function like "xoops_module_pre_install_module" or "xoops_module_update_module" will do the job perfectly.

@Mamba:
I am not good at php but i think we cannot avoid eval with that trick.

Edit: I will update "how to write standard module" tutorial with my new findings:
1- standard module should not have any file name contain the dirname.
a common mistake in all modules is using dirname as a prefix for all templates. It is not needed
so instead of templates/newbb_thread.html we can use templates/module_thread.html or any desired name.

2- standard module should not have any hard-coded dirname in places we can use a variable for it eg:
- block functions:
$modversion['blocks'][$i]['show_func'] = $modversion['dirname'] . "_views_show";
$modversion['blocks'][$i]['edit_func'] = $modversion['dirname'] . "_views_edit";

- table names:
$modversion['tables'][$i] = $modversion['dirname'] . '_log';


- handler table name:
public function __construct(&$db)
    {
        
$this->userlog Userlog::getInstance();
        
parent::__construct($dbUSERLOG_DIRNAME "_log"'UserlogLog'"log_id""log_time");
    }

and any other possible places.

irmtfan

Module Developer
Posted on: 2013/5/11 4:30
irmtfan
irmtfan (Show more)
Module Developer
Posts: 3419
Since: 2003/12/7
#32

Re: SmartClone 1.10 Beta 1 ready for testing

I found a temporary solution to run "pre" functions without using eval.
add this to xoops_version.php
// if we are in modulesadmin to install, update or uninstall
if (!empty($_REQUEST['fct']) && $_REQUEST['fct'] == "modulesadmin" && !empty($_REQUEST['module']) && $_REQUEST['module'] == $modversion['dirname']) {
    
$hModule xoops_gethandler('module');
    switch (
$_REQUEST['op']) {
        case 
"install":
            
$module =& $hModule->create();
            
$module->loadInfoAsVar($modversion['dirname']);
            
// Load module specific install script if any
            
$install_script $modversion['onInstall'];
            if (
$install_script && trim($install_script) != '') {
                include_once 
XOOPS_ROOT_PATH '/modules/' $modversion['dirname'] . '/' trim($install_script);
            }
            
$func "xoops_module_pre_install_module";
            break;
        case 
"update":
            
$module =& $hModule->getByDirname($modversion['dirname']);
            
// Save current version for use in the update function
            
$prev_version $module->getVar('version');
            
// Load module specific update script if any
            
$update_script $modversion['onUpdate'];
            if (
$update_script && trim($update_script) != '') {
                include_once 
XOOPS_ROOT_PATH '/modules/' $modversion['dirname'] . '/' trim($update_script);
            }
            
$func "xoops_module_pre_update_module";
            break;
        case 
"uninstall":
            
$module =& $hModule->getByDirname($modversion['dirname']);
            
// Load module specific update script if any
            
$uninstall_script $modversion['onUninstall'];
            if (
$uninstall_script && trim($uninstall_script) != '') {
                include_once 
XOOPS_ROOT_PATH '/modules/' $modversion['dirname'] . '/' trim($uninstall_script);
            }
            
$func "xoops_module_pre_uninstall_module";
            break;
    }
    if (
function_exists($func)) {
        
$result $func($module);
        if (!
$result) {
            
$module->setErrors('<p>' sprintf_AM_SYSTEM_MODULES_FAILED_EXECUTE"<strong>{$func}</strong>") . '</p>');
        } else {
            
$module->setErrors('<p>' sprintf_AM_SYSTEM_MODULES_FAILED_SUCESS"<strong>{$func}</strong>") . '</p>');
        }
    }
}

It is just temporary because it will execute the pre functions whenever user goes to moduelsadmin link:
eg: modules/system/admin.php?fct=modulesadmin&op=update&module=$dirname

Now the wish to clone modules by simple folder renaming is accomplished. without using eval.
even we can update a clone module using the original module. (which is not possible in current SmartClone)
meanwhile we should send a core request to remove dirname from all Oninstall,Onupdate or Onuninstall functions at least in core 2.6
It seems previous core developers had a bad habit to add dirname to all instance of module functions to avoid conflict. But they didnt think while in some core operations like blocks and search functions core will face conflict between modules, in update and install and uninstall it is not needed and now it makes troubles for cloning.