DEPRECATION WARNING

This documentation is not using the current rendering mechanism and is probably outdated. The extension maintainer should switch to the new system. Details on how to use the rendering mechanism can be found here.

MVC

Author:Robert Lemke
Created:2006-03-14T17:06:18
Changed:2009-05-14T20:51:26
Classification:MVC and DDD Framework for 4.x
Email:poetzinger@aoemedia.de
Info 2:
Info 3:
Info 4:

MVC

Extension Key: mvc

Copyright 2009 AOE media GmbH

This document is published under the Open Content License

available from http://www.opencontent.org/opl.shtml

The content of this document is related to TYPO3

- a GNU/GPL CMS/Framework available from www.typo3.com

Table of Contents

MVC 1

Introduction 2

What does it do? 2

About this extension 2

Motivation 2

Advantages of MVC / MVP 3

Quickstart: building new MVC based extensions 3

The example extension “mvcnews” 4

Folderstructure of a MVC based extensions 4

Elements of the MVC Framework 5

Configuration 5

Views 5

Widgets 5

View Helpers 5

LinkCreator 5

Link 5

Label 6

FieldRenderer 6

tcaFieldRenderer 6

formElementRenderer 6

Model 6

“domain” package 6

“ddd” package 7

Presentation model and presentation logic 7

Modifiers 8

Filter and Validators 8

Short Introduction to MVC 8

Model: 8

View: 9

Controller: 9

View details: 9

view helper: 9

composite view: 9

transform view 10

What should I take care of? 10

Setup 10

Supported configuration 10

Insides 11

Request and Dispatching in general 11

Finding the relevant controller (request building) and dispatching: 11

Global Controllers 11

How controllers are executed in TYPO3: 12

Adding Plugins and Ajaxsupport 12

Simple Plugin 12

Switched Plugin 12

Adding controllers as typoscript object 13

AJAX Page Types 13

AJAX with eID 14

Hooks 14

Introduction

What does it do?

MVC is a TYPO3 extension which provides a basic framework on top of TYPO3 4.x that enables building enterprise web applications. It includes:

A MVC Framework for TYPO3 4.x, based on the general FLOW3 concept (different naming). Additional the following stuff:

presentation model concept

TYPO3 specific view helpers

TYPO3 specific simple configuration object (that supports initialisation from typoscript and flexforms)

tx_mvc_extMgm for adding the required typoscript to use MVC Plugins

several frontControllers for adding and executing MVC plugins in TYPO3

simple and flexible form rendering concept

base classes for model objects and repositories. (inspired by DDD - still under refactoring)

filter and validators for adding security to your application

abstraction from common TYPO3 functionalities.

more tools and system classes that offers framework like functionality for building enterprise web applications.

About this extension

The extension is developed and maintained by AOE media GmbH.

It is developed because of the requirement to build clean and scalable web applications in TYPO3 4.x and the need to smaller the gap between other web frameworks especially FLOW3.

Motivation

img-1 Screenshot of the example extension “objects” showing a list of records with search and pagination. The pagination supports unobtrusive ajax.

img-2

Screenshot of the controller with the default “showlistAction”, the “ajaxshowlistAction” and the “showdetailAction” that belongs to the output above. In this case a composite view is composed together with the sub views: search form, pagination, list. Each with its own model: a model for the search form and a collection of records that are rendered in the list. That's all!

Advantages of MVC / MVP

  • increase testability (unit tests at least for domain layer, also unittests for controllers and views are possible)
  • focus on a clean and maintainable (domain) model without thinking much of the concrete view requirements.
  • Better support fo team development
  • change- and exchangeable views
  • reuse of models
  • defines the base structure of typical applications and offers the base for using other helpful patterns in your application.

Quickstart: building new MVC based extensions

1) Start normal with the kickstarter and create your tables etc. there. But do not create frontend plugins. Once the basis extension is kickstarted several steps are required to have a working MVC plugin:

2) Add a folder “controller” and add a class with the following naming convention “class.<tx-extensionkey>_controller_<controllername>.php” that extends the action controller .

Each controller has <actionname>Action() methods that are automatically called if a argument "action" is found

Each controller has to set some member variables like: argumentNamespace; extensionKey; defaultActionMethodName.

Each action has his view autoloaded and should use $this->view (its a default empty view or the view detected by a naming convention)

