SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
Joomla Extensions
Development Best Practices
Francesco Abeni for GiBiLogic
extensions.gibilogic.com
About me
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Francesco
Abeni
sPrintAddCSSPizzaBox
About this speech
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
The quality of code in the Joomlasphere
No dev course
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Our target
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Good = not bad
Excellent = above the average
Good is enough for today
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
IDE basic features
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● multiple files edit
● syntax highlighting
● index for methods and variables
● autocompletion
● compiler
● versioning / unit testing / phpdoc / ...
Some IDEs
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Versioning
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
http://git-scm.com/book
Standard
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Everything in its right place
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Backend ● administrator
○ components
■ com_componentname
● componentname.php
● controllers
● models
● views
Everything in its right place
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Backend ● administrator
○ components
■ com_componentname
● ...
● tables
● sql
● helpers
● media
○ com_componentname
■ css
■ js
■ img
● components
○ com_componentname
■ componentname.php
■ controllers
■ models
■ views
Everything in its right place
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Frontend
● images
○ com_componentname
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
CSS / JS
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Use existing libraries
JavaScript
● MooTools (since Joomla 1.5)
● JQuery (since Joomla 2.5)
CSS + JavaScript
● Bootstrap (since Joomla 3.x)
CSS out of the door
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Don't:
<br style="clear: both">
<div style="height: 200px">
JS out of the door
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<button id="submit" type=submit" value="ClickMe!" onclick="validateForm()" />
Do:
<button id="submit" type=submit" value="ClickMe!"/>
document.addEvent('load',function(){
$('submit').addEvent('click',function(){
validateForm();
});
});
Don't:
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Joomla framework
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● JDatabase
● JUser
● JSession
● JDocument
● JHTML
● JForm
● JFile
● JUri
● JFolder
● JLog
● JFilterInput
● JError and JException
● JDate
● JUtilities
● JVersion
● JLayout
PHP functions and classes
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● pcre
● trim
● usort
● array_map
● json_encode
● json_decode
● microtime(true)
● glob
● DateTime
● Standard PHP Library
● Exception
● SimpleXML
● TCPDF
● PHPMailer
PHP version
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● 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
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Real objects
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
book writer library
Bad design sample
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● views/search
● views/editbook
● views/book
● views/books
● views/booksauthor
● views/topten
Don't:
The controller
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Filters input
● Decides what to do
● Checks access
● Executes task(s)
● Passes control to the view
The model
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Retrieves object data
● Validates object data
● Gets object data
● Saves object data
● Hates to be mistaken as an helper
The view
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Ask the model for data
● Display object(s)
● Uses layouts!
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Header comment
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
/**
* @version mybooks.php 2013-08-10 15:23:00Z zanardi
* @package GiBi MyBooks
* @author GiBiLogic
* @authorUrl http://www.gibilogic.com
* @authorEmail info@gibilogic.com
* @copyright Copyright (C) 2013 GiBiLogic. All rights reserved.
* @license GNU/GPL v2 or later
* @description Backend entry point
*/
Entry point
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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();
Controller - part 1
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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;
...
Controller - part 2
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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);
}
...
Controller - part 3
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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;
}
Model - part 1
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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'));
}
Model - part 2
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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();
}
Model - part 3
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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();
}
...
Model - part 4
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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');
}
...
View - part 1
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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);
}
View - part 2
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?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');
}
}
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Helpers
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
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
Table classes
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Interface to and from the database
Active Record pattern
● Define table name and unique id
● load, store, delete, and so on
Table classes - sample code
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
class TableBook extends JTable
{
public function __construct(&$db)
{
parent::__construct(‘#__books’, ‘id’, $db);
}
}
Layouts
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Page types related to a single view (object)
"tmpl" subfolder (template override)
● List
● Single item (readonly)
● Single item (edit form)
● Blog
● ...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
System messages
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
$app = JFactory::getApplication();
$app->enqueueMessage( $msg, $type )
JError / JException / JLog
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Error handling vs. logging
● JError is deprecated
● JException is deprecated
● Use basic PHP Exception class
● JLog is a way to track what's happening
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Visibility
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
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
Constants
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● 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
Versioning
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● version format: major.minor.release (es. v3.1.5)
● variant: v3.1.5 Free, v3.1.5 Pro
And the road goes on and on
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Thanks :)
f.abeni@gibilogic.com
@f_abeni / @gibilogic
http://www.slideshare.net/FrancescoAbeni/best-practices-for-joomla-extensions-developers-25353320
Francesco Abeni
http://extensions.gibilogic.com

