Extension Developers Guide

From TYPO3Wiki

(Redirected from Table of Contents (XDG))
Jump to: navigation, search

<< Back to Developer manuals page

[edit]

Short-name: XDG

Preface

The content of this document is related to TYPO3, a GNU/GPL CMS/Framework available from http://www.typo3.com

This is a draft version. You're welcome to edit it.
When the content is good enough, please change the {{draft}} tag to {{review}} .



The document TYPO3 Extension Development is a guide mainly for extension developers, explaining the basic steps to create an extension and going further into advanced topics useful for TYPO3 extension development.

Contents

Introduction

What is an extension?

glossary-definition: An extension is basically a piece of software that extends or alters the functionality of TYPO3. The concept of extensions makes TYPO3 one of the most flexible CMS-Frameworks around enabling you to achieve virtually every function you need TYPO3 to take care of.

A wide variety of extensions can be downloaded from the TYPO3 extension repository, but being interested in an "Extension Developers Guide" I assume that you already have been there and downloaded some of the extensions to play around with.

Extension Types

Explains the difference between user extensions and core extensions, and when you actually need either of those. Additional types are: Backend modules, frontend plugins, code libraries, services etc.

Required Knowledge

Information on the knowledge about concepts that matter when you write extensions. E.g. PHP, databases and database normalization, the concept of Typoscript, OOP etc. (possibly accompanied with links to online documents, articles and literature suggestions)

Extensions supporting extension development

Extension Development Evaluator

Extension Development Evaluator (extdeveval) (contact: kasper) The extension ExtDevEval gives you the APIs for extensions and a link list to documentation.


T3DEV Developer Extension

Thats a newer extension for developers that integrates better in TYPO3 >=4.2. t3dev (t3dev) (contact: neoblack)

Show TYPO3 Info

Show Typo3 Info (sg_showdoku) (contact: geithman)

Kickstarter

Extension Kickstarter (kickstarter) (contact: flyguide)

Kickstarter MVC (lib/div)

kickstarter__mvc (kickstarter__mvc) (contact: gawain) is an add-on for the kickstarter, to generate frontend plugins in MVC style based on the upcoming lib/div libraries lib (lib) (contact: elmar.hinz). See Kickstarter_team#Kickstarter MVC (lib/div)

Tutorials and Videos

Also the following Tutorials and Videos are a great help for first steps:
- Backend Programming
- Creating a basic extension

I encourage you to follow the tutorial "Backend Programming" step by step, even if you will later create all the basic files with the Kickstarter. The reason is, that you get a feeling for what the different files and entries are for, especially when making mistakes that lead to misbehaviour of TYPO3. It's good to start from scratch once, although you'll be happy that most of the things can be achieved by using the kickstarter later on.

This should keep you busy for a while.

The TYPO3 architecture

Explains the overall architecture of TYPO3, possibly accompanied by diagrams. The "why" of things is also very important here. Pre/post-processing issues, the role (and boundaries!) of Typoscript, the philosophy behind the architecture, the TCA etc. (Kasper will be the best judge of the structure of this section)

Extension Maintenance

Local extensions

The local extensions usually resides in the typo3conf/ext/ directory.

Pros
Extensions in the local scope will not be overwritten when updating the TYPO3 Installation. Therefore it is recommended to put most extensions into local scope.

Cons
When having multiple TYPO3 installations sharing one typo3_src directory, it can be a waste of space when every user installs one extension in local scope.

Global extensions

The global extensions usually resides (on standard TYPO3 installations) in the typo3/ext directory.

Pros
When having multiple TYPO3 installations sharing one typo3_src directory it can be clever to install some often needed or default extensions in global scope.

Cons
When updating, the folder typo3 containing the backend will be fully replaced, and the extensions in Global Scope are replaced, too.

Upgrading

