This repository has been archived by the owner on Apr 17, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathModuleOverride.php
165 lines (146 loc) · 4.9 KB
/
ModuleOverride.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<?php
/**
* ModuleOverride
*
* @author Steven <[email protected]>
* @version 0.1a
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
*/
class ModuleOverride
{
/**
* The current module name who loaded
* @var string
*/
protected $module_name;
/**
* Path of module core (in modules/ dir)
* @var string
*/
protected $module_core_path;
/**
* Filemtime of all overrided module
* @var array
*/
protected $overrided_module;
/**
* Constructor
* Init the constant and property
* @param string $moduleName
*/
protected function __construct($moduleName)
{
$this->module_name = $moduleName;
if(!defined('_PS_THEME_CACHE_DIR_'))
define('_PS_THEME_CACHE_DIR_', _PS_THEME_DIR_.'cache'.DS.'modules'.DS);
if(!is_dir(_PS_THEME_CACHE_DIR_))
mkdir(_PS_THEME_CACHE_DIR_, 0705);
$this->module_core_path = _PS_THEME_CACHE_DIR_.$this->module_name.'.core.php';
if(file_exists(_PS_THEME_CACHE_DIR_.'module_index.php'))
$this->overrided_module = include _PS_THEME_CACHE_DIR_.'module_index.php';
if(!is_array($this->overrided_module))
$this->overrided_module = array();
}
/**
* Load the right classes
* @param string $moduleName
* @static
*/
public static function load($moduleName)
{
$self = new self($moduleName);
$self->_load();
}
/**
* Load all classes for this module
*/
protected function _load()
{
// If not override, then we load basic file
if(!file_exists(_PS_THEME_DIR_.'modules/'.$this->module_name.'/'.$this->module_name.'.php'))
{
if(file_exists(_PS_MODULE_DIR_.$this->module_name.'/'.$this->module_name.'.php'))
{
include_once _PS_MODULE_DIR_.$this->module_name.'/'.$this->module_name.'.php';
}
}
else
{
// else we load the parent class
$this->loadOverridedModule();
// and the child class
require_once _PS_THEME_DIR_.'modules/'.$this->module_name.'/'.$this->module_name.'.php';
}
}
/**
* Load and generate the parent classe
*/
protected function loadOverridedModule()
{
if(!file_exists($this->module_core_path) || $this->hasChanged())
$this->generateCodeModuleFile();
require_once $this->module_core_path;
}
/**
* Generate the parent class (with change name)
* and update the filemtime file
*/
protected function generateCodeModuleFile()
{
// Rewrite the name class
$moduleCore = preg_replace('/class\s+([a-zA-Z0-9_-]+)/', 'class $1Module', file_get_contents(_PS_MODULE_DIR_.$this->module_name.'/'.$this->module_name.'.php'));
// Rewrite the dirname rules
$moduleCore = preg_replace('/dirname\(__FILE__\)/i', '\''._PS_MODULE_DIR_.$this->module_name.'\'', $moduleCore);
// Replace the private methods by protected (for allowed rewrite in extended classes)
$moduleCore = str_ireplace('private', 'protected', $moduleCore);
file_put_contents($this->module_core_path, $moduleCore, LOCK_EX);
$this->overrided_module[$this->module_name] = filemtime(_PS_MODULE_DIR_.$this->module_name.'/'.$this->module_name.'.php');
$this->generateIndex();
}
/**
* Return true if the file of parent class was a change
* @return bool
*/
protected function hasChanged()
{
return !array_key_exists($this->module_name, $this->overrided_module) || $this->overrided_module[$this->module_name] != filemtime(_PS_MODULE_DIR_.$this->module_name.'/'.$this->module_name.'.php');
}
/**
* Generate file width array of filetime
*/
protected function generateIndex()
{
$content = '<?php return '.var_export($this->overrided_module, true).'; ?>';
// Write classes index on disc to cache it
$filename = _PS_THEME_CACHE_DIR_.'module_index.php';
if ((file_exists($filename) && !is_writable($filename)) || !is_writable(dirname($filename)))
{
header('HTTP/1.1 503 temporarily overloaded');
// Cannot use PrestaShopException in this context
die($filename.' is not writable, please give write permissions (chmod 666) on this file.');
}
else
{
// Let's write index content in cache file
// In order to be sure that this file is correctly written, a check is done on the file content
$loop_protection = 0;
do
{
$integrity_is_ok = false;
file_put_contents($filename, $content, LOCK_EX);
if ($loop_protection++ > 10)
break;
// If the file content end with PHP tag, integrity of the file is ok
if (preg_match('#\?>\s*$#', file_get_contents($filename)))
$integrity_is_ok = true;
}
while (!$integrity_is_ok);
if (!$integrity_is_ok)
{
file_put_contents($filename, '<?php return array(); ?>', LOCK_EX);
// Cannot use PrestaShopException in this context
die('Your file '.$filename.' is corrupted. Please remove this file, a new one will be regenerated automatically');
}
}
}
}