TomatoCMS in A Nutshell

62
TomatoCMS in A Nutshell www.tomatocms.com

description

Explain TomatoCMS in deep detail

Transcript of TomatoCMS in A Nutshell

Page 1: TomatoCMS in A Nutshell

TomatoCMS in A Nutshell

www.tomatocms.com

Page 2: TomatoCMS in A Nutshell

Table of Content

TomatoCMS : Background

TomatoCMS : Architecture

TomatoCMS : System Design

TomatoCMS : Components

TomatoCMS : Features (Current & New)

Page 3: TomatoCMS in A Nutshell

TomatoCMS : Background

Page 4: TomatoCMS in A Nutshell

Pre-Requisition PHP 5.2 or higher (PHP 5.2 is able to use but need to modify index.php)

MySQL server 5.0 or higher (Default/Recommend)

Background Knowledge Zend Framework – Not required jQuery – Should be MVC/OOP – Strong required PHP – Just familiar with web developer is OK Familiar with any CMS

(ASP.NET or PHP)

Page 5: TomatoCMS in A Nutshell

TomatoCMS Overview

A content management system based-on

OS Independents

Cross-Platforms

Multiple DBs

Web Server (with mod_rewrite)

Not support on IE6.0

Page 6: TomatoCMS in A Nutshell

The concept is …

Problem: Here is what we want to have on website

Page 7: TomatoCMS in A Nutshell

The concept is …

Imagine how it can be created

Page 8: TomatoCMS in A Nutshell

The concept is …

How to define the width of container / widget? => use 960 Grid System (12 columns)

Page 9: TomatoCMS in A Nutshell

The concept is …

How to define the layout? Construct the nested containers …

Page 10: TomatoCMS in A Nutshell

The concept …

How to define the layout? … and widget

Page 11: TomatoCMS in A Nutshell

We made it because …

How to manage layout?• Edit the layout file (XML file) manually• Visual Layout Editor: drag, drop, configure, preview

Demonstration Live-demo

You get the idea !!! 1 page = n * containers1 container = n * containers + m * widgets

Page 12: TomatoCMS in A Nutshell

TomatoCMS : Architecture

Page 13: TomatoCMS in A Nutshell

TomatoCMS : Stack View

3rd PartyCSSTidy

HTML Purifier

JSMin

PclZip ZFDebug

Tomato Library

Tomato_Autoloader

Tomato_Config

Tomato_GlobalKey

Tomato_Hook

Tomato_Language

Tomato_Layout

Tomato_Widget

Tomato_Zip

Tomato_Cache

Tomato Core Module

Standard Modules 3rd Party Modules

Page 14: TomatoCMS in A Nutshell

CSSTidy

HTML Purifier

JSMin

PclZip

ZFDebug

TomatoCMS : Layer View3rd

Par

ty

Tomato Library

Tomato_AutoloaderTomato_Autoloader

Tomato_ConfigTomato_Config

Tomato_GlobalKeyTomato_GlobalKey

Tomato_HookTomato_Hook

Tomato_LanguageTomato_Language

Tomato_LayoutTomato_Layout

Tomato_WidgetTomato_Widget

Tomato_ZipTomato_Zip

Tomato_CacheTomato_Cache

Tomato Core Module

Standard/3rd Party Modules Extension/Add-on

Web Application Framework

General/CommonLibrary

Application Framework

Page 15: TomatoCMS in A Nutshell

TomatoCMS : Stack View 3rd Party Library

Zend Framework 1.0 It’s ASP.NET3.5 Clone

CSSTidy allow CSS Parser and

Optimizer

HTML Purifier 4.1.0 Standards Compliant HTML

Filtering

JSMin Compress JavaScript for PHP

PclZip PHP library that manage ZIP

archives ZFDebug

Debugging code in Zend Framework

Page 16: TomatoCMS in A Nutshell

TomatoCMS : Stack View

Tomato Library Tomato_Autoloader: inherit from

Zend_Loader_Autoloader_ResourceZend_Loader_Autoloader_Resource

Tomato_Cache: manage Cache for Front-end & Back-end