Practices that are involved with keeping your server clean and safe for upgrading (i.e. avoiding breaking things by modifying an existing extension and then upgrading it), some things about dependencies, how to manually install extensions etc.

PHP Compatibility

Things to keep in mind when installing extensions on the server (like the register_globals thing, explaining the distribution's .htaccess file that sets PHP flags, PHP version compatibility, etc.)

Programming Extensions

(note: probably better to not rely on the kickstarter here, it's more educative to learn from scratch if you really want to learn about extension writing, and that's why someone reads this guide after all)

One base for all - Or one for many at least

(Explains when and how you should inherit from tslib_pibase, and how your extension will be 'hooked' at runtime. Please extend!)

When Kasper Skårhøj put the idea of extensions for TYPO3 into reality, he delivered a PHP class which can serve as a basis for frontend plugins. This class is called “pi_base”, derived from “plugin base”. It's not required to use this class. If you code your own version, this class gives you a good example for the required API.

Whenever you create a new frontend plugin with TYPO3's kickstarter wizard, you will find a working hello world example in the extension's directory. This sample code already uses pi_base and maybe you have been using it at some point without really taking notice of it.

By the way - the file which contains the pibase is part of the CMS extension and located in typo3/sysext/cms/tslib/class.tslib_pibase.php. Have a look at this file right now, it is well commented and provides some vital features for your own plugins.

The file class.tslib_pibase.php contains the parent class; 'pibase', providing an API with the most basic methods for frontend plugins. It contains;

  • Init functions, to initialize pivars for example,
  • Link functions, to create various kinds of links,
  • Listing, browsing, searching functions, for working with database records,
  • Stylesheet and CSS functions,
  • Database and query functions,
  • FlexForms related functions,
  • Various functions, e.g.: pi_RTEcssText().

A full listing of all the functions can be found at the top of the file.

When you write a function, write one to extend this class. This will save you a lot of work if you plan to work with anything in the list above. Of course, you can also write your own functions.

// include the pibase
require_once(PATH_tslib.'class.tslib_pibase.php');

// extend tslib_pibase
class tx_photoblog_pi1 extends tslib_pibase {
  // Your functions go here
}

The nice thing about this setup is that you can write your own implementation of a function. Your plugin will then use your implementation instead of the one in 'pibase'. So if you don't like the way pi_setPiVarDefaults behaves, you can write your own.

When using the kickstarter, your new extension class automatically becomes an extension of tslib_pibase.

Things you must use

Explains which parts of the TYPO3 API are mandatory to use in order to work correctly with TYPO3 or "system - intense" extensions of TYPO3 (like RealURL).


t3lib_div

makeInstance

To instantiate an object you must use the new operator only in connection with makeInstanceClass method or substitute it by the makeInstance function. e.g.

$treeView = &t3lib_div::makeInstance('tx_treelib_treeView');
getUserObj

An alternative to makeInstance is getUserObj which can get access to an already existent object. Description:

  • Creates and returns reference to a user defined object.

This function can return an object reference if you like. Just prefix the function call with "&": "$objRef = &t3lib_div::getUserObj('EXT:myext/class.tx_myext_myclass.php:&tx_myext_myclass');". This will work ONLY if you prefix the class name with "&" as well. See description of function arguments.

  • @param string Class reference, '[file-reference":"]["&"]class-name'. You can prefix the class name with "[file-reference]:" and t3lib_div::getFileAbsFileName() will then be used to resolve the filename and subsequently include it by "require_once()" which means you don't have to worry about including the class file either! Example: "EXT:realurl/class.tx_realurl.php:&tx_realurl". Finally; for the class name you can prefix it with "&" and you will reuse the previous instance of the object identified by the full reference string (meaning; if you ask for the same $classRef later in another place in the code you will get a reference to the first created one!).
  • @param string Required prefix of class name. By default "tx_" is allowed.
  • @param boolean If set, no debug() error message is shown if class/function is not present.
  • @return object The instance of the class asked for. Instance is created with t3lib_div::makeInstance
  • @see callUserFunction()
function &getUserObj($classRef,$checkPrefix='user_',$silent=0)

Typolinks in FE-plugins

Only links which are generated with the typolink function work properly in all situtations. This is necessary for the support of realurl, cooluri, for frames, for languages, for proper caching, for result browser and a lot more.

You can either use the typolink function directly or indirectly.

Directly calling the typolink function

Please set up a page to show how this is done and link it.

Indirect calls to the typolink function
  • tslib_pibase
    • $this->pi_getPageLink for internal links (parameter: id)
    • $this->pi_linkToPage for internal links (parameters: title, id)
  • lib (lib) (contact: elmar.hinz)

See

Discussion: tslib_pibase vs. other options

The use of the the typolink function is not trivial. On the other hand the indirect functions of tslib_pibase are cryptic and you have to learn multiple of them. Each of that functions is limited in it's range of use. You should consider this if you build a simple extension with typical links.

The class tx_lib_link also doesn't match all use cases, estimated 95%. Inheritence of an own class is an option for the remaining 5%. If you are a friend of OO programming it's probably your choice.

You should consider to learn the direct use of the typolink function, if you program extensions often. You have only to learn one function one time and it works for all use cases.

Things you can use

If you are programming a Frontend Plugin, the main API functions for are tslib_pibase (tslib/class.tslib_pibase.php) and tslib_cObj (class.tslib_content.php).

tslib_cObj

Description of how to use the API functions of the class tslib_cObj.

The main trick about those functions is the way parameters are passed to it.

Normally PHP functions get their configuration as parameters, like:

 doSomething($parameter);

The trick about the tslib_cObj API functions of TYPO3 is that they always expect an associative array $conf to be passed to it which contains the parameters.

The following example shows a valid $conf array for the IMAGE function: <PHP> :
 
  $conf = array(
    'file' => 'fileadmin/my_image.jpg',
    'alttext' => 'This image is an example!',
  );
 

The great thing about this is, that all possible parameters are nicely documented in the TSRef.

More to come here.

Example: <PHP> :
 
 $conf = array(
 	'parameter' => 'http://www.typo3.org 230x450:resizable=0,location=1',
 	'title' => 'Title-Tag: Link to typo3.org',
 	'ATagParams.' => array(
 		'append' => 'TEXT',
 		'append.' => array(
 			'value' => ' class="testing" ',
 		), 
 	),
 );
 $content .= $this->cObj->typolink('linktext', $conf);
 

tslib_pibase

Description of the class tslib_pibase

Finding classes/functions

This is a suggestion of an approach when working with Typo3 classes, but you don't know where the function (method) you are looking for is located and how it is called:

  • Install the Extension Development Evaluator extension (extdeveval). It's a must for developers and gives you a nice API-documentation for most of the important classes.
  • Have a look at the full-API. Or use doxygen to generate your own version from source.
  • Debugging the GLOBALS variable can give some insight...
  • If you want to get more information on a certain function, study the source/use a debugger to find out how something is done in another ext/functionality. Have a closer look on how the function is called:
t3lib_extMgm::extRelPath($_EXTKEY)
                         ^------ the extension-key ;)
              ^------ the functions name, search for that in the file
      ^------ it is class.t3lib_extmgm.php
