How to change Joomla without core hacks Peter Martin JUG010 - Joomla User Group Rotterdam Website: www.db8.nl Twitter: @pe7er Linkedin: http://linkedin.com/in/pe7er Dinsdag 18 december 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 2 Undoing core hacks Questions?
Core Hack 3
Core Hack Core Hack = modification in source code Joomla 3rd party extension Joomla 4 = 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 Core Hacks... 5 Anyone? Anyone?
Core Hack Disadvantage of changing core code : Stability Might give problems with 3rd party extensions Maintainability 6 Your code changes can be overwritten when you upgrade
Core Hack Example: Contact Form Visitor's IP address is NOT displayed in email 7
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); 8
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] 9
Eight Alternatives to Core Hacks 10
1. Template override 11
1. Template override Template Layout of website "Space" for output components & modules Components supply their own HTML output to the template Template 12 & Modules overrides (since Joomla 1.5) Copy HTML output of components / modules & change the copy
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! 13
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 14
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> 15
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] => [ ] 16
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;?> 17 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
Example1 Latest News module 1e. date/time from database in UTC format To use Server Time Zone : 18 $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>
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 19
2. Alternative Layouts 20
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 21 types of alternative layouts: Module Component Category Menu Item
2. Alternative Layouts 22 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/
2. Alternative Layouts 23 Example: Rename override (#1from this presentation) default.php to non-existing tmpl file: layout-with-date.php :
3. Language Overrides 24
3. Language Overrides Since Joomla 2.5 Before 2.5: Core hack language files Extensions > Language Manager > Overrides 25
3. Language Overrides New, 26 e.g. Read more
3. Language Overrides Read 27 more Read much more
3. Language Overrides Save 28 & Close :
3. Language Overrides Result: 29
3. Language Overrides Important: [Filter] Site / Admin! File location override: /language/overrides/en-gb.override.ini COM_CONTENT_READ_MORE= "Read much more: " Note: 30 Other languages 3rd party extensions
4. Use of Plugins 31
4. Use of Plugins Joomla 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 32 removes HTML layout 2
4. Use of Plugins ReReplacer 33 Nonumber (Peter van Westen) Component + System Plugin Download: http://www.nonumber.nl/extensions/rereplacer
4. Use of Plugins Start Search #sub# Replace by <sub> End 34 subscript tag subscript tag Search #/sub# Replace by </sub>
4. Use of Plugins Water 35 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
5. Clone a Module 36
5. Clone a Module 37 If template override possible, e.g. mod_quickicon
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... 38
5. Clone a Module 5a. Copy Module /administrator/modules/mod_quickicon/ to /administrator/modules/mod_quickicon2/ 5b. Rename files 39 mod_quickicon.php mod_quickicon2.php mod_quickicon.xml mod_quickicon2.xml
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> 40
5. Clone a Module 5d. Add to Joomla: Extensions > Extension Manager > Discover 41
5. Clone a Module 5e. Add Module mod_quickicon2: 42 Extensions > Module Manager > Filter: administrator [New] > mod_quickicon2 Title: My own Quick Icons Position: icon
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 43
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') ), 44
5. Clone a Module 5h. Result: 45
6. Component with own controller 46
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 47 Template override: not possible Clone Component: possible, but component = big Plugin: maybe possible, but which? 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 48
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" /> 49
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 50
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'); 51
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); 52
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]> 53 [Message of visitor]
7. Plugin Extra fields 54
7. Plugin Extra fields Joomla 55 runs extensions: Components: URL index.php?com_content Modules: Menu item &menuitem=x Plugin listen to events ( hooks ) Components have hooks
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 Display Save Delete 56 (add fields to those 4 forms):
7. Plugin Extra fields Extended User Profile User Plugin : Events: oncontentpreparedata oncontentprepareform onuseraftersave onuserafterdelete Documentation: 57 Creating a profile plugin: http://docs.joomla.org/creating_a_profile_plugin
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 Display Save Delete 58 (add fields to those 3 places):
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 59
8. Overriding Core Classes 60
8. Overriding Core Classes Joomla's Loaded once Loaded before everything else Core core classes are: 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? 61
8. Overriding Core Classes Joomla! Programming Mark Dexter & Louis Landry (released April 2012) Page 182-186: Using Plugins to Override Core Classes Documentation: 62 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) Exception: 63 Classes that have already been loaded before the System Plugins are imported...
8. Overriding Core Classes plg_system_overrides config.php overrides.php overrides.xml Override Classes in /overrides/ Define classes to override in config.php 64
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); 65
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'; } } 66
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> 67
9. Other Thoughts.htaccess 68 & 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?
Undoing Core Hacks 69
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! 70
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/ 71
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: 72 /my-site-without-hack/ now has original (non-core Hacked) software!
Undoing Core Hacks Use 73 diff tool to compare: /my-site-with-hack/ /my-site-without-hack/
Undoing Core Hacks 74
Undoing Core Hacks 75
Conclusion 76
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 77 Use diff tools to compare original & modified code
Conclusion Core Changes ( hacks ) might get lost during upgrade Most Hack don't! 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! 78
Questions? 79
Questions? Peter Martin e-mail: info at db8.nl website: www.db8.nl 80
Used Photos 81 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 Barłowski, 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