Tomato_Config: read/manage configuration file Tomato_GlobalKey: HTTP logging Tomato_Hook: based class for Hook components Tomato_Language: Manage language packs for each

module/widget Tomato_Layout: Manage layout for front-end Tomato_Widget: Widget abstract class for manage

Widget componts Tomato_Version: Version of TomatoCMS (stable is 2.0.8) Tomato_Zip: Zip file management (refer to PclZip)

Page 17: TomatoCMS in A Nutshell

TomatoCMS : Stack View

Tomato Core Module: Handle & management TomatoCMS

Core Action : Behind the scene Authentication Cache Config Hook Locale

Bundle Feature : Support in back-end & Front-end Dashboard Language Log Message Module Page

Permalink Plugin Privillege Resource Role Rule

Target Template ** User Widget

Page 18: TomatoCMS in A Nutshell

TomatoCMS : Components Modules

Set of codes/container of components (i.e. widgets & hooks)

Inside modules Routing Languages Model ~ View ~ Controller Widgets Plug-in Hook ** Services **

Widgets Snip code for some interaction with user (e.g. display

feed) Inside widgets

Languages View ~ Model (rare)

Page 19: TomatoCMS in A Nutshell

TomatoCMS : Components (2) Plugin

Set of codes that work on “Pre-Dispatch” or “Post-Dispatch”

2 Levels access: - Global (not belong to any modules) Module (depended on module)

Hook Set of codes that work during “Pre-Dispatch” and “Post-

Dispatch” 2 Levels access: -

Global (not belong to any modules) Module (depended on module)

Plugin & Hook can’t access the DB layer

Page 20: TomatoCMS in A Nutshell

TomatoCMS : Naming

File & Class Naming: General Concept File Name : “CamelCase” with the first letter capitalized. Class Name : Mixed folder/sub-folder and separate by “_”

(Underscore) Apply to all components/libraries in TomatoCMS

Components Naming : “module” level Class naming : <Module Name>_<Sub Module>_<Class

Name> File Name: \application\ <Module Name>\<Sub Module>\

<Class Name>.php

Components Naming : Global level Class naming : <Component Type>_<Object Name>_<Type

Name> File Name: \application\ <Component Type>\<Object Name>\

<Type Name>.php Apply on : Hooks, Plug-ins

Page 21: TomatoCMS in A Nutshell

TomatoCMS : Naming

TomatoCMS Libraries (\libraries\Tomato) Start with “Tomato_Tomato_” and no need to inherit from any class Format: “Tomato_<Folder>_<Sub-Folder>_<Class Name>”

e.g. Tomato_Cache_File \libraries\Tomato\Cache\File.php Auto-loading when required to use

TomatoCMS Global Hooks (\ application\hooks) Format: “Hooks_<Hook Name>_Hook”

e.g. Hooks_BadWordsCensor_Hook \application\hooks\badwordscensor\Hook.php

TomatoCMS Global Plugin (\ application\plugins) Format: “Plugins_<Plugin Name>_Plugin”

e.g. Plugins_AdminAccess_Plugin \application\plugin\AdminAccess\Plugin.php

Page 22: TomatoCMS in A Nutshell

TomatoCMS : Naming

TomatoCMS Components (\application\modules) Basic Idea:

Class Name : <Module Name>_<Sub-Folder Name>_<Resource Name>

File Name : \appliation\modules\ <Module Name>\<Sub-Folder Name>\<Resource Name>.php

Controller: <Module Name>_<Resource Name>Controller e.g. Ad_BannerController \application\modules\ad\controllers\

BannerController.php Must extended from “Zend_Controller_Action”

Others Follow above rule Models ~ DAO ~ Interface Services Widgets

Page 23: TomatoCMS in A Nutshell

TomatoCMS : Folder Structure

v2.0.5 v2.0.6v2.0.7v2.0.8 (Stable)

v2.0.9v2.1.0 (Beta)

application

config

hooks

modules core **

moduleplugins

templates

js

libraries

skins

ZF

Tomato

3rd Party

config Remove in v.2.1.0

hooks

modules core **

moduleplugins

templates

js

libraries

skins

ZF

Tomato

3rd Party

In application folder before!

Page 24: TomatoCMS in A Nutshell