^----- it's in folder 't3lib' (t3lib = TYPO3 Library)

Read the description of the function extRelPath in file class.t3lib_extmgm.php.

Types of user extensions

Backend

All kind of BE-related extensions for extending or replacing backend-functions. The extensions in this category do not create a new link in the main menu on the left side, they implement or extend functions of other backend areas. For example, an extension extending the clickmenu with more items or an extension implementing a new RTE should be put in this section.

Backend Modules

A backend module is an extension that has a link in the main menu below one of the main menu items "web", "file", "doc", "tools" or "help". Backend modules are usually closed sections of their own, this means their functions are not used anywhere else. Examples: visitor tracking system, AWStats, Backup

Frontend

This is a category for extensions that influence and alter the frontend output in general like parsers.

Frontend Plugins

Frontend plugins are listed as pluggable content elements in the TYPO3 backend. While most other content elements display a single content entry of tt_content, the range of the functionality of plugins is broad. Often they display multiple entries of other tables than tt_content in form of a combination of a list view and a details view.

One extension can contain more than one frontend plugin. While the kickstarter creates them as folders named pi1, pi2, etc. it is a good habit, to choose more telling names for the folders.

Clickmenu items

A clickmenu item is added to the BE clickmenu.

Miscellaneous

Mostly some libaries.