This is an example code:

/**
 * Default Controller for the 'objects' extension.
 *
 */
class tx_objects_controller_default extends tx_mvc_controller_action {

        /**
         * @var        string
         */
        protected $extensionKey = 'objects';

        /**
         * @var        string
         */
        protected $defaultActionMethodName = 'showlistAction';

        /**
         * @var        string
         */
        protected $argumentsNamespace = 'objects';



        public function showlistAction() {
        return $this-view->render();
        }

3) If you want a plugin (you normally want this). The controller needs to be registered as a plugin, therefore place the following code to ext_localconf.php

$pluginListTypeKey=$_EXTKEY.'_plugin';
tx_mvc_extMgm::addSimplePluginController($_EXTKEY,$pluginListTypeKey,'default');

That will add the configuration for a new plugin to TYPO3.

Also you are required to add this to ext_tables.php:

$pluginListTypeKey=$_EXTKEY.'_plugin';
t3lib_extMgm::addPlugin(array('LLL:EXT:objects/locallang_db.xml:tt_content.list_type_pi1',$pluginListTypeKey),'list_type');

t3lib_extMgm::addStaticFile($_EXTKEY,"configuration/static/","Objects Outputs");

4) If you want to use the autoloading of view, then create a view for your action in the folder “view” following this namingconvention: <controllername>/class.<tx- extensionkey>_view_<controllername>_<actionname>.php

This enables you to access the initialised view object in the action with $this->view.A minimalistic view could look like:

class tx_objects_view_default_showDetail extends tx_mvc_view_abstractView {
        public function render() {
                return 'Hello World';
        }
}

5) Then you should already be able to use a plugin with the “hello world” output.

6) Now add something useful :-). This can start with implementing your model design in the folder “domain”, if useful with the use of the abstract Classes the extension provides. After the functionality of your domain layer is checked with Unittests you are ready to use them in your controller and pass them to the view.

The example extension “mvcnews”

There is the extension “mvcnews” that uses most of the features – have a look at that.

It also shows the unobtrusive AJAX implementation – jquery is required in the FE to see it working – but any other JavaScript framework is also OK.

Its currently in forge.