Weitere ähnliche Inhalte

Was ist angesagt?

Phpforandroid en
Phpforandroid enPhpforandroid en
Phpforandroid en
ivmos
 

Was ist angesagt? (12)

PHP for Android: prototyping Android apps in php
PHP for Android: prototyping Android apps in phpPHP for Android: prototyping Android apps in php
PHP for Android: prototyping Android apps in php
 
IPC 2013 - High Performance PHP with HipHop
IPC 2013 - High Performance PHP with HipHopIPC 2013 - High Performance PHP with HipHop
IPC 2013 - High Performance PHP with HipHop
 
Developing a Joomla 3.x Component using RAD/FOF - Joomladay UK 2014
Developing a Joomla 3.x Component using RAD/FOF - Joomladay UK 2014Developing a Joomla 3.x Component using RAD/FOF - Joomladay UK 2014
Developing a Joomla 3.x Component using RAD/FOF - Joomladay UK 2014
 
Phpforandroid en
Phpforandroid enPhpforandroid en
Phpforandroid en
 
Laravel でやってみるクリーンアーキテクチャ #phpconfuk
Laravel でやってみるクリーンアーキテクチャ #phpconfukLaravel でやってみるクリーンアーキテクチャ #phpconfuk
Laravel でやってみるクリーンアーキテクチャ #phpconfuk
 
BDD - Writing better scenario
BDD - Writing better scenarioBDD - Writing better scenario
BDD - Writing better scenario
 
Android is going to Go! Android and Golang
Android is going to Go! Android and GolangAndroid is going to Go! Android and Golang
Android is going to Go! Android and Golang
 
An introduction to_golang.avi
An introduction to_golang.aviAn introduction to_golang.avi
An introduction to_golang.avi
 
第26回PHP勉強会
第26回PHP勉強会第26回PHP勉強会
第26回PHP勉強会
 
Debugging Effectively - Frederick Web Tech 9/6/16
Debugging Effectively - Frederick Web Tech 9/6/16Debugging Effectively - Frederick Web Tech 9/6/16
Debugging Effectively - Frederick Web Tech 9/6/16
 
Pluggin creation
Pluggin creationPluggin creation
Pluggin creation
 
Debugging Effectively
Debugging EffectivelyDebugging Effectively
Debugging Effectively
 

Andere mochten auch

AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...
AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...
AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...
Mark Smith
 

Andere mochten auch (20)

Annonce jfim ba 2017
Annonce jfim ba 2017Annonce jfim ba 2017
Annonce jfim ba 2017
 
Introduccion a devops y devsecops
Introduccion a devops y devsecopsIntroduccion a devops y devsecops
Introduccion a devops y devsecops
 
Déclaration du WANEP à l'occasion du 8 mars 2017
Déclaration du WANEP à l'occasion du  8 mars 2017Déclaration du WANEP à l'occasion du  8 mars 2017
Déclaration du WANEP à l'occasion du 8 mars 2017
 
Urge la aprobación del presupuesto de elecciones 2018 presentado por el Tribu...
Urge la aprobación del presupuesto de elecciones 2018 presentado por el Tribu...Urge la aprobación del presupuesto de elecciones 2018 presentado por el Tribu...
Urge la aprobación del presupuesto de elecciones 2018 presentado por el Tribu...
 
Lean Learning Academy overview
Lean Learning Academy overviewLean Learning Academy overview
Lean Learning Academy overview
 
State-of-the-Art-Cardiology-Practice: Management OF Acute Coronary Syndrome P...
State-of-the-Art-Cardiology-Practice: Management OF Acute Coronary Syndrome P...State-of-the-Art-Cardiology-Practice: Management OF Acute Coronary Syndrome P...
State-of-the-Art-Cardiology-Practice: Management OF Acute Coronary Syndrome P...
 