Services

Templates

Examples

Skins

Skins for the TYPO3 backend.

Required extension files

Most of the content of this list is taken from T3Doc/TYPO3 Core APIs: "files and locations".

All these files are either marked (optional) or (required).

ext_emconf.php (required)

The term "emconf" stands for "Extension Manager/Repository config file". This file holds general information about the extension in an array called $EM_CONF[$_EXTKEY]. It is auto-written from Extension Manager when extensions are imported from the repository.

If this file is missing, the Extension Manager won't find the extension.

ext_localconf.php (optional)

Addition to localconf.php which is included if found. Should contain additional configuration of $TYPO3_CONF_VARS and may include additional PHP class files. All 'ext_localconf.php' files of included extensions are included right after the typo3conf/localconf.php file has been included and database constants defined. Therefore you cannot setup database name, username, password though, because database constants are defined already at this point.

ext_tables.sql (optional)

This file contains the sql-statement that will update or create tables in your typo3-database.

This file should contain a table-structure dump of the tables used by the extension. It is used for evaluation of the database structure and is therefore important to check and update the database when an extension is enabled. If you add additional fields (or depend on certain fields) to existing tables you can also put them here. In that case insert a CREATE TABLE structure for that table, but remove all lines except the ones defining the fields you need. The ext_tables.sql file may not necessarily be dumpable directly to MySQL (because of the semi-complete table definitions allowed defining only required fields, see above). But the EM or Install Tool can handle this. The only very important thing is that the syntax of the content is exactly like MySQL made it so that the parsing and analysis of the file is done correctly by the EM.

ext_tables.php (optional)

This file works hand in hand with the above by telling TYPO3 how to display and handle the data from the sql file.

Addition to tables.php which is included if found. Should contain configuration of tables, modules, backend styles etc. Everything which can be done in an extTables file is allowed here. All 'ext_tables.php' files of loaded extensions are included right after the 'tables.php' file in the order they are defined in the global array TYPO3_LOADED_EXT but right before a general extTables file (defined with the var $typo_db_extTableDef_script in the typo3conf/localconf.php file, later set as the constant TYPO3_extTableDef_script). Thus a general extTables file in typo3conf/ may overrule any settings made by loaded extensions. You should not use this file for setting up $TYPO3_CONF_VARS. See ext_localconf.php .

ext_tables_static+adt.sql (optional)

Static SQL tables and their data. If the extension requires static data you can dump it into a sql-file by this name. Example for dumping mysql data from bash (being in the extension directory):

mysqldump --password=[password] [database name] [tablename] --add-drop-table > ./ext_tables_static.sql

--add-drop-table will make sure to include a DROP TABLE statement so any data is inserted in a fresh table. You can also drop the table content using the EM in the backend.

The table structure of static tables needs to be in the ext_tables.sql file as well - otherwise an installed static table will be reported as being in excess in the EM!

locallang_db.php (optional)

The language file with translations for every row - used for displaying them in the backend.

locallang.php (optional)

The language file with translations available in the extension-scripts.

ext_typoscript_setup.txt (optional)

Contains some TypoScript for the extension.

ext_icon.gif (optional?)