TomatoCMS : Why Change?

Easy to add 3rd party files on each module e.g. CSS JavaScript

Access resources (modules/widgets) via URL e.g. the thumbnails of modules/widgets

Change Model layer: “Fat Model, thin Controller” principle Easy to do unit-testing Able to perform other actions e.g. cache data, validate input,

integrate Zend_Form (in the future), etc.

Refer to : http://forum.tomatocms.com/viewtopic.php?f=41&t=937&p=2303&hilit=structure#p2303

Page 25: TomatoCMS in A Nutshell

TomatoCMS : System Design

Page 26: TomatoCMS in A Nutshell

TomatoCMS : System Design

System Overview Understand Zend Framework (ZF) MVC ZF Implementation in TomatoCMS TomatoCMS: Data Access Layer (DAL) TomatoCMS: Model vs DAL

Page 27: TomatoCMS in A Nutshell

System Overview

Request

TomotoCMS

Index.php

Bootstrap.phpBootstrap.php

Load Controller

Load Controller

Response

RenderView

RenderView

Load

Initialize everything

LoadData Object

LoadData Object

Call

Access

Page 28: TomatoCMS in A Nutshell

Understand ZF MVC M-V-C in Zend Framework ZF MVC : Structure ZF MVC : Behavior ZF MVC : Flow

Page 29: TomatoCMS in A Nutshell

M-V-C in ZF Zend_M…?

Model s can be very different : DB, Web-Services, Feeds, … etc.

For example: - Zend_Db (Adaptor Pattern) Zend_Service Zend_Feed Etc.

Zend_Controller Front Controller pattern Zend_Controller_Action

action methods correspond to various actions you wish the controller to be handle

Zend_View template system agnostic Zend_Layout: implement “Two Steps View” pattern

Refer to: http://www.slideshare.net/webholics/mvc-with-zend-framework

Page 30: TomatoCMS in A Nutshell

ZF MVC : StructureZend_ApplicationZend_Application

Zend_Controller_FrontZend_Controller_Front

Zend_Db_Table_AbstractZend_Db_Table_Abstract Zend_Controller_ActionZend_Controller_Action

Zend_ViewZend_View

Page 31: TomatoCMS in A Nutshell

ZF MVC : Behavior

Client

Request dispatch() route()

dispatch()action1Action()

render() action1.php

Response

Page 32: TomatoCMS in A Nutshell

ZF MVC : Flow

The basic Zend Framework workflow of handling a request is fairly simple.

Refer to: http://www.slideshare.net/Tricode/zend-framework-02-mvc-4977880

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 33: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)First the Request is ‘captured’

and aRequest Object is made. The Request Object is just a representation of the Request

itself.

By default the HTTP Request Object is

used. It holds attributes like the URL

and parameters.

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 34: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)

Secondly the Router is called.

The Router checks the Request Object, and alters it depending on registered Routes.

By default the Rewrite Router is used. This Router sets the controller, action and parameters from the URL.

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 35: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)

After the Routing is done, the Dispatch Loop is started.

The Dispatch Loop is performed until the status of the Request Object is set to ‘dispatched’.

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 36: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)The default Dispatcher is the Standard Dispatcher.

This Dispatcher defines controllers as UpperCamelCase classes that end with Controller, and derfines actions as lowerCamelCase methods ending with Action.

FooController::barAction()

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 37: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)

Next, the Action Controller is called.

This is the Controller that you have created yourself.

Like this:

/foo/bar

FooController::barAction()

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 38: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)

The Action Controller often implements a View.

As the View is rendered, the output is added to the Response Object.

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 39: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)After the Action Controller has finished the Dispatcher Loop normally finishes.

If the Action Controller resetted the Dispatched status of the Request Object, the Loop continues, and a new Dispatch is triggered.

For instance you can forward to another Action.

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 40: TomatoCMS in A Nutshell

ZF MVC : Flow (Cont’)At last the Response is sent back.

By default the Response used is the http Response.

Request Router preDispatch

Dispatcher

postDispatch

Actions left?

RequestObject

Action Controller

Send Response

Response Object

Page 41: TomatoCMS in A Nutshell

