You are on page 1of 75

Core Hacks are evil How to change Joomla without core hacks

Peter Martin, twitter: @pe7er www.joomladay.co.uk, Sat 5th Oct 2013

Overview Presentation
Introduction Core Hack Alternatives

Template Override Alternative Layouts Language Override Use of Plugins Clone Module Component with own controller Extra Fields Overriding Core classes

>>>Sheetsvia:www.db8.nl<<<

Undoing core hacks Questions?

Peter Martin joomladagen.nl 20+21 april 2013

A. Core Hack

Peter Martin joomladagen.nl 20+21 april 2013

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

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

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);

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]

B. Eight Alternatives to Core Hacks

Peter Martin joomladagen.nl 20+21 april 2013

1. Template Override

Peter Martin joomladagen.nl 20+21 april 2013

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_fulltext": "","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_p ublish_date":"","show_item_navigation":"","show_icons":"","show_print_icon":"","show_email_icon":"","show_vot e":"","show_hits":"","show_noauth":"","alternative_readmore":"","article_layout":"","show_publishing_options":""," show_article_options":"","show_urls_images_backend":"","show_urls_images_frontend":""} [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-data-articles [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

Peter Martin joomladagen.nl 20+21 april 2013

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

types of alternative layouts:

Module Component Category Menu Item

20

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

Peter Martin joomladagen.nl 20+21 april 2013

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

Peter Martin joomladagen.nl 20+21 april 2013

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 H 2O 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

subscript tag

Search #/sub# Replace by </sub>

33

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 H 2O

Check the Menu/Article Alias! Menu item, Browser Page Title! Water is H2O

34

5. Clone a Module

Peter Martin joomladagen.nl 20+21 april 2013

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_quickicon 2', $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

Peter Martin joomladagen.nl 20+21 april 2013

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,

missing

in email the IP address of the sender is

Template override: not possible Clone Component: possible, but component = big Plugin: maybe possible, but which?

Add your own controller....

46

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]> [Message of visitor]

52

7. Plugin Extra fields

Peter Martin joomladagen.nl 20+21 april 2013

53

7. Plugin Extra fields


Joomla

runs extensions:

Components: URL index.php?option=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):

Display Save Delete

55

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

Content Plugin:
Events:

onContentPrepareData onContentPrepareForm onUserAfterSave onUserAfterDelete onContentPrepare

Documentation:
Adding

Extra Fields to article: http://docs.joomla.org/Adding_custom_fields_ to_the_article_component

58

8. Overriding Core Classes

Peter Martin joomladagen.nl 20+21 april 2013

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:

http://docs.joomla.org/How_to_override_the_compon ent_mvc_from_the_Joomla%21_core

61

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

Undoing Core Hacks

Peter Martin joomladagen.nl 20+21 april 2013

64

Undoing Core Hacks


Usually

Core Hacks are NOT documented Analyse code to find Core Hacks:
Joomla 2.5 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!

65

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/

66

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:

/my-site-without-hack/ now has original (non-Core Hacked) software!

67

Undoing Core Hacks


Use

diff tool to compare:

/my-site-with-hack/ /my-site-without-hack/

68

Undoing Core Hacks

69

Undoing Core Hacks

70

The

Peter Martin joomladagen.nl 20+21 april 2013

71

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

72

Conclusion
Core

Hack don't! of the 8 alternatives:


modifications won't get overwritten with an upgrade code improvements won't make it into the modified copy!

Changes (hacks) might get lost during upgrade

Most

Are in fact a hack on a copy of Joomla / 3rd party code


Advantage:

Disadvantage:

73

Questions?

Peter Martin joomladagen.nl 20+21 april 2013

74

Questions?
Presentation

available at www.db8.nl

Peter Martin e-mail: info at db8.nl website: www.db8.nl Twitter: @pe7er

Peter Martin joomladagen.nl 20+21 april 2013

75

Used Photos

digital dreams - Flavio Takemoto - http://www.sxc.hu/photo/1160561 Who buys this stuff for a kid? - Jason Antony - http://www.sxc.hu/photo/456502 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

76

You might also like