The extension icon displayed in the EM.


--murphy 18:36, 14 May 2004 (UTC)

Extending an extension

Actions that are required to extend an extension, and the implications this has for future compatibility. A case study would be useful here. Core hooks: How you would extend the core by requesting a hook from the core devs.


If you want to extend an existing extension TCA array:

1) Setup a simple extension with kickstarter

2) In the ext_tables.php file add these lines to the top:

  <?php
  if (!defined ('TYPO3_MODE')) 	die ('Access denied.');
  //Load the TCA array you want to modify
  t3lib_div::loadTCA("tt_news");
  $TCA['tt_news']['columns']['bodytext']['config']['rows'] = 15;

Remark: Be careful with this. To let this work your new extension containing this must be after "tt_news" in $TYPO3_CONF_VARS['EXT']['extList'] (in typo3conf/localconf.php). On updates (of single extensions) or uninstall/install (of extensions) this order can mess up (My experience with Typo3 3.8.1).

Remark: The extensions are in proper order in $TYPO3_CONF_VARS['EXT']['extList'] as long as the dependencies are declared in ext_emconf.php. Often this dependencies are lost during upload, due to a current bug of the TER.

3) In BE > Tools > Configuration > Menu $TCA (tables.php)

4) Here you can select the changes and copy this config to your ext_table.php file

Quality standards

Explains the reviewing guidelines which are the official standard for a quality extension. How to get a Cohiba?

Common practices

Security

Handling user data

Examples along with descriptions on how to handle incoming GET/POST data

Dealing with Typoscript

Explains when to use Typoscript for your extensions and how to read it inside the extensions

WARNING: You will only be able to understand this chapter, if you have read the documentation TypoScript Syntax and In-depth Study.

Handling file uploads

Examples of dealing with file uploads in extensions

Using sessions

Sessions are used to carry userdata along the visit without having to post them over and over again. The data is available as long as the session is valid, usually until all (!) browserwindows are closed.

Since TYPO3 has already a session running you can use the existing session to read/write data into it. However you must first understand that Sessions in Frontend and Backend are handled differently.

The routine on the other hand is always the same.

  • Recover your Data from the session
  • Add values (possibly into an array that holds all the sessiondata)
  • Save your Data to the session

When writing all your data into a single array you can be sure that no data gets lost.


Backend

In Backendmodules Sessions are called by using:

$my_vars = $GLOBALS["BE_USER"]->getSessionData("tx_myextension");

you then will add your own values:

$my_vars['somevalue'] = "Hello World";

Don't forget to save the data to the session in the end:

$GLOBALS["BE_USER"]->setAndSaveSessionData ('tx_myextension', $my_vars);

Of cause $my_vars can be in a classwide context with $this->my_vars


Frontend

In Frontendmodules Sessions are called slightly differently by using:

$my_vars = $GLOBALS["TSFE"]->fe_user->getKey('ses','tx_myextension_mykey');

you then will add your own values the same way:

$my_vars['somevalue'] = "Hello World";

Again, Don't forget to save the data to the session in the end:

$GLOBALS["TSFE"]->fe_user->setKey('ses','tx_myextension_mykey',$my_vars);
$GLOBALS["TSFE"]->storeSessionData();

Of course $my_vars can be in a classwide context with $this->my_vars

This is all you need to know to manage Sessions with extensions.

TIP: Good Editors (see tools section) offer templates or stationaries for code. If you save these statements as templates, you can access them without the hassle of checking this document. Just make sure you can tell the frontend from the backend statements.

Using databases

Introduction