15 Teaching Ideas for 2017
15 Teaching Ideas for 201715 Teaching Ideas for 2017
15 Teaching Ideas for 2017
 
Lessons Learned From Five of Marketing's Top Minds - starring Robert Rose, An...
Lessons Learned From Five of Marketing's Top Minds - starring Robert Rose, An...Lessons Learned From Five of Marketing's Top Minds - starring Robert Rose, An...
Lessons Learned From Five of Marketing's Top Minds - starring Robert Rose, An...
 
Integrating React.js Into a PHP Application
Integrating React.js Into a PHP ApplicationIntegrating React.js Into a PHP Application
Integrating React.js Into a PHP Application
 
Organisational behavior
Organisational behavior Organisational behavior
Organisational behavior
 
Chapter 0: Fluxtrol Introduction to Induction Heating Technology and Magnetic...
Chapter 0: Fluxtrol Introduction to Induction Heating Technology and Magnetic...Chapter 0: Fluxtrol Introduction to Induction Heating Technology and Magnetic...
Chapter 0: Fluxtrol Introduction to Induction Heating Technology and Magnetic...
 
The Be-All, End-All List of Small Business Tax Deductions
The Be-All, End-All List of Small Business Tax DeductionsThe Be-All, End-All List of Small Business Tax Deductions
The Be-All, End-All List of Small Business Tax Deductions
 
Scotland Scrap Of Paper
Scotland Scrap Of PaperScotland Scrap Of Paper
Scotland Scrap Of Paper
 
CVCK 2016 発表資料 / おしゃべりプログラミング 代表 中村圭介
CVCK 2016 発表資料 / おしゃべりプログラミング 代表 中村圭介CVCK 2016 発表資料 / おしゃべりプログラミング 代表 中村圭介
CVCK 2016 発表資料 / おしゃべりプログラミング 代表 中村圭介
 
Umbrella Fabric/IXP SDN OpenFlow: The TouiX to TouSIX Experience
Umbrella Fabric/IXP SDN OpenFlow: The TouiX to TouSIX ExperienceUmbrella Fabric/IXP SDN OpenFlow: The TouiX to TouSIX Experience
Umbrella Fabric/IXP SDN OpenFlow: The TouiX to TouSIX Experience
 
Sectoral Overview and Investment Opportunities
Sectoral Overview and Investment OpportunitiesSectoral Overview and Investment Opportunities
Sectoral Overview and Investment Opportunities
 
AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...
AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...
AusNOG 2013 - The Rapid Rise of the Mobile Multihomed Host, and What it Might...
 
6 b historia-zigzag-e
6 b historia-zigzag-e6 b historia-zigzag-e
6 b historia-zigzag-e
 
Beyond Cigarettes: The Risks of Non-Cigarette Nicotine Products and Implicati...
Beyond Cigarettes: The Risks of Non-Cigarette Nicotine Products and Implicati...Beyond Cigarettes: The Risks of Non-Cigarette Nicotine Products and Implicati...
Beyond Cigarettes: The Risks of Non-Cigarette Nicotine Products and Implicati...
 
Electrophoresis presentation
Electrophoresis presentationElectrophoresis presentation
Electrophoresis presentation
 

Ähnlich wie Best practices for joomla extensions developers

Behat Workshop at WeLovePHP
Behat Workshop at WeLovePHPBehat Workshop at WeLovePHP
Behat Workshop at WeLovePHP
Marcos Quesada
 
Francesco abeni joomla_extensions_best_practices
Francesco abeni joomla_extensions_best_practicesFrancesco abeni joomla_extensions_best_practices
Francesco abeni joomla_extensions_best_practices
Francesco Abeni
 
Benefit of CodeIgniter php framework
Benefit of CodeIgniter php frameworkBenefit of CodeIgniter php framework
Benefit of CodeIgniter php framework
Bo-Yi Wu
 

Ähnlich wie Best practices for joomla extensions developers (20)