ZF Implementation in TomatoCMS MVC Structure

Not use : Zend_Db_Table Data Access : implement by Tomato Entity Class

MVC Behavior Same as standard ZF

Bootstrap Initialize useful classes for TomatoCMS

MVC Flow Same as standard ZF

Page 42: TomatoCMS in A Nutshell

ZF MVC Structure : Implementation

Zend_ApplicationZend_Application

Zend_Controller_FrontZend_Controller_Front

Zend_Db_Table_AbstractZend_Db_Table_Abstract Zend_Controller_ActionZend_Controller_Action

Zend_ViewZend_View

Not Used

Page 43: TomatoCMS in A Nutshell

BootStrap : TomatoCMS Heart-beat

Bootstrap

Zend_Application_Bootstrap_BootstrapZend_Application_Bootstrap_Bootstrap

Page 44: TomatoCMS in A Nutshell

BootStrap : Methods _initAutoload() Method

Register class name & auto-loading when required See naming conversion : Auto-Loader will look-up

Class/File conversion rule.

_initRoutes() Method Avoiding standard routing in ZF Routing: define in INI files under folder “\application\modules\<Module Name>\config\routes”

_initSession() Method Initialize session variables for store information Doesn’t allow to access session variable directly.

Page 45: TomatoCMS in A Nutshell

BootStrap : Methods (2) _initActionHelpers() method

Extend “Controllers action” automatically Standard Action-Helper : CSRF protection User-Defined Action-Helper: \Libraries\Tomato\Controller\Action\Helper

_initPlugins() methods Extend “dispatcher” automatically Standard Plug-in loaded when start TomatoCMS

Core_Controllers_Plugin_Init() Tomato_Controller_Plugin_Admin() Tomato_Controller_Plugin_Template() Core_Controllers_Plugin_HookLoader() Core_Controllers_Plugin_Auth() Core_Controllers_Plugin_Permalink() Tomato_Controller_Plugin_LocalizationRoute() Zend_Controller_Plugin_ErrorHandler()

Page 46: TomatoCMS in A Nutshell

TomatoCMS: DAL DAL = Data Access Layer Avoiding “Zend_Db_Table_Abstract” using

“Tomato_Db_Connection” Multiple support 3 kind of DBs

MySQL (with PDO and without PDO) MS-SQL (testing with 2005 & 2008) PostgreSQL Never tested

Page 47: TomatoCMS in A Nutshell

TomatoCMS: DAL structure

Tomato_Db_ConnectionTomato_Db_ConnectionTomato_Db_ConnectionTomato_Db_Connection

Connection(PDO_MySQL)Connection(PDO_MySQL)

Connection(MySQL)

Connection(MySQL)

Connection(PqSQL)

Connection(PqSQL)

Connection(MS-SQL)Connection(MS-SQL)

Tomato_Db_Connection_AbstractTomato_Db_Connection_AbstractTomato_Db_Connection_AbstractTomato_Db_Connection_Abstract

Page 48: TomatoCMS in A Nutshell

TomatoCMS: DAL Architecture

Tomato_Db_ConnectionTomato_Db_ConnectionTomato_Db_ConnectionTomato_Db_Connection

factory(contained $class of Tomato_Db_Connection_AbstractTomato_Db_Connection_Abstract))

getSlaveConnection()getSlaveConnection()getMasterConnection()getMasterConnection()

DB DB

• Purpose for Load-Balancing• Master & Slave : can be the same DB or different DB

• Purpose for Load-Balancing• Master & Slave : can be the same DB or different DB

Page 49: TomatoCMS in A Nutshell

TomatoCMS: Model vs DAO

Tomato_Model_EntityTomato_Model_EntityTomato_Model_EntityTomato_Model_Entity

Tomato_Model_DaoTomato_Model_DaoTomato_Model_DaoTomato_Model_Dao

Tomato_Db_ConnectionTomato_Db_ConnectionTomato_Db_ConnectionTomato_Db_Connection

MyModelMyModelMyModelMyModel

Page 50: TomatoCMS in A Nutshell

TomatoCMS: Model vs DALModel

Data encapsulation Only Properties for mapping table purpose