The DBAL consists of a t3lib_DB class in the GLOBALS array $GLOBALS['TYPO3_DB'] (used as 'global $TYPO3_DB' in the declaration section of each function).
It offers methods for building queries for inserting, updating, deleting and of course selecting records from tables in the db: INSERTquery, DELETEquery, UPDATEquery and SELECTquery. Each of these methods has as similar method that executes the statement: exec_INSERTquery, exec_DELETEquery, exec_UPDATEquery and exec_SELECTquery. These are the functions that will be used for retrieving the resultset. This resultset can be browsed by methods in the class. These methods will be familiar to people knowing the php mysql functions. For instance the php function mysql_num_rows is called sql_num_rows, mysql_fetch_assoc is sql_fetch_assoc etc.

many-to-many relations

There are also methods for retrieving many-to-many relations from tables that adhere to the standard TYPO3 way of mm relations. So take care to name your table fields in the following way.

  • Use $mm_table together with $local_table or $foreign_table to select over two tables. Or use all three tables to select the full MM-relation.
  • The JOIN is done with [$local_table].uid <--> [$mm_table].uid_local / [$mm_table].uid_foreign <--> [$foreign_table].uid
  • The functions are for selecting MM-relations between tables adhering to the MM-format used by TCE (TYPO3 Core Engine). See the section on $TCA in Inside TYPO3 for more details.

Function Overview

Query execution
  • exec_INSERTquery($table,$fields_values)
  • exec_UPDATEquery($table,$where,$fields_values)
  • exec_DELETEquery($table,$where)
  • exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy=,$orderBy=,$limit=)
  • exec_SELECT_mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause=,$groupBy=,$orderBy=,$limit=)
Creates and executes a SELECT query, selecting fields ($select) from two/three tables joined
  • exec_SELECT_queryArray($queryParts)
  • exec_SELECTgetRows($select_fields,$from_table,$where_clause,$groupBy=,$orderBy=,$limit=,$uidIndexField=)

to get the last inserted id, you can use: $GLOBALS['TYPO3_DB']->sql_insert_id();

SECTION: Query building
  • function INSERTquery($table,$fields_values)
  • function UPDATEquery($table,$where,$fields_values)
  • function DELETEquery($table,$where)
  • function SELECTquery($select_fields,$from_table,$where_clause,$groupBy=,$orderBy=,$limit=)
  • function listQuery($field, $value, $table)
  • function searchQuery($searchWords,$fields,$table)

I think there should be a note on the use of the query-building functions. If you have a query from a query-build function, is there a way to execute it? A function sql_query($query) exists, but is mentioned as deprecated in the file class.t3lib_db.php.

SECTION: Various helper functions
  • function quoteStr($str, $table)
  • function cleanIntArray($arr)
  • function cleanIntList($list)
  • function stripOrderBy($str)
  • function stripGroupBy($str)
  • function splitGroupOrderLimit($str)

SELECT

As an example, lets try to select the fields uid,name and email from the tt_address table. We only want to select records with a certain pid contained in the variable $id.

$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,name,email','tt_address','pid = '.$id);

This will return a recordset with all the tt_address records in the folder with uid $id. Actually the DBAL will not check the where clause (pid=$id), for SQL-injection, and if this variable is fetched from the browser, it will be a good idea to put it through intval since it is supposed to be an integer.

$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,name,email','tt_address','pid = '.intval($id));

You should use the enableFields method to exclude entries which have been deleted, are hidden or have been scheduled using {start,end}time. The function will return a string for your WHERE clause:

$where = 'pid = '.intval($id);
$where .= $this->cObj->enableFields('tt_address');
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid,name,email','tt_address',$where);

If you don't already have a WHERE clause you will get a wrong mysql statement (SELECT * FROM tt_address WHERE AND ...), so you have to strip the leading AND in this case:

$where = preg_replace('/^ AND/', '', $where);

But it's more efficent to change (SELECT * FROM tt_address WHERE AND ...) to (SELECT * FROM tt_address WHERE 1=1 AND ...) with

$where = '1=1'.$where;

or (SELECT * FROM tt_address WHERE OR ...) to (SELECT * FROM tt_address WHERE 1=0 OR ...) with

$where = '1=0'.$where;


