覆盖文件夹功能和冲突?
我在prestashop基本代码中有一个名为group.php
的类文件。
我想添加一个新字段,并对该group.php
文件进行一些功能更改。
我创建了一个自定义模块并在那里进行了那些更改。当我安装该模块时,我继承的group.php
文件将被发送到Base Override文件夹并保留在那里。
现在我的问题是,
覆盖功能如何运作?
prestashop如何管理冲突?
例如:我有2个模块,它们单独覆盖同一个文件group.php
。
如果我同时安装那两个$data->{'data-val'}->$johndoe;
将存在于基本覆盖文件夹中的模块?
答案 0 :(得分:3)
以下是addOverride()
类的Module
方法:
/**
* Add all methods in a module override to the override class
*
* @param string $classname
* @return bool
*/
public function addOverride($classname)
{
$path = Autoload::getInstance()->getClassPath($classname.'Core');
// Check if there is already an override file, if not, we just need to copy the file
if (!($classpath = Autoload::getInstance()->getClassPath($classname)))
{
$override_src = $this->getLocalPath().'override'.DIRECTORY_SEPARATOR.$path;
$override_dest = _PS_ROOT_DIR_.DIRECTORY_SEPARATOR.'override'.DIRECTORY_SEPARATOR.$path;
if (!is_writable(dirname($override_dest)))
throw new Exception(sprintf(Tools::displayError('directory (%s) not writable'), dirname($override_dest)));
copy($override_src, $override_dest);
// Re-generate the class index
Autoload::getInstance()->generateIndex();
return true;
}
// Check if override file is writable
$override_path = _PS_ROOT_DIR_.'/'.Autoload::getInstance()->getClassPath($classname);
if ((!file_exists($override_path) && !is_writable(dirname($override_path))) || (file_exists($override_path) && !is_writable($override_path)))
throw new Exception(sprintf(Tools::displayError('file (%s) not writable'), $override_path));
// Make a reflection of the override class and the module override class
$override_file = file($override_path);
eval(preg_replace(array('#^\s*<\?php#', '#class\s+'.$classname.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'), array('', 'class '.$classname.'OverrideOriginal'), implode('', $override_file)));
$override_class = new ReflectionClass($classname.'OverrideOriginal');
$module_file = file($this->getLocalPath().'override'.DIRECTORY_SEPARATOR.$path);
eval(preg_replace(array('#^\s*<\?php#', '#class\s+'.$classname.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array('', 'class '.$classname.'Override'), implode('', $module_file)));
$module_class = new ReflectionClass($classname.'Override');
// Check if none of the methods already exists in the override class
foreach ($module_class->getMethods() as $method)
if ($override_class->hasMethod($method->getName()))
throw new Exception(sprintf(Tools::displayError('The method %1$s in the class %2$s is already overriden.'), $method->getName(), $classname));
// Check if none of the properties already exists in the override class
foreach ($module_class->getProperties() as $property)
if ($override_class->hasProperty($property->getName()))
throw new Exception(sprintf(Tools::displayError('The property %1$s in the class %2$s is already defined.'), $property->getName(), $classname));
// Insert the methods from module override in override
$copy_from = array_slice($module_file, $module_class->getStartLine() + 1, $module_class->getEndLine() - $module_class->getStartLine() - 2);
array_splice($override_file, $override_class->getEndLine() - 1, 0, $copy_from);
$code = implode('', $override_file);
file_put_contents($override_path, $code);
return true;
}
正如评论中所述,冲突是在方法和属性规模上处理的。
如果您尝试安装覆盖新方法或新属性的模块,一切都会正常工作,两个文件将合并。
如果您尝试安装覆盖已被其他模块覆盖的方法的模块,则安装将失败。
答案 1 :(得分:2)
当两个模块覆盖同一个文件时,PrestaShop会在覆盖函数的顶部添加注释,以识别哪个模块被哪个模块覆盖。
该评论的示例是:
/*
* module: supercheckout
* date: 2016-12-01 08:03:28
* version: 1.0.1
*/
public function overriddenFunction()
{
parent::mylogout();
-- Custom Code Here --
}
您可以在您的结尾(/override / classes / group.php)中的重写文件中进行检查。
只有在卸载任何模块并且只有一个模块覆盖模块时,才会使用这些注释删除被覆盖的代码,然后删除该文件。