DAL Contain Business Logic Contain SQL native 1 Class = 1 DB type

Page 51: TomatoCMS in A Nutshell

TomatoCMS: DAL MechanismModel/DAO able to call from- Controller- Services (*)

$conn = Tomato_Db_Connection::factory()->getMasterConnection();$bannerDao = Tomato_Model_Dao_Factory::getInstance()

->setModule('ad') ->getBannerDao();$bannerDao->setDbConnection($conn);……$id = $bannerDao->add($banner);

$conn = Tomato_Db_Connection::factory()->getMasterConnection();$bannerDao = Tomato_Model_Dao_Factory::getInstance()

->setModule('ad') ->getBannerDao();$bannerDao->setDbConnection($conn);……$id = $bannerDao->add($banner);

$conn(Tomato_Db_Connection) DB

$bannerDAO(Tomato_Model_Dao_Factory)

setDBConnection

(Load by adapter type)

(*) Since 2.0.9, Controller won’t declare $conn/$Dao variables anymore. Services Object will handle this case

(*) Since 2.0.9, Controller won’t declare $conn/$Dao variables anymore. Services Object will handle this case

Page 52: TomatoCMS in A Nutshell

TomatoCMS : Components

Page 53: TomatoCMS in A Nutshell

TomatoCMS : Components TypeModule

Services Widgets View-Helpers Action-Helpers

Plug-insHooks

Page 54: TomatoCMS in A Nutshell

TomatoCMS: Components Original idea for components in TomatoCMS

Able to install/Uninstall easier we’ve GUI for configuration : Module ~ Plug-in ~ Hooks ~

Widget Scalability Modular system

Page 55: TomatoCMS in A Nutshell

TomatoCMS: Module Set of codes/container of components

Each module will not interface other modules Each module able to access other modules Each module able to depended on other modules Following “Modular Design” Principle

Inside modules Routing : Mapping URL with Action in Controller Languages : Multi-languages pack (e.g. EN, VN, TH, etc. Model ~ View ~ Controller : Already explain in previous chapter Widgets : Snip codes for interactive with user Plug-in ~ Hook : Explain next section Services : Independent class for re-used in module or between module View-Helper: aka, User-Control (in ASP.NET) reusable code for

view/display

Page 56: TomatoCMS in A Nutshell

TomatoCMS: Module StructureFor example: - “Comments” module

• /config/ contain XML files for identify module• /config/routes defined routing (mapping URL with Controller’s action)• /controllers• /languages contained language pack files (in INI)• /models• /views contained html file for display on GUI• /views/helpers contained view-helper code• /widgets contained widget code/html for display

Page 57: TomatoCMS in A Nutshell

TomatoCMS: Module Configuration

• Easy for installation• Dependency requirements• Able to upload directly to server

Page 58: TomatoCMS in A Nutshell

TomatoCMS: Module’s Components Main Components M~V~C objects Optional Components

Services e.g. get data from DB, calculation logic, business logic, etc.

Widget Some widget can has their own DAO/model

Plug-in/Hook View Helper

Same concept of “User Control” in ASP.NET Able to share between module

Action Helper Similar to “httpModule” in ASP.NET (2.0 or higher) Work automatically when URL has request

Page 59: TomatoCMS in A Nutshell

TomatoCMS: Plug-In Work with “Controller” object

Automatically work Bootstrap has load some plug-ins to work User able to defined plug-ins to load while start-up by

add plug-in name in “application.ini”

Work on 2 events type: - preDispatch

e.g. Auth (in Core module) Admin (in Tomato’s library)

postDispatch Localization ActionCache

Page 60: TomatoCMS in A Nutshell

TomatoCMS: Hook Hook

Working between preDispatch() and postDispatch() 2 types of Hooks: -

Filter Action

Hook Target Declare in “controller” Enabled “extra” flow to work

Page 61: TomatoCMS in A Nutshell

TomatoCMS: Hook (Cont’)e.g. class “Core_AuthController”

Has Hook

?

ExecuteHook

Other lines of codeHook

Target

Page 62: TomatoCMS in A Nutshell

TomatoCMS: Hook Target

Register “Hook” that related to the code