Generally speaking, TYPO3 has a method for escaping query parts:

string $GLOBALS['TYPO3_DB']->quoteStr(string);

Browsing the resultset can now be done like this:

while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
 do_something_with_the_data($row);
}
$GLOBALS['TYPO3_DB']->sql_free_result($res);

It is always a good idea to free the resultset when finished with it. This is done by the methods sql_free_result.

The exec_SELECTquery takes these parameters (taken from the docs in the source file):

/**
 * Creates and executes a SELECT SQL-statement
 * Using this function specifically allow us to handle the LIMIT feature independently of DB.
 * Usage count/core: 340
 *
 * @param	string	List of fields to select from the table. This is what comes right
 *                     after "SELECT ...". Required value.
 * @param	string	Table(s) from which to select. This is what comes right after "FROM ...".
 *                     Required value.
 * @param	string	Optional additional WHERE clauses put in the end of the query. NOTICE: You 
 *                     must escape values in this argument with $this->quoteStr() yourself! DO NOT
 *                     PUT IN GROUP BY, ORDER BY or LIMIT!
 * @param	string	Optional GROUP BY field(s), if none, supply blank string.
 * @param	string	Optional ORDER BY field(s), if none, supply blank string.
 * @param	string	Optional LIMIT value ([begin,]max), if none, supply blank string.
 * @return	pointer		MySQL result pointer / DBAL object
 */
function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy=,$orderBy=,$limit=)

DELETE

Deleting records is done by the exec_DELETEquery, it takes two arguments, the table to delete from, and the WHERE clause to select which records to delete.

$GLOBALS['TYPO3_DB']->exec_DELETEquery('tt_address','uid='.intval($uid));

Again, make sure the input parameters are SQL-injection safe by running them through intval() or similar.

UPDATE

When updating records use the exec_UPDATEquery command. It takes the table name, where clause and an associative array of fieldnames => values pairs. The values are run through t3lib_db->quotestr which will make sure that they are injection safe (see the section on cleaning functions).

$GLOBALS['TYPO3_DB']->exec_UPDATEquery('tt_address','uid='.intval($uid),array('email'=>$email,
                                                                              'name'=>$name));

Remember to make sure that the where clause,fieldnames at table name are run through addslashes or similar if they are fetched from variables.

INSERT

The insert command follows the same syntax as the update command, except there is no where clause.

$GLOBALS['TYPO3_DB']->exec_INSERTquery('tt_address',array('name'=>$name,
                                                          'email'=>$email));

When inserting a record, one can call the sql_insert_id() method to retrieve the id of the latest inserted record.

Debugging

One drawback of using the DBAL is that all database errors, like malformed queries, will look like they originated from the t3lib_db class. debugging is done by setting

$GLOBALS['TYPO3_DB']->debugOutput = TRUE;

This will save all built queries (not necessarily executed) in the debug_lastBuiltQuery parameters of the class. When debugOutput is set, all errors are output to screen by echo (at least in the MySQL implementation of DBAL).

See also the Extension Development Mini-HowTo.


If you do not use DBAL you can easily get your sql-queries:

$GLOBALS['TYPO3_DB']->store_lastBuiltQuery = 1;
// make Query
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit);
// echo Query
echo $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery;

Security - Cleaning functions

The DBAL will check some of the variables, but when writing extension, you are responsible for making sure that there is no SQL injection exploits. Several helper functions exists for this. Use intval when you know that the field is supposed to be an integer. DBAL offers two other functions for cleaning lists and arrays of integers:

$GLOBALS['TYPO3_DB']->cleanIntList($list);
$GLOBALS['TYPO3_DB']->cleanIntArray($arr);

They will make sure that you list or array only contains integers.

Security - quoting function

For escaping strings use the method quoteStr of the DBAL. This will escape your string according to which table you want to insert into. In the MySQL implementation it is equivalent to calling addslashes, but use quotestr instead.

