├── README.md
├── module
└── helper.php
├── mvcoverride.php
└── mvcoverride.xml
/README.md:
--------------------------------------------------------------------------------
1 | Hi everyone,
2 |
3 | thank you for your interest for this plugin.
4 |
5 | Unfortunately, I am running out of time these days, so I won't update it.
6 |
7 | If anyone has a solution to make it better, please feel free to fork it.
8 |
9 | Maybe, I'll come back in a few months, but right now I have a big project that will take all my energies.
10 |
11 |
12 | plg_mvcoverride
13 | ===============
14 |
15 | Joomla plugin to override Joomla MVC.
16 |
17 | Plugin used (and updated for j!3) in these joomla docs :
18 |
19 | [How to override the component mvc from the Joomla! core - Joomla! Documentation](http://docs.joomla.org/How_to_override_the_component_mvc_from_the_Joomla!_core)
20 |
21 | The joomla 2.5.x version is here :
22 |
23 | Plugin Override - Joomla! Extensions Directory
24 |
25 | http://extensions.joomla.org/extensions/style-a-design/templating/15611
26 |
27 | ###Usage example
28 | For a component :
29 | >/templates/yourtemplate/code/com_search/views/search/view.html.php
30 |
31 | For a module :
32 | >/templates/yourtemplate/code/module_name/helper.php
33 |
34 |
35 | ###Issue
36 | No more issue ATM.
37 |
38 | Alex Chartier found a working solution.
39 |
40 | If someone finds an issue, please tell us.
41 |
--------------------------------------------------------------------------------
/module/helper.php:
--------------------------------------------------------------------------------
1 | mark('beforeRenderModule ' . $module->module . ' (' . $module->title . ')');
39 | }
40 |
41 | $app = JFactory::getApplication();
42 |
43 | // Record the scope.
44 | $scope = $app->scope;
45 |
46 | // Set scope to component name
47 | $app->scope = $module->module;
48 |
49 | // Get module parameters
50 | $params = new JRegistry;
51 | $params->loadString($module->params);
52 |
53 | // Get the template
54 | $template = $app->getTemplate();
55 |
56 | // Get module path
57 | $module->module = preg_replace('/[^A-Z0-9_\.-]/i', '', $module->module);
58 | $path = JPATH_BASE . '/modules/' . $module->module . '/' . $module->module . '.php';
59 | self::addIncludePath(JPATH_BASE . '/modules');
60 |
61 | // Load the module
62 | // $module->user is a check for 1.0 custom modules and is deprecated refactoring
63 | if (empty($module->user))
64 | {
65 | $lang = JFactory::getLanguage();
66 |
67 | // 1.5 or Core then 1.6 3PD
68 | $lang->load($module->module, JPATH_BASE, null, false, false) ||
69 | $lang->load($module->module, dirname($path), null, false, false) ||
70 | $lang->load($module->module, JPATH_BASE, $lang->getDefault(), false, false) ||
71 | $lang->load($module->module, dirname($path), $lang->getDefault(), false, false);
72 |
73 | $content = '';
74 | ob_start();
75 | include JPath::find(self::addIncludePath(),$module->module . '/' . $module->module . '.php');
76 | $module->content = ob_get_contents() . $content;
77 | ob_end_clean();
78 | }
79 |
80 | // Load the module chrome functions
81 | if (!$chrome)
82 | {
83 | $chrome = array();
84 | }
85 |
86 | include_once JPATH_THEMES . '/system/html/modules.php';
87 | $chromePath = JPATH_THEMES . '/' . $template . '/html/modules.php';
88 |
89 | if (!isset($chrome[$chromePath]))
90 | {
91 | if (file_exists($chromePath))
92 | {
93 | include_once $chromePath;
94 | }
95 |
96 | $chrome[$chromePath] = true;
97 | }
98 |
99 | // Check if the current module has a style param to override template module style
100 | $paramsChromeStyle = $params->get('style');
101 |
102 | if ($paramsChromeStyle)
103 | {
104 | $attribs['style'] = preg_replace('/^(system|' . $template . ')\-/i', '', $paramsChromeStyle);
105 | }
106 |
107 | // Make sure a style is set
108 | if (!isset($attribs['style']))
109 | {
110 | $attribs['style'] = 'none';
111 | }
112 |
113 | // Dynamically add outline style
114 | if ($app->input->getBool('tp') && JComponentHelper::getParams('com_templates')->get('template_positions_display'))
115 | {
116 | $attribs['style'] .= ' outline';
117 | }
118 |
119 | foreach (explode(' ', $attribs['style']) as $style)
120 | {
121 | $chromeMethod = 'modChrome_' . $style;
122 |
123 | // Apply chrome and render module
124 | if (function_exists($chromeMethod))
125 | {
126 | $module->style = $attribs['style'];
127 |
128 | ob_start();
129 | $chromeMethod($module, $params, $attribs);
130 | $module->content = ob_get_contents();
131 | ob_end_clean();
132 | }
133 | }
134 |
135 | // Revert the scope
136 | $app->scope = $scope;
137 |
138 | if (constant('JDEBUG'))
139 | {
140 | JProfiler::getInstance('Application')->mark('afterRenderModule ' . $module->module . ' (' . $module->title . ')');
141 | }
142 |
143 | return $module->content;
144 | }
145 |
146 | /**
147 | * Get the path to a layout for a module
148 | *
149 | * @param string $module The name of the module
150 | * @param string $layout The name of the module layout. If alternative layout, in the form template:filename.
151 | *
152 | * @return string The path to the module layout
153 | *
154 | * @since 11.1
155 | */
156 | public static function getLayoutPath($module, $layout = 'default')
157 | {
158 | $template = JFactory::getApplication()->getTemplate();
159 | $defaultLayout = $layout;
160 |
161 | if (strpos($layout, ':') !== false)
162 | {
163 | // Get the template and file name from the string
164 | $temp = explode(':', $layout);
165 | $template = ($temp[0] == '_') ? $template : $temp[0];
166 | $layout = $temp[1];
167 | $defaultLayout = ($temp[1]) ? $temp[1] : 'default';
168 | }
169 |
170 | // Build the template and base path for the layout
171 | $templatePaths = array(
172 | JPATH_THEMES . '/' . $template . '/html/' . $module,
173 | JPATH_BASE . '/modules/' . $module . '/tmpl',
174 | );
175 | $dPath = JPATH_BASE . '/modules/' . $module . '/tmpl/default.php';
176 |
177 | // If the template has a layout override use it
178 | if ($tPath = JPath::find($templatePaths,$defaultLayout.'.php'))
179 | {
180 | return $tPath;
181 | }
182 | else
183 | {
184 | return $dPath;
185 | }
186 | }
187 |
188 | /**
189 | * Add a directory where JModuleHelper should search for module. You may
190 | * either pass a string or an array of directories.
191 | *
192 | * @param string $path A path to search.
193 | *
194 | * @return array An array with directory elements
195 | *
196 | * @since 11.1
197 | */
198 | public static function addIncludePath($path = '')
199 | {
200 | // Force path to array
201 | settype($path, 'array');
202 |
203 | // Loop through the path directories
204 | foreach ($path as $dir)
205 | {
206 | if (!empty($dir) && !in_array($dir, self::$includePaths))
207 | {
208 | jimport('joomla.filesystem.path');
209 | array_unshift(self::$includePaths, JPath::clean($dir));
210 |
211 | //fix to override include path priority
212 | self::$includePaths = array_reverse(self::$includePaths);
213 | }
214 | }
215 |
216 | return self::$includePaths;
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/mvcoverride.php:
--------------------------------------------------------------------------------
1 | getShortVersion(), "3.8", "lt"))
21 | {
22 | if (version_compare($jV->getShortVersion(), "3", "lt"))
23 | $loc = '/joomla/application/module/';
24 | else
25 | $loc = '/cms/module/';
26 |
27 | //override JModuleHelper library class
28 | $moduleHelperContent = JFile::read(JPATH_LIBRARIES . $loc . 'helper.php');
29 | $moduleHelperContent = str_replace('JModuleHelper', 'JModuleHelperLibraryDefault', $moduleHelperContent);
30 | $moduleHelperContent = str_replace('input->get('option');
52 |
53 | if( empty($option) && JFactory::getApplication()->isSite() ) {
54 | $menuDefault = JFactory::getApplication()->getMenu()->getDefault();
55 | if ($menuDefault == 0) return;
56 |
57 | $componentID = $menuDefault->componentid;
58 | $db = JFactory::getDBO();
59 |
60 | //corrected by vdrover
61 | $db->setQuery('SELECT * FROM #__extensions WHERE extension_id ='.$db->quote($componentID));
62 | $component = $db->loadObject();
63 | $option = $component->element;
64 | }
65 |
66 | //get files that can be overrided
67 | $componentOverrideFiles = $this->loadComponentFiles($option);
68 | //application name
69 | $applicationName = JFactory::getApplication()->getName();
70 | //template name
71 | $template = JFactory::getApplication()->getTemplate();
72 |
73 | //code paths
74 | $includePath = array();
75 | //template code path
76 | $includePath[] = JPATH_THEMES.'/'.$template.'/code';
77 | //base extensions path
78 | $includePath[] = JPATH_BASE.'/code';
79 |
80 | JModelLegacy::addIncludePath(JPATH_BASE.'/code/modules');
81 | JModelLegacy::addIncludePath(JPATH_THEMES.'/'.$template.'/code/modules');
82 |
83 |
84 | //constants to replace JPATH_COMPONENT, JPATH_COMPONENT_SITE and JPATH_COMPONENT_ADMINISTRATOR
85 | define('JPATH_SOURCE_COMPONENT',JPATH_BASE.'/components/'.$option);
86 | define('JPATH_SOURCE_COMPONENT_SITE',JPATH_SITE.'/components/'.$option);
87 | define('JPATH_SOURCE_COMPONENT_ADMINISTRATOR',JPATH_ADMINISTRATOR.'/components/'.$option);
88 |
89 | //loading override files
90 | if( !empty($componentOverrideFiles) ){
91 | foreach($componentOverrideFiles as $componentFile)
92 | {
93 | if($filePath = $this->findPath($includePath,$componentFile))
94 | {
95 | //include the original code and replace class name add a Default on
96 | if ($this->params->get('extendDefault',0))
97 | {
98 | $bufferFile = file_get_contents(JPATH_BASE.'/components/'.$componentFile);
99 | //detect if source file use some constants
100 | preg_match_all('/JPATH_COMPONENT(_SITE|_ADMINISTRATOR)|JPATH_COMPONENT/i', $bufferFile, $definesSource);
101 |
102 | $bufferOverrideFile = file_get_contents($filePath);
103 | //detect if override file use some constants
104 | preg_match_all('/JPATH_COMPONENT(_SITE|_ADMINISTRATOR)|JPATH_COMPONENT/i', $bufferOverrideFile, $definesSourceOverride);
105 |
106 | // Append "Default" to the class name (ex. ClassNameDefault). We insert the new class name into the original regex match to get
107 | $rx = '/class *[a-z0-0]* *(extends|{)/i';
108 |
109 | preg_match($rx, $bufferFile, $classes);
110 |
111 | $parts = explode(' ',$classes[0]);
112 |
113 | $originalClass = $parts[1];
114 | $replaceClass = $originalClass.'Default';
115 |
116 | if (count($definesSourceOverride[0]))
117 | {
118 |
119 | //throw new Exception(JText::_('Ckjhkjhkjh'));
120 | throw new Exception(JText::_('Plugin MVC Override','Your override file use constants, please replace code constants
JPATH_COMPONENT -> JPATH_SOURCE_COMPONENT,
JPATH_COMPONENT_SITE -> JPATH_SOURCE_COMPONENT_SITE and
JPATH_COMPONENT_ADMINISTRATOR -> JPATH_SOURCE_COMPONENT_ADMINISTRATOR'));
121 | }
122 | else
123 | {
124 | //replace original class name by default
125 | $bufferContent = str_replace($originalClass,$replaceClass,$bufferFile);
126 |
127 | //replace JPATH_COMPONENT constants if found, because we are loading before define these constants
128 | if (count($definesSource[0]))
129 | {
130 | $bufferContent = preg_replace(array('/JPATH_COMPONENT/','/JPATH_COMPONENT_SITE/','/JPATH_COMPONENT_ADMINISTRATOR/'),array('JPATH_SOURCE_COMPONENT','JPATH_SOURCE_COMPONENT_SITE','JPATH_SOURCE_COMPONENT_ADMINISTRATOR'),$bufferContent);
131 | }
132 |
133 | // Change private methods to protected methods
134 | if ($this->params->get('changePrivate',0))
135 | {
136 | $bufferContent = preg_replace('/private *function/i', 'protected function', $bufferContent);
137 | }
138 |
139 | // Finally we can load the base class
140 | eval('?>'.$bufferContent.PHP_EOL.'?>');
141 |
142 | require_once $filePath;
143 | }
144 | }
145 | else
146 | {
147 | require_once $filePath;
148 | }
149 | }
150 | }
151 | }
152 | }
153 |
154 | /**
155 | * loadComponentFiles function.
156 | *
157 | * @access private
158 | * @param mixed $option
159 | * @return void
160 | */
161 | private function loadComponentFiles($option)
162 | {
163 | $JPATH_COMPONENT = JPATH_BASE.'/components/'.$option;
164 | $files = array();
165 |
166 | //check if default controller exists
167 | if (JFile::exists($JPATH_COMPONENT.'/controller.php'))
168 | {
169 | $files[] = $JPATH_COMPONENT.'/controller.php';
170 | }
171 |
172 | //check if controllers folder exists
173 | if (JFolder::exists($JPATH_COMPONENT.'/controllers'))
174 | {
175 | $controllers = JFolder::files($JPATH_COMPONENT.'/controllers', '.php', false, true);
176 | $files = array_merge($files, $controllers);
177 | }
178 |
179 | //check if models folder exists
180 | if (JFolder::exists($JPATH_COMPONENT.'/models'))
181 | {
182 | $models = JFolder::files($JPATH_COMPONENT.'/models', '.php', false, true);
183 | $files = array_merge($files, $models);
184 | }
185 |
186 | //check if views folder exists
187 | if (JFolder::exists($JPATH_COMPONENT.'/views'))
188 | {
189 | //reading view folders
190 | $views = JFolder::folders($JPATH_COMPONENT.'/views');
191 | foreach ($views as $view)
192 | {
193 | //get view formats files
194 | $viewsFiles = JFolder::files($JPATH_COMPONENT.'/views/'.$view, '.php', false, true);
195 | $files = array_merge($files, $viewsFiles);
196 | }
197 | }
198 |
199 | $return = array();
200 | //cleaning files
201 | foreach ($files as $file)
202 | {
203 | $file = JPath::clean($file);
204 | $file = substr($file, strlen(JPATH_BASE.'/components/'));
205 | $return[] = $file;
206 | }
207 |
208 | return $return;
209 | }
210 | /**
211 | * findPath function.
212 | * Replacement for JPATH::find, if the target path is a symlink JPATH::find fails
213 | *
214 | * @access private
215 | * @param mixed $option
216 | * @return void
217 | */
218 | private function findPath($paths, $file)
219 | {
220 | // Force to array
221 | if (!is_array($paths) && !($paths instanceof Iterator))
222 | {
223 | settype($paths, 'array');
224 | }
225 |
226 | // Start looping through the path set
227 | foreach ($paths as $path)
228 | {
229 | // Get the path to the file
230 | $fullname = $path . '/' . $file;
231 |
232 | if (file_exists($fullname))
233 | {
234 | return $fullname;
235 | }
236 | }
237 |
238 | // Could not find the file in the set of paths
239 | return false;
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/mvcoverride.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | System - MVC Override
4 | Julio Pontes - modified by Alex Chartier and Ghazal
5 | December 2014
6 | Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
7 | http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 | http://twitter.com/juliopontes
9 | 3.3
10 | Provides a component MVC override.
11 |
12 | mvcoverride.php
13 | module
14 |
15 |
16 |
17 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------