Transcript
Page 1: Best practices for Joomla extensions developers - Joomla Day 2013

Joomla Extensions Development Best Practices

Francesco Abeni GiBiLogicextensions.gibilogic.com

Page 2: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

¡Hola, mundo!

Page 3: Best practices for Joomla extensions developers - Joomla Day 2013

Shameless self-promotion

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

FrancescoAbeni

sPrintAddCSSPizzaBox

Page 4: Best practices for Joomla extensions developers - Joomla Day 2013

About this speech

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

The quality of code in the Joomlasphere

Page 5: Best practices for Joomla extensions developers - Joomla Day 2013

Today roadmap:

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● Tools● Files and folders● Reuse software● MVC● Other tips● Conclusions

Feedback please!

Page 6: Best practices for Joomla extensions developers - Joomla Day 2013

No dev course

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 7: Best practices for Joomla extensions developers - Joomla Day 2013

Our target

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Good = not bad

Excellent = above the average

Good is enough for today

Page 8: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 9: Best practices for Joomla extensions developers - Joomla Day 2013

IDE basic features

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● multiple files edit● syntax highlighting● index for methods and variables● autocompletion● autoformatting● compiler● versioning / unit testing / phpdoc / ...

Page 10: Best practices for Joomla extensions developers - Joomla Day 2013

Some IDEs

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 11: Best practices for Joomla extensions developers - Joomla Day 2013

Versioning

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

http://git-scm.com/book

Page 12: Best practices for Joomla extensions developers - Joomla Day 2013

Standard

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 13: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 14: Best practices for Joomla extensions developers - Joomla Day 2013

Everything in its right place

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Backend ● administrator○ components

■ com_componentname● componentname.xml● componentname.php● controllers● models● views

Page 15: Best practices for Joomla extensions developers - Joomla Day 2013

Everything in its right place

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Backend ● administrator○ components

■ com_componentname● ...● config.xml● install.php● sql● tables● helpers

Page 16: Best practices for Joomla extensions developers - Joomla Day 2013

● media○ com_componentname

■ css■ js■ img

● components○ com_componentname

■ componentname.php■ controllers■ models■ views

Everything in its right place

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Frontend

● images○ com_componentname

Page 17: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 18: Best practices for Joomla extensions developers - Joomla Day 2013

CSS / JS

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Use existing libraries

JavaScript● MooTools (since Joomla 1.5)● JQuery (since Joomla 2.5)

CSS + JavaScript● Bootstrap (since Joomla 3.x)

P.S. got conflicts? Use JQueryEasy plugin.

Page 19: Best practices for Joomla extensions developers - Joomla Day 2013

CSS out of the door

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Don't:<div>...</div><br style="clear: both"><div style="height: 200px">...</div>

Do:<link rel=”stylesheet” href=”/media/componentname/styles.css”>...<div class=”clearfix”>...</div><div class="fixedheight">...</div>

.clearfix { … }

.fixedheight { height: 200px }

Page 20: Best practices for Joomla extensions developers - Joomla Day 2013

JS out of the door

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<button id="submit" type=submit" value="ClickMe!" onclick="validateForm()" />

Do:<script src=”/media/componentname/js/script.js”><button id="submit" type=submit" value="ClickMe!"/>

document.addEvent('load',function(){ $('submit').addEvent('click',function(){

validateForm(); });

});

Don't:

Page 21: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 22: Best practices for Joomla extensions developers - Joomla Day 2013

Joomla framework

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● JApplication● JDatabase● JUser● JSession● JDocument● JHTML● JForm● JConfig● JUri

● JFile● JFolder● JLog● JFilterInput ● JError and JException● JDate● JUtilities● JVersion● JLayout

Page 23: Best practices for Joomla extensions developers - Joomla Day 2013

PHP functions and classes

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● pcre● trim● usort● array_map● array_unique● json_encode● json_decode● microtime(true)● glob● curl

● DateTime● Standard PHP Library● Exception● SimpleXML● TCPDF● PHPMailer

Page 24: Best practices for Joomla extensions developers - Joomla Day 2013

PHP version

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● 16. Dec 2010: PHP 5.2 end of life● 11. Jul 2013: PHP 5.3 end of life● 01. Mar 2012: PHP 5.4 released ● 20 Jun 2013: PHP 5.5 released

● PHP 5.4 is 40% faster than PHP 5.2

Page 25: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 26: Best practices for Joomla extensions developers - Joomla Day 2013

Real objects

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

book writer library

Page 27: Best practices for Joomla extensions developers - Joomla Day 2013

Bad design sample

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● views/search● views/editbook● views/book● views/books● views/booksauthor● views/topten

Don't:

Page 28: Best practices for Joomla extensions developers - Joomla Day 2013

The controller

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● Filters input● Decides what to do● Checks access permissions● Executes task(s)● Optionally, calls the view