$GLOBALS['TYPO3_DB']->quoteStr($str,$table);

Handling User Authentication

Examples on what exactly should happen for e.g. logging a user into TYPO3

constants

You should use the BACK_PATH constant in your modules to set the relative path from your script to the typo3 folder of your installation.

$this->backPath = $GLOBALS['BACK_PATH'];	// Setting backpath.
Set your own PATH constants in the ext_localconf.php file of your extension. <PHP> :
 
 if (!defined ('PATH_txcommerce')) {
     define('PATH_txcommerce', t3lib_extMgm::extPath('commerce'));
 }
 if (!defined ('PATH_txcommerce_rel')) {
     define('PATH_txcommerce_rel', t3lib_extMgm::extRelPath('commerce'));
 }
 

Debugging of PHP-Code

debug function

This needs setting of devIPmask in localconf.php

<PHP> :
 
debug($variable. ' '.__FILE__);
 
more comfortable debugging

Use this to get a bit more infos when debugging. This example includes SQL debug (lastBuiltQuery), for this to work put the first three lines in your code before you do your query and the debug statement after the query.

<PHP> :
 
ob_start();
$GLOBALS['TYPO3_DB']->debugOutput = true;
$GLOBALS['TYPO3_DB']->store_lastBuiltQuery = true;
 
/* your query and code here */
 
debug(
  array(  
   'class: ' => __CLASS__,
   'method: ' => __METHOD__,
   'function: ' => __FUNCTION__,
 
   // what to debug
   $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery,
  ),
  'DEBUG data: ',
   __LINE__,
   __FILE__,
   5
);
 

krumo

http://krumo.sourceforge.net/

So you add it to the MVC Framework lib/div.

1. Put the krumo folder into the extension.

2. ext_localconf:

<PHP> :
 
 if (TYPO3_MODE == 'FE'){
   set_include_path(get_include_path() . PATH_SEPARATOR .
t3lib_extMgm::extPath('krumo') . 'krumo/');
   require_once('class.krumo.php');
 }
 

3. clear caches.

XDebug

http://xdebug.org/docs/display

Can also be used with several editors.

Structural practices

Coding conventions

TYPO3 Coding Standards

Make sure to read the complete guide of the TYPO3 coding standards.

When developing TYPO3 core, the style guide has to be followed. When you write your own extensions, you can follow it, although it is highly recommended to follow the guidelines in extensions, too.

General Style

  • XHTML (transitional) / CSS compliance
Paragraphs will probably make up a majority of your (X)HTML code. Some authors were taught the closing paragraph tag (</p>) is unnecessary, however when standards are of importance, which they are, text should be enclosed in p tags like this:
<p>Creating paragraph numero uno is simple.</p>
<p>Starting a new paragraph after numero uno is just as easy.</p>
Note: Those not well-versed in the separation of style from content may be inclined to use several empty paragraphs to create hard returns in a document. This is not recommended, as visual appearance can be easily controlled with CSS, as you will soon see.
  • use quotes for attribute values
  • prevent XSS and SQL injection by usage of htmlspecialchars(), addslashes(), intval()
  • comment all functions and classes fully with parameters and return values
  • Classes have to have @package/@subpackage tags, contain a function index and have the CVS keyword "$Id$" in the header comment of the document.
  • use English words or abbrevations for class/function names, variables, comments, database table and field names, ...

Filenames

  • All filenames have to be shorter than 31 characters
  • filenames should be in lowercase as long as possible

Handling content

Examples of how to use the markers, TemplaVoila, Smarty etc.

Writing larger extensions

Suggestions on how to structure your code when writing larger extensions (explanation of Front Controller style structures)

Porting third party applications to TYPO3

Things to keep in mind when porting third party applications to TYPO3 such as database migration, user integration, etc.

Accessibility

Hints on accessible forms and more...

Personal tools