How to change Joomla without core hacks
Peter Martin Joomla World Conference 2012 Website: www.db8.nl Twitter: @pe7er Linkedin: http://linkedin.com/in/pe7er
Sunday November 18th, 2012
Overview Presentation
Introduction Core Hack Alternatives 1. Template Override 2. Alternative Layouts 3. Language Override 4. Use of Plugins 5. Clone Module 6. Component with own controller 7. Extra Fields 8. Overriding Core classes
Undoing core hacks Questions?
Core Hack
Core Hack
Joomla
= Open Source license GNU GPL GPL protects freedom & rights of users Source code = public You can and are allowed to change all Joomla code Core Hack = modification in source code Joomla 3rd party extension
4
Core Hack
Disadvantage of changing core code: Stability
Might give problems with 3rd party extensions Your code changes can be overwritten when you upgrade
Maintainability
Core Hack Example: Contact Form
Visitor's IP address is NOT displayed in email
6
Core Hack Example: Contact Form
Include
IP address with email:
/components/com_contact/controllers/contact.php private function _sendEmail($data, $contact), just under // Prepare email body $mail->setBody($body); change into: $mail->setBody("IP address: ". $_SERVER['REMOTE_ADDR']."\n\n".$body);
7
Core Hack Example: Contact Form
Result
(until the next Joomla upgrade):
Date: Sat, 17 Aug 2012 15:30:00 +0200 From: Visitor name <[email protected]> Reply-To: [Name visitor] <[email address visitor]> To: [email address SuperAdmin of Website] IP adres: 127.0.0.1 This is an enquiry email via http://www.example.com/ from: [Name visitor] <[email address visitor]> [Message of visitor]
8
Eight Alternatives to Core Hacks
1. Template override
10
1. Template override
Template
Layout of website "Space" for output components & modules
Components
& Modules
supply their own HTML output to the template
Template
overrides (since Joomla 1.5)
Copy HTML output of components / modules & change the copy
11
Example1 Latest News module
Module
displays a list of most recent articles Latest News
Beginners Getting Help Getting Started Joomla! Options
Change
request: customer wants to include a date!
12
Example1 Latest News module
1a. Template override:
Create HTML override folder in your template:
/templates/your_template/html/
Create new folder for module override
/templates/your_template/html/mod_articles_latest/
Copy HTML output from /tmpl/ of the module:
/modules/mod_articles_latest/tmpl/default.php to /templates/your_template/html/mod_articles_latest/default.php
13
Example1 Latest News module
1b. Test template override!
Add some text & check front-end website
/templates/your_template/html/mod_articles_latest/default.php
1c. Analyse useful variables with print_r:
<ul class="latestnews<?php echo $moduleclass_sfx; ?>"> <?php foreach ($list as $item) : ?> <li><?php print_r($item);?> <a href="<?php echo $item->link; ?>"> <?php echo $item->title; ?></a> </li> <?php endforeach; ?>
</ul>
14
Example1 Latest News module
stdClass Object ( [id] => 8 [title] => Beginners [alias] => beginners [title_alias] => [introtext] => If this is your first Joomla! site or your first web site, you have come to the right place. Joomla will help you get your website up and running quickly and easily. Start off using your site by logging in using the administrator account you created when you installed Joomla. [checked_out] => 0 [checked_out_time] => 0000-00-00 00:00:00 [catid] => 19 [created] => 2011-01-01 00:00:01 [created_by] => 42 [created_by_alias] => Joomla! [modified] => 2011-12-27 11:10:49 [modified_by] => 42 [modified_by_name] => Super User [publish_up] => 2011-01-01 00:00:01 [publish_down] => 0000-00-00 00:00:00 [images] => {"image_intro":"","float_intro":"","image_intro_alt":"","image_intro_caption":"","image_fulltext":"","float_fullte xt":"","image_fulltext_alt":"","image_fulltext_caption":""} [urls] => {"urla":"","urlatext":"","targeta":"","urlb":"","urlbtext":"","targetb":"","urlc":"","urlctext":"","targetc":""} [attribs] => {"show_title":"","link_titles":"","show_intro":"","show_category":"","link_category":"","show_parent_category ":"","link_parent_category":"","show_author":"","link_author":"","show_create_date":"","show_modify_date" :"","show_publish_date":"","show_item_navigation":"","show_icons":"","show_print_icon":"","show_email_i con":"","show_vote":"","show_hits":"","show_noauth":"","alternative_readmore":"","article_layout":"","show _publishing_options":"","show_article_options":"","show_urls_images_backend":"","show_urls_images_fro ntend":""} [metadata] => {"robots":"","author":"","rights":"","xreference":""} [metakey] => [metadesc] => [access] => 1 [hits] => 2 [xreference] => [featured] => 1 [readmore] => 1488 [state] => 1 [category_title] => Joomla! [category_route] => sample-data-articles/joomla [category_access] => 1 [category_alias] => joomla [author] => Joomla! [author_email] =>
[email protected] [contactid] => [parent_title] => Sample Data-Articles [parent_id] => 14 [parent_route] => sample-data-articles [parent_alias] => sample-dataarticles [rating] => [rating_count] => [published] => 1 [parents_published] => 1 [alternative_readmore] => [layout] => [params] => JRegistry Object ( [data:protected] => stdClass Object ( [article_layout] => _:default [show_title] => []
15
Example1 Latest News module
1d. Add to override $item->created:
<?php foreach ($list as $item) : ?> <li> <a href="<?php echo $item->link; ?>"> <?php echo $item->created." - ".$item->title; ?></a> </li> <?php endforeach; ?>
Output: Latest News
2011-01-01 00:00:01 Beginners 2011-01-01 00:00:01 - Getting Help 2011-01-01 00:00:01 - Getting Started 2011-01-01 00:00:01 - Joomla! 2011-01-01 00:00:01 - Options
16
Example1 Latest News module
1e. date/time from database in UTC format To use Server Time Zone:
$config = Jfactory::getConfig(); $user = Jfactory::getUser(); ?> <ul class="latestnews<?php echo $moduleclass_sfx; ?>"> <?php foreach ($list as $item) : $date = JFactory::getDate($item->created, 'UTC'); $date->setTimezone(new DateTimeZone($user->getParam('timezone', $config>get('offset')))); $item->format_created = $date->toFormat($params->get($item->created, '%A %d %B %Y, %H:%M:%S'), true, false); ?> <li> <a href="<?php echo $item->link; ?>"> <?php echo $item->format_created." - ".$item->title; ?></a> </li> <?php endforeach; ?> </ul>
17
Example1 Latest News module
Output:
Latest News
Saturday 01 January 2011, 01:00:01 - Beginners Saturday 01 January 2011, 01:00:01 - Getting Help Saturday 01 January 2011, 01:00:01 - Getting Started Saturday 01 January 2011, 01:00:01 - Joomla! Saturday 01 January 2011, 01:00:01 - Options
18
2. Alternative Layouts
19
2. Alternative Layouts
Alternative
Layouts = addition to Template
Override
= Template Override XTD Extra Control Options regarding display Extra HTML output files in /templates/html/
Four
20
types of alternative layouts:
Module Component Category Menu Item
2. Alternative Layouts
Template override file: /templates/your_template/html/mod_articles_latest/default.php overrides the HTML output of /modules/mod_articles_latest/tmpl/default.php
Alternative layout: Add other tmpl HTML output files to Template Override folder: /templates/your_template/html/mod_articles_latest/
21
2. Alternative Layouts
Example: Rename override (#1from this presentation) default.php to non-existing tmpl file: layout-with-date.php:
22
3. Language Overrides
23
3. Language Overrides
Since Joomla 2.5 Before 2.5: Core hack language files Extensions > Language Manager > Overrides
24
3. Language Overrides
New,
e.g. Read more
25
3. Language Overrides
Read
more Read much more
26
3. Language Overrides
Save
& Close:
27
3. Language Overrides
Result:
28
3. Language Overrides
Important:
[Filter] Site / Admin !
File
location override: /language/overrides/en-GB.override.ini
COM_CONTENT_READ_MORE= "Read much more: " Other languages 3rd party extensions
Note:
29
4. Use of Plugins
30
4. Use of Plugins
Joomla
removes HTML layout
In article titles In menu item titles In breadcrumb
Water
is H2O
Menu item H<sub>2</sub>O Water is H2O Article title H<sub>2</sub>O Water is H2O Text in article H<sub>2</sub>O Water is H O
2
31
4. Use of Plugins
ReReplacer
Nonumber (Peter van Westen) Component + System Plugin Download: http://www.nonumber.nl/extensions/rereplacer
32
4. Use of Plugins
Start
subscript tag
Search #sub# Replace by <sub>
End
33
subscript tag
Search #/sub# Replace by </sub>
4. Use of Plugins
Water
is H2O
Menu itemH#sub#2#/sub#O Water is H2O
Article title #sub#2#/sub#O Water is H2O Text in article H<sub>2</sub>O Water is H2O
Check the Menu/Article Alias! Menu item, Browser Page Title! Water is H2O
34
5. Clone a Module
35
5. Clone a Module
If template override possible, e.g. mod_quickicon
36
5. Clone a Module
Add
your own Quick Icon? Output of Quick Icon module:
/administrator/modules/mod_quickicon/tmpl/default.php
$html = JHtml::_('icons.buttons', $buttons); ?> <?php if (!empty($html)): ?> <div class="cpanel"><?php echo $html;?></div> <?php endif;?> Not possible to use template override...
37
5. Clone a Module
5a. Copy Module
/administrator/modules/mod_quickicon/ to /administrator/modules/mod_quickicon2/
5b. Rename files
mod_quickicon.php mod_quickicon2.php mod_quickicon.xml mod_quickicon2.xml
38
5. Clone a Module
5c. Edit mod_quickicon references mod_quickicon2.php
$buttons = modQuickIcon2Helper::getButtons($params); require JModuleHelper::getLayoutPath('mod_quickicon2', $params->get('layout', 'default'));
mod_quickicon2.xml
<name>mod_quickicon2</name> <filename module="mod_quickicon2">mod_quickicon2.php</filename>
39
5. Clone a Module
5d. Add to Joomla: Extensions > Extension Manager > Discover
40
5. Clone a Module
5e. Add Module mod_quickicon2:
Extensions > Module Manager > Filter: administrator [New] > mod_quickicon2 Title: My own Quick Icons Position: icon
41
5. Clone a Module
Oops: Fatal error: Cannot redeclare class modQuickIconHelper in /administrator/modules/mod_quickicon2/helper.php on line 18
5f. Edit helper.php
/administrator/modules/mod_quickicon2/helper.php change the classname: abstract class modQuickIconHelper2
42
5. Clone a Module
5g. Add your own array
/administrator/modules/mod_quickicon2/helper.php array( 'link' => Jroute::_('index.php?option=com_search'), 'image' => 'header/icon-48-search.png', 'text' => Jtext::_('Search'), 'access' => array('core.manage', 'com_search') ),
43
5. Clone a Module
5h. Result:
44
6. Component with own controller
45
6. Component with own controller
Joomla's
contact component:
Displays contact details Displays contact form Retrieves input contact form (check input, send to specified email address)
However,
in email the IP address of the sender is missing
Template override: not possible Clone Component: possible, but component = big Plugin: maybe possible, but which?
46
Add your own controller....
6. Component with own controller
Add
own controller to component:
Put own controller in existing /controllers/ folder of component Template override: change hidden variables in form to trigger your own controller
Example:
Change com_contact without corehack send IP address in e-mail to website administrator
47
6. Component with own controller
6a. Template override that triggers own controller:
Create template override folder /html/com_contact/contact/
Copy contact form HTML output
/components/com_contact/views/contact/tmpl/default_form.php
to template override folder /html/com_contact/contact/ Change /templates/your_template/html/com_contact/ contact/default_form.php
<input type="hidden" name="option" value="com_contact" /> <input type="hidden" name="task" value="contact.submit" /> <input type="hidden" name="return" value="<?php echo $this->return_page;?>" /> <input type="hidden" name="id" value="<?php echo $this->contact->slug; ?>" />
change task:
<input type="hidden" name="task" value="my_own_controller.submit" />
48
6. Component with own controller
6b. Own controller
Copy com_contact controller
/components/com_contact/controllers/contact.php
to (file name = 'task' from form in template override)
/components/com_contact/controllers/my_own_controller.php
6c. Change code of your own controller:
6c1. Change Classnaam:
class ContactControllerContact extends JcontrollerForm
becomes:
class ContactControllerMy_own_controller extends JControllerForm
49
6. Component with own controller
6c. Change code of your own controller:
6c2. Ask for model (Contact) with explicit prefix to prevent error:
Fatal error: Call to a member function getItem() on a non-object in /components/com_contact/controllers/my_own_controller.php on line 38
In method: public function submit()
$model = $this->getModel('Contact');
becomes:
$model = $this->getModel('Contact','ContactModel'); 50
6. Component with own controller
6C. Change code of your own controller:
6c3. Add your own code in method private function _sendEmail($data, $contact), just below // Prepare email body
$mail->setBody($body);
becomes:
$mail->setBody("IP address: "._SERVER['REMOTE_ADDR']. "\n\n".$body);
51
6. Component with own controller
6d. Result (will survive next Joomla upgrade):
Date: Sat, 17 Aug 2012 15:30:00 +0200 From: Visitor name <
[email protected]> Reply-To: [Name visitor] <[email address visitor]> To: [email address SuperAdmin of Website] IP adres: 127.0.0.1 This is an enquiry email via http://www.example.com/ from: [Name visitor] <[email address visitor]>
52
[Message of visitor]
7. Plugin Extra fields
53
7. Plugin Extra fields
Joomla
runs extensions:
Components: URL index.php?com_content Modules: Menu item &menuItem=x Plugin listen to events (hooks) Components have hooks
54
7. Plugin Extra fields
Extended
User Profile (core, disabled by
default)
Joomla's core component com_user 4 profile forms:
1.Front-end - User registration form 2.Front-end - User profile edit form 3.Back-end - User Manager > Edit a user form 4.Back-end - Admin menu > My Profile view form
User Plugin:
Functionality
(add fields to those 4 forms):
55
Display Save Delete
7. Plugin Extra fields
Extended
User Profile
User Plugin:
Events:
onContentPrepareData onContentPrepareForm onUserAfterSave onUserAfterDelete
Documentation:
Creating a profile plugin: http://docs.joomla.org/Creating_a_profile_plugin
56
7. Plugin Extra fields
Extra
fields in articles? Joomla's core component com_content 3 places to display extra fields:
1.Front-end - Display extra fields in article 2.Front-end - Extra fields in article editor form 3.Back-end - Extra fields in article editor form
Content Plugin:
Functionality
(add fields to those 3 places):
Display Save Delete
57
7. Plugin Extra fields
Extra
Article Fields
onContentPrepareData onContentPrepareForm onUserAfterSave onUserAfterDelete onContentPrepare
Content Plugin:
Events:
Documentation:
Adding
Extra Fields to article: http://docs.joomla.org/Adding_custom_fields_ to_the_article_component
58
8. Overriding Core Classes
59
8. Overriding Core Classes
Joomla's
core classes are:
Loaded once Loaded before everything else
Core
classes can
be extended (e.g. in your components) but there's no override mechanism
What
if you want to add something to a core class so that all inheritances will have that code?
60
8. Overriding Core Classes
Joomla!
Programming Mark Dexter & Louis Landry (released April 2012)
Page 182-186: Using Plugins to Override Core Classes
Documentation:
61
http://docs.joomla.org/How_to_override_the_ component_mvc_from_the_Joomla %21_core
8. Overriding Core Classes
In
short:
System Plugins are loaded before 1st event (onBeforeInitialise) Plugins can load Classes / plain code Create System Plugin that loads your modified core class (with include_once) Classes that have already been loaded before the System Plugins are imported...
Exception:
62
8. Overriding Core Classes
plg_system_overrides
config.php overrides.php overrides.xml
Override
Classes in /overrides/ Define classes to override in config.php
63
8. Overriding Core Classes
config.php
<?php /** * @package Joomla.Plugin * @subpackage System.Overrides * @copyright Copyright (C) 2012 Don Gilbert. All rights reserved. * @license GNU General Public License version 2 or later; */ define('OVERRIDES', dirname(__FILE__).'/overrides'); // Use JLoader to register all the classes you want to override JLoader::register('JClassToOverride', OVERRIDES.'/libraries/joomla/class/to/override.php', true); 64
8. Overriding Core Classes
overrides.php
<?php defined('JPATH_BASE') or die; /** * System plugin to override core classes terms. * @package Joomla.Plugin * @subpackage System.Overrides * @since 2.5 */ class PlgSystemOverrides extends JPlugin { /* We do our thing in the __construct method * so that our overridden classes will be * available everywhere */ public function __construct(&$subject, $config) { parent::__construct($subject, $config); include_once 'config.php'; } }
65
8. Overriding Core Classes
overrides.xml
<?xml version="1.0" encoding="utf-8"?> <extension version="2.5" type="plugin" group="system" method="upgrade"> <name>plg_system_overrides</name> <author>Don Gilbert</author> <creationDate>Aug 2012</creationDate> <copyright>(C) 2012 Don Gilbert. All rights reserved.</copyright> <license>GNU General Public License version 2 or later;</license> <authorEmail>
[email protected]</authorEmail> <authorUrl>www.electriceasel.com</authorUrl> <version>2.5.6</version> <description>This plugin will override classes contained in the included config file.</description> <files> <filename plugin="overrides">overrides.php</filename> <filename>config.php</filename> <filename>index.html</filename> <folder>overrides</folder> </files> </extension>
66
9. Other Thoughts
.htaccess
& 301 redirects?
301 Redirect /old-file.php http://example.com/new-file.php Does *not* work for files retrieved via filesystem (e.g. via include_once in .php files)
Symbolic Link? http://en.wikipedia.org/wiki/Symbolic_link Linux: ln -s target_path link_path Copy a Joomla Core File to /template/override/ folder & overwrite original with non-writable symlink to copy?
67
Undoing Core Hacks
68
Undoing Core Hacks
Usually
Core Hacks are NOT documented Analyse code to find Core Hacks:
Joomla 2.5.8 without 3rd party extensions: 5,586 items, totalling 19.0 MB Test site with some 3rd party extensions: 7,618 items, totalling 42.2 MB
Good luck!
69
Undoing Core Hacks
Use
diff, a file comparison utility:
GUI: Meld (Linux & Mac OSX) GUI: WinMerge (Windows)
Preparations
1/2:
Back-up of website (Use Akeeba backup!) Local LAMP stack (LAMP/XAMPP/MAMP/WAMP) Restore back-up to two websites using 2 databases:
/my-site-with-hack/ /my-site-without-hack/
70
Undoing Core Hacks
Preparations
2/2:
Download same version of Joomla & unzip Download same versions of 3rd party extensions Overwrite all files with Joomla files (except /installation/ folder) to
/my-site-without-hack/
Install (reinstall) 3rd party extensions to
/my-site-without-hack/
Result:
71
/my-site-without-hack/ now has original (non-Core Hacked) software!
Undoing Core Hacks
Use
diff tool to compare:
/my-site-with-hack/ /my-site-without-hack/
72
Undoing Core Hacks
73
Undoing Core Hacks
74
Conclusion
75
Conclusion
Core Hack = Modification of core files (Joomla or 3rd party) Eight Alternatives to avoid Core Hacks
1. Template Override (copy extensions HTML output to your templates /html/ directory and change that) 2. Alternative Layouts 3. Language Overrides 4. Use Plugins 5. Clone Module (copy complete module & change that) 6. Own controller (add own controller & use template override to trigger your controller) 7. Extra fields 8. Overriding Core Classes
Undoing Core Hacks
Use diff tools to compare original & modified code
76
Conclusion
Core
Hack don't!
Changes (hacks) might get lost during upgrade
Most
of the 8 alternatives:
Are in fact a hack on a copy of Joomla / 3rd party code
Advantage:
modifications won't get overwritten with an upgrade
Disadvantage:
code improvements won't make it into the modified copy!
77
Questions?
78
Questions?
Peter Martin e-mail: info at db8.nl website: www.db8.nl
79
Used Photos
Axe - Peter Huys, http://www.sxc.hu/photo/808871 Photo Frame 9 Billy Alexander, http://www.sxc.hu/photo/1367198 Bengali Keyborad - Mohammad Jobaed Adnan http://www.sxc.hu/photo/676844 usb - Vangelis Thomaidis, http://www.sxc.hu/photo/913590 HiSpeed copier 1 - Marcin Barowski, http://www.sxc.hu/photo/537037 Game pad - Michal Zacharzewski, http://www.sxc.hu/photo/957040 EXTRA Warmth - Nicolas Raymond http://www.sxc.hu/photo/971125 blueprint - Kerem Yucel, http://www.sxc.hu/photo/282237 Red Plaster - Paul Barker, http://www.sxc.hu/photo/1114174 signs signs - Jason Antony, http://www.sxc.hu/photo/751034 Face - Questions - Bob Smith, http://www.sxc.hu/photo/418215
80