Folderstructure of a MVC based extensions

  • configuration (Place to add the static typoscript code. Place to add the flexform configuration for your plugins)

  • controller (folder that has the controllers. Namingconvention: class.<extensionprefix>_controller_<controllername>.php)

  • domain (the place where to add your domainlogik and domainobjects (DDD)). Suggested subfolders:

    • model

      <optional extension sepcific packages>

    • service

  • presentation (presentationmodels (if any))

  • res/templates (default templates for the templateviews)

  • view

    • folder that includes the views in subfolders:
    • subfolders = controllername
    • namingconvention: <extensionprefix>_view_<controllername>_<actionname>.php
  • system (System layer of your extension with useful classes that don't belong to the Domain layer)

Elements of the MVC Framework

Configuration

In your controller as well in your views you have a configuration object in the membervariable $this->configuration.

It has the typoscript and flexformconfiguration loaded. You can access the configuration by path:

$this->configuration->get('listView.itemsPerView');

Views

If you want to create a new view you can extend your concrete view from the abstractView class and implement your specific render() method.Or you use the phpTemplateView and put your “renderlogik” inside of a template file.

Other views (like a advanced Markerview or the upcoming Fluid view is planned)

Widgets

Are ready build views that understands a certain model and renders it. Currently we have two views, both can be controlled using a own php template (instead of the default):

  • pagination: Use this to render pagination
  • list: You can use this to render a List (the model needs to be a List (ArrayObject) of ArrayObjects)

View Helpers

Viewhelpers are objects that are available in the views. They help to solve common rendering tasks like getting links or formatting strings.

You can get a viewhelper by asking the view:

$this->getViewHelper('tx_mvc_viewHelper_label');

In the phpTemplateView you have already available viewhelpers in membervariables:

$this->labels=$this->getViewHelper('tx_mvc_viewHelper_label');
$this->fieldRenderer=$this->getViewHelper('tx_mvc_viewHelper_fieldRenderer');
$this->linkCreator=$this->getViewHelper('tx_mvc_viewHelper_linkCreator');
LinkCreator

Is a kind of factory for the “link” viewhelper. Ask this “linkCreator” to get a new instance of a link object. You should use this linkCreator – because the linkobject it return is already initialised with the current controller argument namespace, the ajax settings etc.

There are different Methods to get predefined linkObjects. Examples:

$linkObject=$this->linkCreator->getActionLink('label','showdetail');

$linkObject=$this->linkCreator->getAjaxActionLink('ajaxshowdetail');
Label

Is initialised by the locallang file (default location view/locallang.xml) and should be ask in order to get languagelabels.

Example:

$this->pi_getLL('mvc.widget.previous_page');

or

$this->labels->get('mvc.widget.previous_page')
FieldRenderer

Is currently unfinished and has methods to render strings as something. E.g.:

$fieldRenderer->asDate(time());
$fieldRender->asRTE($mytext);
$fieldRender->asImage(...)
...
tcaFieldRenderer

A special fieldRenderer that intelligent decides with the help of the TCA configuration of a field how to render it for the frontend. This viewHelper is also used for the TCA presentation model and isn't finished yet.

formElementRenderer

Methods for getting formular elements like selectboxes, radioelement or inputelement. You can build your own selectboxes within a view or you can use the presentation models for formulars and formularelements if the forms are more complex.

Examples:

$this->formElementRenderer->renderElement($this->formModel->getElementByName('objectsformsended'));

$this->formElementRenderer->renderMVCHiddenFields();

$this->formElementRenderer->getSubmitButton();

$this->formElementRenderer->getClosingForm();

Model

Inside the mvc extension you will find two packages, that supports you building your model. One thing before – there is no need to use one of this concepts, you can also create your completely own model classes that supports the needs of your application.

However, this extension ships with two packages:

  • “ddd” package: The classes in this package belongs to the first concepts, they are mainly nice wrapper classes for a relational table. See below for a detailed description. You can use this for TYPO3 or non TYPO3 tables.
  • “domain” package: This package is part of the new persitence concept in the extension:
    • It uses functionality of the system “persitence” package in order to build and get objects from the database
    • It uses Dependency Injection
    • The persitence concept allows to dynamically resolve relations to other tables.
    • Its still work in progress
    • It supports only TCA Tables
“domain” package

This package is currently work in progress and does not have full feature support. This is what currently works:

  • load objects from database

    support for 1:n and n:1 relantion

  • no storage or update currently implemented

  • not all relationtypes currently implemented

This package contains abstract basis classes, that can be used to build your domain model on top of TYPO3 TCA tables:

  • tx_mvc_domain_abstractObject: Abstract Baseclass for your entities.
  • tx_mvc_domain_abstractRepository: Abstract Repository as entry to your domain model. It provides common repository methods like “findById”, “findAll” und “findCollectionByProperty”
  • tx_mvc_domain_objectCollection: simple Object Collection, that is used if a method returns a collection of objects

Lets start with a short example. Assume that we have a “article” table, that has a “title” and a “category” where it belongs to. Category is a seperate table.

1. register your new domain class to the dependency injection manager class (Inverse of Control Manager):

tx_picocontainer_IoC_manager::registerPrototype('tx_mvcnews_domain_model_article');

2. tell the persitence framework for which table this class is responsible:

//register this class to the class2TableMapping object
tx_picocontainer_IoC_manager::getSingleton('tx_mvc_system_persitence_class2TableMapping')->addMapping('tx_mvcnews_article','tx_mvcnews_domain_model_article');
  1. write your class code and add meaningful methods
/**
 * Domain Class "article"
 *
 * @author      Daniel Pötzinger
 */
class tx_mvcnews_domain_model_article extends tx_mvc_domain_abstractObject {

}

Now you can use your object:

$articleRepository = tx_picocontainer_IoC_manager::getSingleton ( 'tx_mvcnews_domain_model_articleRepository' );
$article=$articleRepository->findById(1);
$article->hasTitle();
$article->getTitle();
$article->setTitle('my title');
$categoryObject=$article->getCategory();
$categoryObject->getTitle();

You can see what the persitence concept and the domain package can do for you:

  • magic methods (has/set/get)Nameofthedatabasefield
  • magic resolving of relations, depending on the TCA configuration both ways are supported
    • lazy loading (aggregate or simple relation)
    • preloading (composition)
“ddd” package

There are basic model classes. they are more a data wrapper – wrapping a single row of a table into an object. For complex applications you have to create your own model classes with behaviour and business logic. For the common data wrapping obejcts – that needs a row of data from a database table you can use the classes inside of the mvc framework:

  • tx_mvc_abstractDbObject – a simple object that is constructed with a row of any table. You can then access all properties with methods like $obj->getTitle() and $obj->setTitle('new title')
  • tx_mvc_abstractRepository – a simple repository – use this to get (find methods) add(), save() and update() objects
  • tx_mvc_abstractTCAObject - similar to the abstractDbObject – but it has some more nice functions based on the TCA configuration of the table.
  • tx_mvc_abstractTCAObjectRepository - A repository to find, add(), save() or update() TCAobjects. It has build in functionality to use workspace and language overlays before returning an object.

Some notes on the concept: Each of that abstract domain classes uses functions from a system layer to access the persistence data in the database.

Presentation model and presentation logic

There are requirements in your application that requires some logic in the view. For example: “the most recent articles should have a red headline” or “the previewimage should have a watermark” or ...

The question is where to put them?

Following a clean domain driven style there is the rule that you never should put logic that is only required for presentation issues inside of the domain layer.

One concept of adding view-specific-logic to models before passing them to the view is to wrap them with a presentation model. So a presentation model is a model that is outside of your domain layer.

In the mvc framework a TCA presentation model can act as a wrapper for domain objects and offers this features:

  • the content returned from the presentation model is already formatted according to the TCA informations. (for example: a timestamp is returned as formatted date; a imagefield as <img> tag and so on.)
  • you can add fields and “getter” methods that are only available in the presentation model. You can use this for resolving relations or add view specific logic. (methods like “getSpeakingCategoryName()” or “getHeadlineColorCode()”.
  • You can reuse this presentation models in different views (e.g. single, list ...)

There is also a package “form” that has some simple form classes that are useful to build forms, validate them...

(Alternatives: Once the new form concept planned for TYPO3 4.4 is available you can also use this. You also can use Zend_Form or Quickform.)

More presentation logic in state of the art web applications is part of the client javascript code. Together with AJAX functionality the javascript code often is something like a presenter on the client side: listing on events → doing some ajax calls and updating the view.

Modifiers

Is a object that is able to modify field values based on some configuration. In the framework this can be used to modify values of the data wrapping objects right before the content is returned.

The frameworks allows to inject Modifiers into abstractDbObject per typoscript configuration:

plugin.tx_aoetirepresenter_controller_tirePresenter.configuration {

        modifier {

# Configure the default view of the controller "tirePresenter"

           tx_aoetirepresenter_view_tirePresenter_default {

                               # Register a "TypoScript" fieldRenderer on the tire domain
                        tx_aoetirepresenter_domain_tire = typoScript
                        tx_aoetirepresenter_domain_tire.fields {

                                        # define field configuration on domain tire
                                title = TEXT
                                title {
                                        field = title
                                        wrap = <h1>|</h1>
                                }
                        }
              }

      }
}

Then in your controller call:

$this->doInjectModifierIntoDomainObject($TireCollection) // this method accept ArrayObject as collection of abstractDbObject or just a simple abstractDbObject

That will automatically detect if a modifier is configured for the object, and sets the configuration for the view.

Therefore use modifiers as an alternative to presentation objects. Be sure the modifier injection is done right before you pass the object to the view. Also be sure that you don't do other things with the object after passing it to the view – or at least be aware that the values returned by the object are modified according to the injected modifier.

Filter and Validators

Filters: Objects that filters values. E.g. a text filter ensures that any input is filtered to text. Filters are useful to secure arguments for example.

Validators: Checks values against certain rules. E.g. a TextPlainValidator can be used to validate that a value is really plain text (no html etc). Use this for tests, checking invariants or the formElements for example.

$validator=tx_mvc_validator_factory::getTextPlainValidator()
if ($validator->isValid('<b>test</b>')) {
  //value not validated
}

Short Introduction to MVC

MVC intention is to build (Web)-Applications in a modular way, where we have 3 general parts responsible for creating the output and allowing the interaction with the user:

Model:

In the context of the MVC the model has the data that is required to render things in the view. So it represents the data that are required for rendering. It also takes over the operation related to the domain.

The model object can be for example a domain-object (see Domain Driven Design) or it can be a presentation model (see below).

In big application the domain model is used to do something and get the data.

View:

takes over the display of the applications state.

Controller:

It glues together Model and View, it controls the user interaction with the model and the view. (Thin layer that connects models with there views)

The common controller in use is the ActionController, technically that means its a controller that implements certain actions. In this framework all public methods in such a ActionController should end with "Action". Typically the controller has a default action that is processed if no other action is requested.

The MVC framework decides which action to call – of course based on the “actions” a user performed in the UI (for example a user clicked some special link in the UI).

What is part of a action method? In the action methods itself some queries and/or commands in the underlying (domain) models are done. Then typically the correct models are passed to the view and the view is responsible for creating the required output.

A controller in this MVC framework has mainly two objects where it can read the stuff that is required for his actions: configuration and arguments .

  • $this->configuration->get(<somepath>): Configuration object has all the configuration for that controller (the framework loads this for you – its loaded from typoscript + flexform automatically)
  • $this->arguments: The arguments has the arguments for that controllers (the _GET and _POST vars that belongs to the argumentsNamespace of the controller). This arguments has to be validated and secured still! You can access all arguments in the array $this->arguments.

View details:

A view takes care of *„rendering the pixels on the screen“* and should be as dump as possible. Typically a view class understands one or more model(s) and outputs the information of that model. ( A view is not allowed to write in the model. ) So the view is aware of the model and knows how to read the data out of it – but never the model should know something about the view!The view needs to know the model it wants to render, therefore in the action something like this can be written:

$view->setModel($model);

Speaking setter methods in your view helps understanding the code.

Typically you will have a „Template View“, then you can set the template to use before calling the render() method of the view.

$view->setTemplate('mytemplate.html');
return $view->render();

To help you with rendering the output there are some concepts:

view helper:

Are objects that contains common helper methods for views. For example:

  • helping generation links
  • helping rendering strings
  • helping getting language labels
  • helping generating formulars
  • some custom helpers that have reoccurring snippets (like buttons, special icons)

In this extension viewHelpers are “injected” to the view, there will be a Hook that allows you to inject custom viewHelpers.

composite view:

Doublicate of code is always something smelly – so for example you may always require the same pagebrowser – then you want to write the rendering for this in just one place. “view helpers” are one way to deal with that. The composite view pattern is another.

This is a view that composes several other views. For example imagine a typical listview: You have a search form, then a pagebrowser then a table with the list of items. So you can imagine this view as a composition of several SubViews (a pageBrowserView a SearchView and a ListView).

If you want to have a composite view – just use one of the view classes and add some methods to register your “subviews”. See the example extension for an example.

transform view

Another type of view is transformview – as the name says: It simply takes input and transforms it to have a different output. (For example a htmlToPDFTransformView).

In this extension there is a special interface for transformViews.

What should I take care of?

  • Its just a MVC framework that offers you the possibility to split view and business logic. It does not make your application or extension maintainable and clean just by using this pattern:
    • the model is the hearth: focus on a clean and understandable design in the model layer (e.g. using concepts from domain driven design: http://www.typo3-media.com/blog/domain-driven-design- introduction.html )
    • the view logic needs to be understandable and free of duplicate code (use some of the explained concepts)
    • The splitting in model and view is perfect to start with Test Driven Development: Build test cases for your model classes using the extension “phpunit”
  • Its still work in progress – we already consider this extension very useful but maybe some parts will change because of further refactoring or changed concepts.

Setup

Setup of tx_mvc_simplePluginFrontController->main:

::

a

controller

b

controllerconfiguration

c

“controllerconfiguration”

((Unknown Property))

a

b

c

Setup of tx_mvc_switchedPluginFrontController->main:

::

a

switchFlexKey

b

string

c

the concrete selected controller is expected in the flexformconfiguration. Here the path to that field needs to be configured!

::

a

switch.[controllername]

b

controllerconfiguration

c

Namespace for configuration of the switched controllers. Each subsection is from type “controllerconfiguration”

Setup of a “controllerconfiguration”:

::

a

configuration

b

typoscript

c

The namespace to configure your concrete extension. This is used to load $this->configuration object in you controller.

::

a

controllerName

b

string

c

The name of your controller (that should be called)

::

a

Extension

b

String

c

The extensionkey of the extension where the controller belongs to.

((generated))

Supported configuration

The framework is aware of some configurations per default:

To disable the injection of the build in viewHelpers you can add this to your configuration:

configuration {
 viewHelper.disable {
  linkCreator=1
  label=1
  fieldRenderer=!
 }
}

To configure the correct building of Ajax Links:

configuration {
 ajaxPageType=xxxxx
}

Suggested Namespace for configuring the TCA presentation model:

configuration {
  presentationModel {
                <tablename> {
                        <columnname> {
                                (your configuration)
                        }
                }
  }
}

Insides

Request and Dispatching in general

General spoken in a MVC Framework several objects are required in order to build the output:

  • request – represents the request that comes in (e.g. a website url with some parameters). In the MVC Framework that is an object containing all relevant informations of a request (includes already the name of the responsible controller). The request object is build by a requestBuilder
  • response – is just a container for the response (in this case for HTML body output and header output)
  • dispatcher – simple takes a request and response object and tries to call the (requestHandling-)Controller that is specified in the request – till the request can be marked as “dispatched”
  • requestHandlingController – is a controller that takes request and response object and is able to do something (useful) with that. Normally a ActionController is the one handling a request.
  • ActionController – is a special requestHAndlingController that has the concept of actions. Each request is interpreted in order to decide which concrete actionmethod in the controller is responsible for the current request.
Finding the relevant controller (request building) and dispatching:

When plugins are added to a page this is how it is dispatched:

The informations required to find the responsible controller comes from TYPO3, because the CMS decides which page should be shown and which plugins and/or typoscript objects are added to that page. Technically the simplePluginFrontController (or switchedPluginFrontController) get control from TYPO3 in order to return the output for the concrete plugin instance. The request-object is technically build from the typoscript configuration (that this concrete instance has) – this request is then simply passed to the dispatcher. And finally the content is returned by a controller.

Of course there can be multiple instances of plugins on one page. So imagine every plugin instance as a separate MVC part! You should have this is mind – thats a difference to common MVC frameworks where you don't have the TYPO3 CMS with all its concepts like pagetree, typoscript, pagerendering etc. Because you can have multiple plugins on a page and other plugins on other pages you have to tale care of:

  • TYPO3 decides the order of executing your plugins. Have that in mind when you change state or session of you application on a controller Action. (read the text abaout global front controllers when you run into issues with that)
  • If you link to a certain controller/action you might need to know the pageId for it. (Use configuration to configure the pageId for certain links)
Global Controllers

We introduced the concept of a “global controller”. Such controllers are not allowed to produce any output. They are called before pagerendering starts. Therefore there are useful to listen for actions that change the state or session of your application. If this state is used by multiple plugins – its a good idea to put the change logic inside of a global controller. This ensures that the updated state is always available for the normal plugins.

In the framework there is the globalFrontController that offers a concept of calling controllers independent from the current page. Controllers needs to be registered as a global controller – in order to support dispatching.

How controllers are executed in TYPO3:

There are some supported ways of how your controller can be executed with the help of this framework:

A MVC Plugin is configured in TYPO3 and is executed by TYPO3 during the page rendering – there are this possible ways:

as plugin contentelement on a page:

this can be a simple plugin configuration (representing exact one controller)

or a “switched” plugin, than the flexform needs to be read to detect the controller that should be used for the concrete plugin instance .

as typoscript (=simple plugin configuration)

as AJAX pagetype (see Ajax section for details)

global available controllers can be called independent from plugins on a page, they are executed before any plugin requests. Use this in order to execute preparing Actions, or actions that changes state for more that one other controller (plugins on the page) (like deleting something in a session or modifying something that is relevant for several plugins on a page – normally this is only required in complexer applications). Controllers that act as global controllers are not allowed to return any output (of course).

Adding Plugins and Ajaxsupport

Simple Plugin

Is configured with this php code in ext_localconf.php:

$pluginListTypeKey=$_EXTKEY.'_plugin';
tx_mvc_extMgm::addSimplePluginController($_EXTKEY,$pluginListTypeKey,'default');

And technically it adds this typoscript:

img-3 As you see the configuration for the controller is taken from the common controller configuration namespace “plugin.tx_objects_controller_uncachedtest.configuration” Use this path to add common configuration within the static template.

For registering it really as a plugin (that it is available in the contentelement) you still have to place this in ext_tables.php:

$pluginListTypeKey=$_EXTKEY.'_plugin2';
t3lib_extMgm::addPlugin(array('LLL:EXT:objects/locallang_db.xml:tt_content.list_type_pi2',$pluginListTypeKey),'list_type');

And if you like of course the static typoscript configuration template:

t3lib_extMgm::addStaticFile($_EXTKEY,"configuration/static/","Objects Outputs");
Switched Plugin

A switched pugin is a plugin where multiple controllers can belong to. Then you need to have a flexform configuration with a selectbox that represents the controllerswitch:

img-4

Is added with:

$pluginListTypeKey=$_EXTKEY.'_plugin';
tx_mvc_extMgm::addSwitchedPluginController($_EXTKEY,$pluginListTypeKey,array('default','uncachedtest'),'commonsettings.field_controller',0);

|img-5|

Also you need to place this lines in ext_tables.php:

$pluginListTypeKey=$_EXTKEY.'_plugin';
t3lib_div::loadTCA('tt_content');
$TCA['tt_content']['types']['list']['subtypes_excludelist'][$pluginListTypeKey]= 'layout,select_key,pages,recursive';
$TCA['tt_content']['types']['list']['subtypes_addlist'][$pluginListTypeKey]='pi_flexform';
t3lib_extMgm::addPlugin(array('LLL:EXT:objects/locallang_db.xml:tt_content.list_type_pi1',$pluginListTypeKey),'list_type');
t3lib_extMgm::addStaticFile($_EXTKEY,"configuration/static/","Objects Outputs");
t3lib_extMgm::addPiFlexFormValue($pluginListTypeKey, 'FILE:EXT:'.$_EXTKEY.'/configuration/flexform.xml');
Adding controllers as typoscript object

You simply configure your “simplePluginFrontController” in a typoscript object like this:

lib.myobject=USER
lib.myobject {
 userFunc= tx_simplePluginFrontController->main
 controller {
     configuration < plugin.tx_objects_controller_default.configuration
     configuration {
             myextraconfigurationforthisobject=something
     }
     controllerName= default
     extension=objects
 }
}
AJAX Page Types

The default concept for adding AJAX functionality is to configure a special pagetype for each controller. This is done in that way:

$pluginListTypeKey=$_EXTKEY.'_plugin';
tx_mvc_extMgm::addAjaxResponsePageType($_EXTKEY,$pluginListTypeKey,'default',9112008,'objects');

This results in that typoscript:

img-6 The framework will than takes care that the AJAX call has exactly the same configuration like your plugin (also flexform configuration is loaded)

Using a seperate pagetype has the advantages of: TYPO3 cache support – even static cache if you want, full TYPO3 environment, good performance since no TYPO3 templates needs to be rendered for that pagetype.

AJAX with eID

As mentioned the default concept of AJAX is to configure a AJAX pagetype with the correct typoscript etc. This way you have initialised TYPO3 environment, access to typoscript, typolink, cObj etc.

However there might be reasons where you don't need typoscript and a full initialised TSFE etc. - so you can create a eID script for answering your ajax calls. This is how it works:

1 – register eId script in your extension (ext_localconf.php):

$TYPO3_CONF_VARS['FE']['eID_include']['eft_postpaidconfigurator'] = 'EXT:eft/typo3/eid_postpaidConfigurator.php';
2 place this code in this script:
<?php
require_once t3lib_extMgm::extPath('mvc') . 'mvc/class.tx_mvc_eIdFrontControllerService.php';
$feUserObj = tslib_eidtools::initFeUser(); // Initialize FE user object
$uid=t3lib_div::_GP('mvcinstance');
$response=tx_mvc_frontControllerService::start('eft','postpaidConfigurator',array(),$uid);
echo $response->getContent();
?>

That means the eId script is responsible for getting the configuration and it determines the extension and controller that should be used to answer the request. The idea is to create and register seperate eId scripts for each controller where you want ajax eId support

Creating Links:

You can use the linkCreator:

->getEIDActionLink('eft_postpaidconfigurator', 'someAjaxAction')
Hooks

The MVC extension has several Hooks that can be used to modify behaviour – every hook has an interface in mvc/hooks/ that contains more descriptions.

For example there is a hook that allows to add own view helpers, by injecting them into the view during the initializeView() method.

Using mvc in the backend

..to be documented..

img-7 MVC - 14