You are on page 1of 80

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 <info@example.com> 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] => joomladagen@db8.nl [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 <info@example.com> 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>don@electriceasel.com</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