Page 29: Best practices for Joomla extensions developers - Joomla Day 2013

The model

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● Retrieves object data● Validates object data● Gets object data● Saves object data● Hates to be mistaken as an helper

Page 30: Best practices for Joomla extensions developers - Joomla Day 2013

The view

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● Ask the model for data● Display object(s)● Uses layouts!

Page 31: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 32: Best practices for Joomla extensions developers - Joomla Day 2013

Header comment

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php

/*** @version mybooks.php 2013-08-10 15:23:00Z zanardi* @package GiBi MyBooks* @author GiBiLogic* @authorUrl http://www.gibilogic.com* @authorEmail [email protected]* @copyright Copyright (C) 2013 GiBiLogic. All rights reserved.* @license GNU/GPL v2 or later* @description Backend entry point*/

Page 33: Best practices for Joomla extensions developers - Joomla Day 2013

Entry point

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php...defined('_JEXEC') or die();

jimport('joomla.application.component.controller');

$view = JFactory::getApplication()->input->get('view', 'book');$task = JFactory::getApplication()->input->get('task', 'index');JFactory::getApplication()->input->set('task', "$view.$task");

$controller = JController::getInstance('MyBooks');$controller->execute($task);$controller->redirect();

Page 34: Best practices for Joomla extensions developers - Joomla Day 2013

Controller - part 1

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php...defined('_JEXEC') or die('The way is shut!');

jimport('joomla.application.component.controlleradmin');