Last Month in PHP - June 2016
Last Month in PHP - June 2016Last Month in PHP - June 2016
Last Month in PHP - June 2016
 
Behat Workshop at WeLovePHP
Behat Workshop at WeLovePHPBehat Workshop at WeLovePHP
Behat Workshop at WeLovePHP
 
Refactoring to GO modules
Refactoring to GO modulesRefactoring to GO modules
Refactoring to GO modules
 
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
Creating a Smooth Development Workflow for High-Quality Modular Open-Source P...
 
Francesco abeni joomla_extensions_best_practices
Francesco abeni joomla_extensions_best_practicesFrancesco abeni joomla_extensions_best_practices
Francesco abeni joomla_extensions_best_practices
 
Rapid application development using Akeeba FOF and Joomla 3.2
Rapid application development using Akeeba FOF and Joomla 3.2Rapid application development using Akeeba FOF and Joomla 3.2
Rapid application development using Akeeba FOF and Joomla 3.2
 
Benefit of CodeIgniter php framework
Benefit of CodeIgniter php frameworkBenefit of CodeIgniter php framework
Benefit of CodeIgniter php framework
 
JUG Utrecht 2013 - Have you tried turning it off and on again? Problemen oplo...
JUG Utrecht 2013 - Have you tried turning it off and on again? Problemen oplo...JUG Utrecht 2013 - Have you tried turning it off and on again? Problemen oplo...
JUG Utrecht 2013 - Have you tried turning it off and on again? Problemen oplo...
 
Deploy a PHP App on Google App Engine
Deploy a PHP App on Google App EngineDeploy a PHP App on Google App Engine
Deploy a PHP App on Google App Engine
 
EuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears TrainingEuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears Training
 
Testing with Codeception
Testing with CodeceptionTesting with Codeception
Testing with Codeception
 
web2py:Web development like a boss
web2py:Web development like a bossweb2py:Web development like a boss
web2py:Web development like a boss
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
 
API Details For Ascitconsultancyservices.com
API Details For Ascitconsultancyservices.comAPI Details For Ascitconsultancyservices.com
API Details For Ascitconsultancyservices.com
 
Api details for american syscorp
Api details for american syscorpApi details for american syscorp
Api details for american syscorp
 
Introduction to Magento 2 module development - PHP Antwerp Meetup 2017
Introduction to Magento 2 module development - PHP Antwerp Meetup 2017Introduction to Magento 2 module development - PHP Antwerp Meetup 2017
Introduction to Magento 2 module development - PHP Antwerp Meetup 2017
 
Magento++
Magento++Magento++
Magento++
 
drone continuous Integration
drone continuous Integrationdrone continuous Integration
drone continuous Integration
 
Behat internals for advanced usage. Symfony Camp 2016
Behat internals for advanced usage. Symfony Camp 2016Behat internals for advanced usage. Symfony Camp 2016
Behat internals for advanced usage. Symfony Camp 2016
 
Php through the eyes of a hoster: PHPNW10
Php through the eyes of a hoster: PHPNW10Php through the eyes of a hoster: PHPNW10
Php through the eyes of a hoster: PHPNW10
 

Kürzlich hochgeladen

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Kürzlich hochgeladen (20)

Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