/*** MyBooksControllerBook class.** @see JControllerAdmin*/class MyBooksControllerBook extends JControllerAdmin{ /** * Controller's view. * * @var JView */ private $view; ...

Page 35: Best practices for Joomla extensions developers - Joomla Day 2013

Controller - part 2

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php ... /** * Class constructor. * * @param type $config */ public function __construct($config = array()) { parent::__construct($config);

$this->model = $this->getModel();

$this->view = $this->getView(JFactory::getApplication()->input->get('view', 'book'), 'html'); $this->view->setModel($this->model, true); $this->view->setModel($this->getModel('Author', 'MyBooksModel'), false); $this->view->setModel($this->getModel('Editor', 'MyBooksModel'), false); } ...

Page 36: Best practices for Joomla extensions developers - Joomla Day 2013

Controller - part 3

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php ... public function index() { $this->view->setLayout('index') $this->view->display(); }

public function create() { $this->view->setLayout('create'); $this->view->display(); }

public function save() { $data = JFactory::getApplication()->input->get('jform', null); if (!$data || !$this->model->validate($data)) { $msg = 'Invalid data!'; $type = 'error'; $this->setRedirect('index.php?option=com_mybooks&view=book&task=create', $msg, $type); return false; }

Page 37: Best practices for Joomla extensions developers - Joomla Day 2013

Model - part 1

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php...defined('_JEXEC') or die('The way is shut!');

jimport('joomla.application.component.model');jimport('joomla.html.pagination');

class MybooksModelBook extends JModel{ private $table = '#__mybooks_book';

public function __construct($config = array()) { parent::__construct($config);

$app = JFactory::getApplication(); $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->getCfg('list_limit'), 'int'); $limitstart = $app->input->get('limitstart', 0, '', 'int'); $this->setState('limit', $limit); $this->setState('limitstart', $limitstart); $this->setState('author_id', $app->getUserStateFromRequest('com_mybooks.filters.author_id', 'author_id', 0, 'int')); }

Page 38: Best practices for Joomla extensions developers - Joomla Day 2013

Model - part 2

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php ... public function getList() { return $this->_getList( $this->buildQuery(), $this->getState('limitstart'), $this->getState('limit') ); }

public function getLast() { $query = $this->_db->getQuery(true); $query->select('*')->from($this->table)->orderby('created_at DESC'); $this->_db->setQuery($query,0,1); $results = $this->_db->loadObjectList('id'); return $results ? $results : array(); }

public function getLastByAuthor($author_id) { $query = $this->_db->getQuery(true); $query->select('*')->from($this->table)->where(“author_id = '$author_id'”)->orderby('created_at DESC'); $this->_db->setQuery($query,0,1); return $this->_db->loadObject(); }

Page 39: Best practices for Joomla extensions developers - Joomla Day 2013

Model - part 3

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php ... public function create($data) { if (!$data) { return 0; }

$data['created_at'] = date('Y-m-d H:i:s');

$query = $this->_db->getQuery(true);

$query->insert($this->table)->columns(array_keys($data))->values(sprintf("'%s'", implode("','", array_values($data)))); $this->_db->setQuery($query);

return false === $this->_db->execute() ? 0 : $this->_db->insertid(); } ...

Page 40: Best practices for Joomla extensions developers - Joomla Day 2013

Model - part 4

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php ... public function delete($ids) { $query = $this->_db->getQuery(true); $query->delete()->from($this->table)->where('id IN '.implode(',', $ids)); return false !== $this->_db->execute(); }

public function getPagination(){ return new JPagination( $this->_getListCount($this->buildQuery()), $this->getState('limitstart'), $this->getState('limit') ); }

private function buildQuery(){ $where = $this->buildWhere(); $query = $this->_db->getQuery(true); return $query->select('*')->from($this->table)->where($where)->orderby('created_at DESC'); } ...

Page 41: Best practices for Joomla extensions developers - Joomla Day 2013

View - part 1

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php...defined('_JEXEC') or die('The way is shut!');

jimport('joomla.application.component.view');

class MyBooksViewBook extends JView{ public function display($tpl = null) { $this->pagination = $this->getModel()->getPagination(); $this->filter_author_id = $this->getModel()->getState('author_id');

$this->books = $this->getModel()->findAll(); $this->authors = $this->getModel('Authors')->getList(); $this->editors = $this->getModel('Editors')->getList();

$this->addToolbar($tpl);

parent::display($tpl); }

Page 42: Best practices for Joomla extensions developers - Joomla Day 2013

View - part 2

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php ... protected function addToolbar($tpl){ $methodName = 'addToolBar' . ucfirst(!$tpl ? 'default' : $tpl); $this->{$methodName}(); }

private function addToolBarDefault(){ JToolBarHelper::title(JText::_('COM_MYBOOKS') . ': ' . JText::_('COM_MYBOOKS_BOOK_LIST')); JToolBarHelper::addNew('create'); JToolBarHelper::preferences('com_mybooks'); JToolBarHelper::divider(); JToolBarHelper::deleteList('COM_MYBOOKS_BOOK_LIST_DELETE_CONFIRM', 'delete'); }

private function addToolBarCreate(){ JToolBarHelper::title(JText::_('COM_MYBOOKS') . ': ' . JText::_('COM_MYBOOKS_BOOK_NEW')); JToolBarHelper::apply('save'); JToolBarHelper::divider(); JToolBarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mybooks'); }}

Page 43: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 44: Best practices for Joomla extensions developers - Joomla Day 2013

Helpers

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Common (usually static) functions not related to a specific object

● Get date / time / external info● Format date and numbers● Build title and/or other HTML snippets● Log/error management● Handle CURL connections

Page 45: Best practices for Joomla extensions developers - Joomla Day 2013

Table classes

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Interface to and from the database

Active Record pattern

● Define table name and unique id● load, store, delete, and so on

Page 46: Best practices for Joomla extensions developers - Joomla Day 2013

Table classes - sample code

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

<?php

class TableBook extends JTable { public function __construct(&$db) { parent::__construct(‘#__books’, ‘id’, $db); } }

Page 47: Best practices for Joomla extensions developers - Joomla Day 2013

Layouts

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page types related to a single view (object)"tmpl" subfolder (template override)

● List● Single item (readonly)● Single item (edit form)● Blog● ...

Page 48: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 49: Best practices for Joomla extensions developers - Joomla Day 2013

System messages

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

$app = JFactory::getApplication();$app->enqueueMessage( $msg, $type )

Page 50: Best practices for Joomla extensions developers - Joomla Day 2013

JError / JException / JLog

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Error handling vs. logging

● JError is deprecated● JException is deprecated● Use PHP Exception class(es)

● JLog is a way to track what's happening

Page 51: Best practices for Joomla extensions developers - Joomla Day 2013

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 52: Best practices for Joomla extensions developers - Joomla Day 2013

Visibility

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Variables and methods

● "var ..." is deprecated since PHP 5.1.2● public : available from other classes● private : available only from the class● protected : available from the class and

from inherited or parent classes

Page 53: Best practices for Joomla extensions developers - Joomla Day 2013

Constants

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● constants instead of variables● drop DS● drop DIRECTORY_SEPARATOR● use Joomla constants:

http://docs.joomla.org/Constants● warning: JPATH_SITE vs JPATH_BASE vs

JPATH_ROOT vs JPATH_ADMINISTRATOR

Page 54: Best practices for Joomla extensions developers - Joomla Day 2013

Versioning

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

● version format: major.minor.release (es. v3.1.5)● variant: v3.1.5 Free, v3.1.5 Pro

Page 55: Best practices for Joomla extensions developers - Joomla Day 2013

And the road goes on and on

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Page 56: Best practices for Joomla extensions developers - Joomla Day 2013

Thanks :)

[email protected]@f_abeni / @gibilogic

http://www.slideshare.net/FrancescoAbeni/best-practices-for-joomla-extensions-developers-25353320

Francesco Abeni for GiBiLogichttp://extensions.gibilogic.com - [email protected]

Feedback please!


Recommended