Best practices for joomla extensions developers

  • 1. Joomla Extensions Development Best Practices Francesco Abeni for GiBiLogic extensions.gibilogic.com
  • 2. About me Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Francesco Abeni sPrintAddCSSPizzaBox
  • 3. About this speech Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com The quality of code in the Joomlasphere
  • 4. No dev course Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 5. Our target Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Good = not bad Excellent = above the average Good is enough for today
  • 6. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 7. IDE basic features Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● multiple files edit ● syntax highlighting ● index for methods and variables ● autocompletion ● compiler ● versioning / unit testing / phpdoc / ...
  • 8. Some IDEs Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 9. Versioning Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com http://git-scm.com/book
  • 10. Standard Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 11. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 12. Everything in its right place Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Backend ● administrator ○ components ■ com_componentname ● componentname.php ● controllers ● models ● views
  • 13. Everything in its right place Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Backend ● administrator ○ components ■ com_componentname ● ... ● tables ● sql ● helpers
  • 14. ● media ○ com_componentname ■ css ■ js ■ img ● components ○ com_componentname ■ componentname.php ■ controllers ■ models ■ views Everything in its right place Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Frontend ● images ○ com_componentname
  • 15. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 16. CSS / JS Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Use existing libraries JavaScript ● MooTools (since Joomla 1.5) ● JQuery (since Joomla 2.5) CSS + JavaScript ● Bootstrap (since Joomla 3.x)
  • 17. CSS out of the door Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Don't: <br style="clear: both"> <div style="height: 200px">
  • 18. JS out of the door Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <button id="submit" type=submit" value="ClickMe!" onclick="validateForm()" /> Do: <button id="submit" type=submit" value="ClickMe!"/> document.addEvent('load',function(){ $('submit').addEvent('click',function(){ validateForm(); }); }); Don't:
  • 19. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 20. Joomla framework Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● JDatabase ● JUser ● JSession ● JDocument ● JHTML ● JForm ● JFile ● JUri ● JFolder ● JLog ● JFilterInput ● JError and JException ● JDate ● JUtilities ● JVersion ● JLayout
  • 21. PHP functions and classes Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● pcre ● trim ● usort ● array_map ● json_encode ● json_decode ● microtime(true) ● glob ● DateTime ● Standard PHP Library ● Exception ● SimpleXML ● TCPDF ● PHPMailer
  • 22. PHP version Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● 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
  • 23. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 24. Real objects Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com book writer library
  • 25. Bad design sample Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● views/search ● views/editbook ● views/book ● views/books ● views/booksauthor ● views/topten Don't:
  • 26. The controller Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Filters input ● Decides what to do ● Checks access ● Executes task(s) ● Passes control to the view
  • 27. The model Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Retrieves object data ● Validates object data ● Gets object data ● Saves object data ● Hates to be mistaken as an helper
  • 28. The view Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Ask the model for data ● Display object(s) ● Uses layouts!
  • 29. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 30. Header comment Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php /** * @version mybooks.php 2013-08-10 15:23:00Z zanardi * @package GiBi MyBooks * @author GiBiLogic * @authorUrl http://www.gibilogic.com * @authorEmail info@gibilogic.com * @copyright Copyright (C) 2013 GiBiLogic. All rights reserved. * @license GNU/GPL v2 or later * @description Backend entry point */
  • 31. Entry point Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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();
  • 32. Controller - part 1 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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; ...
  • 33. Controller - part 2 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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); } ...
  • 34. Controller - part 3 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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; }
  • 35. Model - part 1 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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')); }
  • 36. Model - part 2 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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(); }
  • 37. Model - part 3 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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(); } ...
  • 38. Model - part 4 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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'); } ...
  • 39. View - part 1 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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); }
  • 40. View - part 2 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?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'); } }
  • 41. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 42. Helpers Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com 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
  • 43. Table classes Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Interface to and from the database Active Record pattern ● Define table name and unique id ● load, store, delete, and so on
  • 44. Table classes - sample code Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php class TableBook extends JTable { public function __construct(&$db) { parent::__construct(‘#__books’, ‘id’, $db); } }
  • 45. Layouts Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Page types related to a single view (object) "tmpl" subfolder (template override) ● List ● Single item (readonly) ● Single item (edit form) ● Blog ● ...
  • 46. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 47. System messages Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com $app = JFactory::getApplication(); $app->enqueueMessage( $msg, $type )
  • 48. JError / JException / JLog Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Error handling vs. logging ● JError is deprecated ● JException is deprecated ● Use basic PHP Exception class ● JLog is a way to track what's happening
  • 49. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 50. Visibility Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com 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
  • 51. Constants Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● 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
  • 52. Versioning Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● version format: major.minor.release (es. v3.1.5) ● variant: v3.1.5 Free, v3.1.5 Pro
  • 53. And the road goes on and on Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  • 54. Thanks :) f.abeni@gibilogic.com @f_abeni / @gibilogic http://www.slideshare.net/FrancescoAbeni/best-practices-for-joomla-extensions-developers-25353320 Francesco Abeni http://extensions.gibilogic.com